時計を壊せ

駆け出してからそこそこ経ったWebプログラマーの雑記

YAPC::Asia 2013 で ぼくがかんがえたさいきょうのMVC についてはなします #yapcasia

YAPC::Asiaとは

日本で最大級の規模のPerlのカンファレンスです。Perlのカンファレンスですが運用、プロトコル、テスト等開発に関わる様々なトークがあり、和気あいあいとした雰囲気でときには意識高い話もしつつ、ゆるふわにPerlとその周辺技術等への学びや発見を得る事が出来ます。詳しくは http://yapcasia.org/2013/ をどうぞ。

今回、ありがたい事に僕が応募していたトークを採択して頂きました。

ぼくがかんがえたさいきょうのMVCとは

下のリンク先をご覧下さい。

http://yapcasia.org/talk/show/f60b8522-d43e-11e2-ac80-4cc16aeab6a4

ではちょっとさみしいのでこのトークを応募した経緯を書いてみます。


僕は仕事でソーシャルげーむを作っています。ソーシャルゲームは若干特殊な部分はありますが基本的には普通のWebアプリです。(最近はクライアントをAndroid/iOS向けに提供しているものも多いですがそれも多くの場合はバックエンドはWebAPIを提供するWebアプリです)
ソーシャルゲームは場合によってはかなりの種類の機能を提供する場合があり、対応デバイスもAndroid4系/Android2系、iOS/FeaturePhone(所謂ガラケー)などに対応させ、更に複数のソーシャルプラットフォームで動作させる場合もあり、プラットフォームによってOpenSocialの同じAPIでも微妙に仕様が違う場合があったり、同じ目的のAPIをそれぞれ独自の仕様で持っている場合があり、またゲーム自体のロジックが複雑な場合もあり、規模が大きくなる傾向があります。
ある程度の規模まではぶっちゃけ設計が適当でもなんとかなります。意味のわからないコードもひたすら追えばなんとかならなくもないでしょう。最悪全部書き直す事が現実的なコストでできる場合もあります。場合によってはschemaだけ真面目に設計してコードはゴリっと愚直に書いたほうが運用を含めた総合的なコストを低くする事もできる場合も多いと思っています。
しかし、ある程度以上になってくると、適当な設計のアプリケーションでは全てのコードを把握する難易度はかなり上がります。特にRPG系と呼ばれるジャンルのソーシャルアプリは確実に困る規模だと思います。
規模が大きいとどうしても複数人で同時に開発を進める事になります。規模が大きい割に設計が適当だと、同じ役割のコードが様々な場所に書かれたり、様々な機能が沢山搭載されている「ぼくがかんがえたさいきょうのClass!!!」「ぼくがかんがえたさいきょうのmethod!!!」みたいなやつが出来たり、非常にカオスなコードが出来上がります。処理の共通化も困難になり、そのようなコードベース上で無理に行われた共通化は諸悪の根源になりがちです。プロダクションコードでこのようなコードが出来上がると非常に悲しいことになります。テストが書かれていればかなりマシですが、それでもそもそもの設計がぐちゃぐちゃだとリファクタリングにかなり苦労する印象が強いです。コードレビューも苦労します。

これを解決するための考え方の1つが僕はソフトウェアアーキテクチャだと考えています。MVCはそのうちの1つですが、これも必ずしもそのままWebアプリケーションに当てはめられる訳ではなく、特にRDBMSとの関わり方やコンテンツキャッシュとの関わり方について悩んだり、ロジックが変に分散してしまったり、逆に殆どのロジックが詰め込まれる「ぼくがかんがえたさいきょうのClass」みたいな奴が出来て苦労する場合が多いと思います。その為、MVCの考え方を拡張して、目的のアプリケーションに合わせて整理して設計する事が必要になります。
そこに関してある程度考えがまとまったので、今回この話をする事にしました。
ただ、ぼくの考えも非の打ち所の無い完璧なものであるとは思っておらず、より良い感がえ方がきっとあると思うので、この話をきっかけにみんなそれぞれの「ぼくがかんがえたさいきょうのMVC」について話し合うきっかけにでもなれば、ベースの設計の重要性について考える機会が出来たらいいな風な感じです。
id:TAKESAKO さんの「SPDY、HTTP/2.0の使い方」とかid:xtetsujiさんの「mod_perlの展望とApacheの超絶技巧」とかid:akiymさんの「Herokuで学ぶ、初めてのPerl」とか裏番組みんな面白そうなので僕も聴きに行きたいくらいですが、もし興味があれば聴きに来て頂けると喜びます!

YAPC::Asiaに参加するには

チケットの購入が必要です。2日通し券で5000円、1日券で4000円です。なお、学生は無料です。(!!)
チケットの購入はこちらからどうぞ! http://yapcasia.org/2013/tickets/
明日、8/11までなのでまだ購入していない方はお早めに!

#yapcasia 2012 に参加してきました

YAPCはおわっちゃいねえ。俺達のYAPCはまだ始まったばかりだ!

と言ってるわけにもいかないので、いい加減書きます

今年のYAPC

今年は東京大学のなんちゃら記念館というところで開催されました。
今年出来たばかりみたいで新しく、綺麗な建物でした。
運営もいろいろ進化していて、英語のセッションで質問をするときにlestrratさんなど英語の話せる方が翻訳してくださったり、受付も素早く、ホールで飲み物も提供されていたりして、運営の方が去年以上に細かいところまで気を配って運営していてすごいと思いました。
運営の皆さんお疲れ様でした。ありがとうございました。
ぼくも来年は運営手伝ってみたいなと思いました。

聞いたトーク

What Does Your Code Smell Like? (Larry Wall)

Perl6の紹介をライブコーディングでやっててすごかった。
Perl6、多機能なのは良いのだけど、whatever starはどうも受け付けない。。。
あとvimの操作が達人過ぎてやばかった。

Nana/Tora - Perl5 から見える未来。Perl5 と共にあゆむ Perl6 ではないプログラミング言語、それは。 (id:tokuhirom)

toraとnode-perlとnpmの話とかいろいろ聞けて面白かった。
あとトークタイトルがやたらかっこよかった。

Perlと出会い、Perlを作る (id:goccy)

C++によるperlの高速な処理系を作って、どういうところを工夫したのか聞けて面白かった。
まだまだ作っている途中の模様だけど、今後どうなっていくかに期待。

Distributed Job System. Clutch (id:nekokak)

Cluntchの紹介。
前々から興味はあったけど、思ってた以上に使いやすそうで、
Dainamo::Profile::Cluntchとか書いて使ってみようかなと思った。

続・Mobage を支える技術(id:xaicron)

Perlでシグナルを扱うときにXSモジュールが絡む場合にどう扱うか、
何故そのように扱わなければいけないかが知れて良かった。
リアルタイムに茶々が入るのも見てて面白かった。

Profiling memory usage of Perl applications (Tim Bunes)

perlのメモリ管理の解説とDevel::Size(?:Me)?の紹介。
自分の英語力の無さを最も呪ったトークだった。
内容的に凄く知りたい内容なのに、言ってる事を節々しか聞き取れないのは痛かった。
でも、スライドやデモが充実してたので、なんとなく理解出来た気がした。
ブログになんかいろいろ書いてくれていたりするので頑張って読みつつ英語を勉強しようと思いました。
そしてトーク中にデモで使ってたWebAppがすごく便利そうなので、使ってみたくなった。(Devel::SizeMeに同梱されてる模様)
英語、勉強するぞ!!11111っておもった。

Perlアプリケーションのベンチマークとプロファイリング (id:sfujiwara)

アプリケーションの高速化のためには計測が欠かせないというところで計測の手法をいろいろ紹介していた。
本番環境で一部のアクセスだけでNYTProfを動かす方法で、POSIX::AtForkを使って一部のプロセスだけでプロファイリングしているのが面白かった。

Perl 今昔物語(Tomihisa Fuon)

いまのYAPCに至るまでPerlコミュニティはどのように変わってきたのか、
Perlをいま使い続ける理由は何があるのか、
これからperlperlコミュニティはどのように変わっていくべきなのか考えさせられて面白かった。

Perl as a Foreign language(id:dankogai)

まだまだperlを使い続ける理由はあるよという事でperlの良い所として、
perlはサーバーサイドでは今でもどこでも動くし、多少変な書き方してても動く。
まともなUnicodeのサポートもあるし、起動速度が速い。という点を挙げていたりして面白かった。

Skyarc Systems presents 「遠方よりの参加者」発表

遠方からの参加者によるLT。id:meru-akimbo がLTやるという事で聴きに来た。
卵かけご飯とこわい人*1のF#の話がインパクトありすぎた。

ウェブアプリケーション開発の現状・課題とJSX (id:kazuhooku)

ビジネス的な視点も入れて、ウェブアプリケーション開発の歴史と現状について説明して、
JSXが何故必要でどういう機能を持っていて、どのような周辺ツールがあるのかなどを説明していて、
内容盛りだくさんで面白かった。特に、僕はビジネス的な考え方がまだまだ下手なので、
その辺りから説明していたのが聞けて勉強になった。

How Perl Changed My Life (id:mizzy)

mizzyさんがperlコミュニティが如何に好きなのかがすごい伝わってきてじーんとした。
(なぜか)ぼくもPerlで初めて触ったWAFはSledgeで、WAF使うとWebAppが簡単に書けて万能感が手軽に味わえるので、
Sledgeでプログラミングが楽しくなったというところはすごく共感出来たりした。
ぼくがプログラミング楽しいなーと思ったきっかけは中3の頃に罪と罰というCGIゲームを改造していたときで、
コードはメッチャクチャ汚い上にすごくバグってたけど、こんな機能入れちゃえとかいうのが簡単に出来て、
俺SUGEEEEEEって出来たのがまるでゲームみたいで楽しかった。
もっとコード書くの楽しめばもっと良いものが作れる気がしてきた。

ぼくのLTについて

2日目にLTをやらせて頂きました。
説明がめっちゃ駆け足で言葉が足りなかったなと猛反しているのですが。
結局何やってたのかよくわかんない感じになってしまって、
デモってむつかしいなーって思いました。

http://yapcasia.org/2012/talk/show/e9030f38-0637-11e2-a778-779e6aeab6a4

このLTで一番伝えたかった事は「こういうアプローチを試してみたけど、あまりうまくいかなかったので、いい方法あれば教えてください!」という事なんですが、
ただ、「『こういうアプローチ』ってどういうアプローチや!!!」って感じになってしまったので、
簡単にですが補足してみたいと思います。

簡単に言いたかった事を補足

ダミーデータはData::RuledFactoryとか使えばすごく楽に作れるし、使わなくてもそんなに苦労せずに作れるんですが、
ダミーデータの型を変えたり、カラムを減らしたり増やしたりする度にDBのテーブル定義を書き換えたりしなきゃいけないかったりします。

アプリケーションの機能開発をしていると、途中でDBのテーブル定義を書き換えたくなったり、ダミーデータの生成規則を変えたくなる事が多くあったりするので、
このArrayRef[HashRef]なダミーデータをDBにわざわざ毎度入れるのが面倒くさくなってきて、
じゃあArrayRef[HashRef]なダミーデータをgrep { $_ eq "hoge" } @$dummy_data;するか?ってなったけど
わざわざTeng使ってるコードをgrepに書き換えるのはナンセンスだなーってなった。


じゃあTengと同じインターフェースでgrepする(ArrayRef[HashRef]なデータ構造をDBにINSERTせずにそこから直接データを検索する)事が出来たら、
毎度毎度DBにINSERTする手間を省けて楽出来るんじゃないかなーと思ったので、
Teng::Plugin::Staticとか書いてみたという感じでした。


やってる事的にはKawaii DBみたいな事をやっていて、

$teng->search(table_name => +{ hoge => +{ '!=' => "hoge" } });

とかやると裏で

grep { $_->{hoge} ne "hoge" } @$table_data;

みたいなコードが走るイメージです。(実際は!=以外も対応してるのですこし複雑です)


利点は、前述した問題(ダミーデータの生成ルールを書き換えたりするたびにDBにINSERTする必要がある)が解消されていることです
また、Tengのインターフェースをそのまま使えるので殆どのコードを書き換えずともロジックがうまく動きます。
欠点は、、、沢山あります!!!
通常の場合と比べて、ダミーデータの生成*2+フルテーブルスキャン的に検索条件の解釈とマッチ+deep clone*3というのをやっている為非常に遅いです。
Storableを用いてcacheする事によりダミーデータの生成をある程度skipすることには成功しましたが、
それでもやはり結構遅いです。
更にもちろん、SQLを解釈しているわけではないので、dbhを直接触っているコードはもちろん、
search_by_sqlなどsql系のメソッドも動作しません。(利用環境にはそういうコードが無い前提でした*4
また、当然ですがRDBMSを使っていないのでベンチマークなど計測目的では使えません。*5


LTでやるには重すぎるネタかなと思いつつ、自分的に一番アツいネタだったのでこれを話してみましたが、
いろいろ省きすぎたなあと思って反省。
でもポジティブに考えれば以前より考えてコード書くようにはなってきたので、
来年は、問題とそのバックグラウンドも含めて解決策とコードを提案する普通のトークが出来たらいいなと思ってます。

*1:@kyon_mm

*2:ただし初回読み込み時のみ

*3:親データに影響を与えない為

*4:Tengの良い所を潰してしまってる感あるけどやむなしと考えた

*5:スライドのダミーデータの用途でベンチマークを挙げたのは誤解を招いたなと反省しました。

初YAPCで初LTしてきました

YAPC::Asiaってなに_

今日はYAPC::Asiaでした。
YAPC::Asiaは技術的なトークを中心としたカンファレンスです。
Rubyで言うRuby会議みたいなものでしょうか。(行ったこと無いですが)


YAPC自体は世界中で行われていて、今回はそのアジア版という位置づけみたいです。
海外からのゲストスピーカーの方も多数いらっしゃいました。


YAPC::Asia今日もやるので興味のある方はぜひ!

感想

見ていたトークの感想はだいたいTwitteにつぶやいていたので幾つか抜粋してまとめてみました。

  • 今後のPerl: 互換性をあまり意識せずに最新の機能を使ってプログラミング出来るようになる。凄い。
  • Carton: 開発しているタイミングで依存しているモジュールとそのバージョンをコアモジュールかどうかを開発者が意識する事なく管理出来る。凄い。
  • はてな: JavaScriptフリーで本当に大丈夫なのだろうか・・・。
  • スイーツエリアで殆どみんな無言のなか、ももクロが流れていてまじシュール。
  • IDC移行: サービスを停止せずに違うネットワーク間を如何に移行するか。OpenVSNでVPNを貼った上で様々な工夫を凝らして問題を解決していた。凄い。
  • Mゲー: やはりユーザー数の多いサービスは大変な模様。しかしあえて一時的にレプリケーションを止めるなど様々な工夫を凝らして問題を解決していた。凄い。

LT

LTもして来ました。スライドはこちら
外で一人で脳内プレゼンリハしてたら、何やら @kfly8 君から電話が。

kfly8「プロジェクターの接続テストで呼ばれてるぞ!」
僕「えっ!そんなのやるの!」

となって慌てて最前列に向かう。(考えてみたらやるのは当然ですが)

  • 開始直前に接続テスト!が、動かない・・・・ッ!
  • しかもMBPもフリーズしてしまった!何が起こったのかとあわあわ。(この時点でだいぶ動揺してる)
  • 別室で試させて貰うが同様の現象。更に慌てる。このままではLTが出来ない!
  • 運営の方(すみません、名前は失念してしまいました)にPCをお借り出来る事に!(本当にありがとうございました)
  • どうやらMBPとプロジェクタをつなぐ奴がイカレてるらしい事に気付く。
  • 本番の所には運営が用意してくれた同じモノがあるが、本番ぶっつけで接続勝負するとかエンジニア的に無いだろうという事でやめる。
  • 順番が来たのでいざ登壇。
    • 人めっちゃいる!めっちゃいる!!
  • 落ち着け俺。2のn乗を数えて落ち着くんだ!
  • 操作ミスであわあわ
    • 今のでだいぶ時間無駄にしたんじゃね?ドキドキ
  • 時間のプレッシャーに負けて緊張しまくり。
    • 時間やばくね?時間やばくね?


オチを言おうとしたらドラでオチがつきました。

反省

  • 接続テストは早めに。
  • 時間をあえて意識しない。
  • スライド数は少なめに(調整しやすいので)
  • もっと場数を踏む。練習する。

で、LTで結局何を喋ったの?

Class::VirturlAccessorという勢いだけで作った小物モジュールの紹介でした。
アクセサのよくある問題点を解決出来る感じです。
中では大した事はやってないのでモジュールにするまでもないかもですが。


こんな感じで使います。

package Hoge;
use strict;
use warnings;
use parent qw/Fuga/;
use Class::VirturlAccessor (# Class::Accessor::Lite like interface
    ro => [qw/hoge fuga/],
    rw => [qw/foo/],
    disable => ($ENV{PLACK_ENV} eq 'deployment'), # If this is true value, access control disable. But fast!
);

sub new {
    my $class = shift;

    $class->SUPER::new(@_)->with_vaccessor;
}

sub some_method {
    my $self = shift;

    $self->{hoge} = 'some value'; # this is read only valiable! croak!
    $self->{fpp}  = 'some value'; # this is typo! croak!

    return $self->{hoge};         # this is ok!
}


これはクラスにblessされたhashrefに読み書きの制約条件を付けて、かつ存在しないキーにアクセスしようとした場合はtypoと見なして死んでくれる、
しかしVariable::Magicでhookしているので遅いので、本番環境では無効にする事も出来る。
という機能を持ったモジュールです。
Class::Accessor::Liteとかとも併用出来るので、Variable::Magicが嫌いで無ければぜひ使ってみてください!


でも次はもうちょっとまともなプレゼン出来るように頑張ります><
来年リベンジします!宜しくお願い致します!