YAPC::Asia2009 09/10のメモ
- 前夜祭に引き続き初YAPC参加。セッション間の移動大変だった。
- 記念にAcme大全2009とPythons&PerlMongersの2つとも買った
- Acmeの下に何があるか知りたかったからちょうどいいタイミングだった!
- P&Pはパラパラ見てたらダンザマッチョの心得編があってそこだけじっくり読んでしまった
- AnyEventの意味がよくわからないまま使ってたのでmiyagawaさんの話聞けて良かった。やっとmy $w; $w = AnyEvent->timerの中でundefやってる理由がわかった(ような)
- ただ、$cv->cb(sub{ $cv->recv });で複数同時に立ち上げるパターンってのを実際にやってみたけど上手く動かなかった。。もうちょい勉強しないとわからん。
Welcome - id:lestrrat
基調講演 Perlの未来、その行程 - Perl Foundation: Richard Dice
FLOSSの技術進化のためのモデルとは?
- 時間とともにソフトウェアは進化する
- 初めに誰かが開発し、機能を加え、誰かがそれに加える
開発が安定した状態になる
- 死んだ状態
- 問題分野をやり尽くした(Text::Template)
- 開発者の興味がすでに他に移ってしまった
- 次のステップにコストがかかりすぎる
誰も興味ない?
- 本当に?
- 実際は興味がある人と、解決する人が一致しないだけでは?
- お金がある人はお金で解決できる
- 実際は興味がある人と、解決する人が一致しないだけでは?
オープンソースプロジェクト
TPFで起こっていること
- 内部での議論。何ができる?何をするするべき?
- 「最小限」モデル
- 今のまま
- 「意欲的」モデル
- 能動的に組織作りをし、Perlとともに戦う準備
- 「最小限」モデル
Webエンジニアのためのmixiアプリ開発ガイド - mixi 田中洋一郎
公開アプリについて
- アプリ数:231
- 今の1位:能力大学-漢字テスト(ドリコム)
- ユーザ数:395,598
バイラルの仕掛け
- invite
- マイミクにアプリを紹介する機能
- アクティビティフィード
- マイミクの更新情報
mixiアプリとOpenSocial
- OpenSocialにmixiの独自のAPIを加えた物がmixiアプリ
- mixiアプリ(PC版)
- XML + HTML + JavaScript + Flash
- DB用意しなくてもkey valueの簡単なPersistence APIが提供されている
- 自分のサーバにアップロードし、そのURLをmixiアプリに登録
- mixiアプリ(モバイル版)
- 日本の携帯はJavaScriptに対応してないので、HTML + XML + RESTFulAPI
- mixiがプロキシになっていて、リクエストが自分のサーバに渡されるイメージ
- Gadget XMLファイル
- 一つのファイルでPC版とモバイル版の両方に対応可能な記述ができる
必要となる実装
- Social Data API
- /people, /activities, /appdata, JS(opensocial.*)
- Gadget APIの実装
- /gadgets/makeRequest, JS(gadget.*)
- Gadget Rendering
- /gadgets/ifr
- これらを実装するのは大変
PSGI/Plack - id:tokuhirom, id:miyagawa
プロトコルはシンプル
- リクエストはHASHREFにシリアライズして渡す
- レスポンスはARRAYREFにシリアライズして渡す
- 独自変数
- なんで必要か?
- response
- 配列の形にした
- ハッシュじゃないのは同じキーを使う時に困るので
- 配列は嫌だってのは考えなくていい。考えるのはフレームワーク作る人だけ。その人ががんばればいいだけ
- 配列の形にした
- specはgithubに置いてあるので見て
- HTTP::Engineは実装と仕様とAPIが全てごっちゃになってる
- Plack::Adapter::HTTP::Engineも用意してある
- HTTP::Engineから乗り換えやすいように。ただ、これをそのまま出すかはわからない
- HTTP::Engineはメンテナンスのモチベーションが落ちてるのでこの先バグフィックスだけかも
TODO
デモ
- test
- CGI.pmにもPSGIを入れることはメンテナの了承済み
- CGI.pmを使ってるフレームワークはそのまま使える
- AnyEventのデモ
- (セッション始まる前からtimeを出力するデモ作ってたけど、なぜかinteravalで出力されず上手く動かない)
- miyagawa:「バッファされてるから出力されないんじゃない?改行付けたら出ないかな?」
- tokuhirom:コードのwrite部分に改行そのまま入れる
- miyagawa:「いやいや笑」
- miyagawa:「new line」
- tokuhirom:考える
- miyagawa:「\n」
- tokuhirom:考え込む
- miyagawa:「(ノートPCの前に行って書こうとするけど)viだと書けねぇな」
- tokuhirom:意味がわかって"\n"を追加
- 出力できた。会場「おぉ」と盛り上がる
- (セッション始まる前からtimeを出力するデモ作ってたけど、なぜかinteravalで出力されず上手く動かない)
Inline::x86 JIT Assembler - Yoshinori TAKESAKO(id:TAKESAKO)
API Design - Shawn Moore (Sartak)
- GoogleのテックトークでもAPI設計の話が出た
- Moose,Path::Dispatcher,HTTP::Engine,Dist::Zilla,IM::EngineのクールなAPIの話
- 秘訣はテストを書くこと
Path::Dispatcher
- jifty::Dispatcherをprophetで使うために作られた
- 元々はSub::Exporterを使っていた
- 拡張性がなかった
- 元々はSub::Exporterを使っていた
- Robert Krimen(grink)が拡張したがってPath::Dispatcher::Builderができた
- サブクラス化してロジック変更できるようにした
HTTP::Engine
Dist::Zilla
- 色々なプラグインが使える
- プラグインの役割を書くとその役割をもつプラグインが選ばれる
- Request Tracker
- 選択肢を増やせる
- ModuleBuild or MakeMaker
- MetaYAML or MetaJSON
- Dist::Zilla::Pluginに拡張も可能
- ロールに必要な条件を満たせばいい
IM::Engine
- JapperなどのIMに対応
- 今取り組んでるプロジェクト
- 気に入ってるのはplugin_collect
- method=>'traits'でtraitsメソッドが呼び出せる
- 結果はメソッドの結果を配列にまとめたもの
- method=>'traits'でtraitsメソッドが呼び出せる
- new_with_plugins,nwe_with_traitsも気に入ってる
- new_with_traitsはMooseX::Traitsを利用している
- MooseではRoleとTraitはほぼ同意語
まとめ
- Mooseは拡張性やシュガーの分離を教えてくれた
- Path::Dispatcherのようにooシュガー層という考えが広がって欲しい
- HTTP::Engineの必要な機能だけ考えれば柔軟で簡潔になる
- Dist::Zillaのように追加したい機能を明示的に指定できたっていい
- IM::Engineのやり方をすればDRYにできる
- テスト書くのを忘れないように
modern Catalyst - DeNA Hideo Kimura(id:hide-k)
Deprecation
Extend Application
- pluginはもうダメ。怖い人に怒られる
- Application namespaceならギリギリセーフ
- Helper Method
- Role
- use Moose::Roleでsetupに入れれば使える
- あんまやらないけど
- use Moose::Roleでsetupに入れれば使える
- base Controller
- BEGINでextendsする
Extend Controller
Dispatcher
- default:Privateが使えなくなる
- default:Pathを使うようにしてください
- 極端な話catchall::Pathでもかまわない
- index:Privateも同様にダメ
- $c->go、$c->vistiが追加された
- 使い道がよくわからないけど。
Model
- Contollerを小さくして、Modelを賢くしなさい
Test
Asynchronous Event programming with AnyEvnt - id:miyagawa
- 自分の書いたモジュール以外の話をするのは4年ぶりくらいなのでベーシックな話になるかも
- AnyEventの作者の人は面白い人
- miyagawaさんのことが嫌いらしい。メールすると怒濤の勢いで怒ってくる
- でも何かそれが面白くなって来た
- miyagawaさんのことが嫌いらしい。メールすると怒濤の勢いで怒ってくる
- イベントループのモジュールはたくさんあり、APIもそれぞ違う
- これは問題
- POE::Componentsの数が250もあるから人気のように見えるけど、IO::Asyncの対応してるようなものばかり
- これは問題
- AnyEventで書いたコードはどのイベントループが入ったモジュールでも使える
- POEが使われている既存のコードにも追加できる
- もうPOE::Componentsは増やさなくていいよ。ホント。
- POEが使われている既存のコードにも追加できる
AnyEventの基本
- TimerWatcher
- timer
- after秒後にinterval秒ずつ実行
- timer
- condvarで待ち受けのイベントを作って、実行されたらコールバック関数の実行結果をrecvに渡す
- $cv->recvがメインループ
- $cv->recvの戻り値にsendで渡した引数が入る
I/O
- AnyEvent::Handle
- push_readのline,chunk(ある行数分),json(jsonを読み込み終わったら)
- AnyEvent::Sokect
- AnyEvnt::HTTP
- プリミティブなのでHeaderなどは自分でがんばって書かないといけない
モジュールの紹介
AnyEventのTips
- Transactions(multi signals)
- parallelにdownloadしたい場合は一時変数使って書きたくなるけど、そうじゃなくてsendを使わない書き方をする
- beginとendを使う
- parallelにdownloadしたい場合は一時変数使って書きたくなるけど、そうじゃなくてsendを使わない書き方をする
- watcherのスコープについて
- forの中で$wというwatcherを作り、forの外でrecvしようとするときに、何もしないとforが実行されたタイミングで$wが消えるため上手くいかない
- クロージャの循環参照の性質を使って、callbackの中で$wを参照すればいい。
- 中で参照すれば何でもいいんだけど、イディオムとしてはundefがいい
- my $w; $w = AnyEvent->timerと書いて、cb => sub { undef $w; }
- こうすると循環参照が起きて消えない
- my $w; $wとわざわざ2つに分けている理由は、my $w = AnyEvent->timerを定義している中で$wを参照することができないから
- 複数同時に立ち上げたい場合のやり方
- 複数の$cvを->recvでは受けられない
- $cv->cb(sub{ my $v = $cv->recv })
- or use Coro::AnyEvent
- malaさんが明日話すだろうから割愛
CPANにあげたい場合
- AnyEventを使ったモジュールはnewするのはイマイチ
- 単純な関数で書いた方がいい
- AnyEvent::mDNSを参考に
- 単純な関数で書いた方がいい
- 循環参照使うとメモりリークするから気を付ける
- Scalar::Util::weakenを使って確認する
- 最近できたAEという名前空間は引数の個数とか見てくれるのでコンパイル時にエラーが出てくれていい
質問
優しいモダンなWAFの作り方 (How to develop modern web application framework) - id:dann
- Angelosというフレームワークを作ってる
WAFの基本構成要素
- Engine
- requestを受けて、responseを返す(Plackでのサーバ抽象化)
- Dispatcher
- URLをController名へマッピング
- Component Manager
- コントローラなどのロード
Plackを枠にしたWAFの作り方にしました
拡張部分について(拡張性)
- あるべき姿
- コアは小さく
- 拡張箇所を限定
- Contoroller,View,Middleware,Request,Response
- Hookポイントを明示的に
- プラグインの種類は大きく分けて2つ
- ライスサイクルのHook系
- MouseのRole + method modifier
- Class::Trigger
- MouseX::Object::Pluggable
- メソッド生やす系
- MouseのRole
- Exporter
- 多重継承
- ライスサイクルのHook系
- プラグインの作り方
- PluginをRoleに
- RoleはControllerにwithすることで使う
- HooKポイントを明示(規約)
- 大文字でACTION
- プラグインのコードはbefore 'ACTION'とafter 'ACTION'
- 適切なデフォルトセットの提供をする
- ないとutf8flagがどうのとかそういうの考えなくてはいけない
- PluginをRoleに
- まとめ
- WAF作りがかつてないほど簡単になってる
CPAN::Packager - ひきつづき id:dann
- CPANモジュールの依存関係を再起的に解決して自動でRPM/Debパッケージにしてくれるモジュール
- モチベージョン
既存ツールの課題
- 依存関係を解決してくれない
- CPANPLUS::Dist::{Deb,RPM}
- 依存関係の解決が1段階
ツールが満たすべき要件
- 依存関係を再起的に解決
- 手動で既存モジュールのFixが可能
- 入れたくないモジュールは入れないように設定するなど
- CPAN::Packagerは上記を満たしてる
CPAN::Packager使い方
- オプション--builderでRPMなどの指定、confで設定
- 設定ファイルで依存関係や手動での条件を書く
- globalでモジュール共通の全体設定、とmodulesでモジュール毎の設定
- 設定ファイルで依存関係や手動での条件を書く
質問
- 古いバージョンのモジュールを残したい場合は?
- cpanminiでmirrorしないようにするか、手動でskipしてビルドするか
- local::libに比べてメリットは?
- 使ってるのだけど、configが結構めんどくさい
- configのサンプルがあるのでそれ見るとある程度わかりやすいかなと思う
- buildする時にtestはしてない?
- RPM版はそういうモードがあるが、テストしてインストールしてというのをくり返さないといけないので処理が大変
- CPAN::Packager自体が依存関係でかい
- 笑。CPANPLUSの依存関係が多い。パッチwelcome
- CPANPLUSの依存関係はgithubにextlib置くのがいいんじゃないかな?
Key Value Store with O/R Mapper - Kazuhiro Osawa (id:yappo)
- KVSとORMを組み合わせ
Data::Modelって何?
- ORM
- Data::ObjectDriverのようなもの
- webアプリケーション上ではORMはKVSだからそれ用に
スキーマ定義
- use Data::Model:Scema;でDSLをインストール
- install_model user => schema {} でuserテーブルが作れる
- key 'user_id'でprimary keyを指定
- column qw/ /でカラムを設定
使い方
基礎知識
なぜ他のモジュールを選ばなかったの?
- 結論から言うと満足する物を自分で作る方が速かった
- 使おうとしたモジュールの選定基準
- webアプリはindex張ってあるkeyを基準にひっぱってくる
- JOINは考慮しない
- テーブルを複数のDBサーバへ分散する時に面倒
- Schema定義で楽したい
- DB以外のデータソースも扱いたい
- KVS風な物
- 他モジュール
- Class::DBIは実績はあるが古い
- DBIx::CLassは昔使ったトラウマで選ばなかった
- Roseは見る暇なくJifty::DBIはJiftyでないと旨味なさそう
- DSL周りは参考にした
- Fey::ORM
- use Moose使ってるのは…
- DBIx::MoCo
- ドキュメント少ない
- infrate周りは参考にした
- Data::ObjectDriver
- 本当はこれが使いたかった
- ググっても全然日本語情報なくて辛い
- SixApartが想定する使い方以外だとどうなるかわからない
- DBIx::Skinny
- 一年前はバグ多そうだった
- 今はそうでもないらしいので次のセッションで聞いてみて
ORMを作るポイント
使い方
- lookup
- memcacheのインタフェースに合わせてる
- insert
- kvsなのでsetにした
- column sugar
- ものぐさな人におすすめ
- column_sugarを定義するとそれを利用できる
- あんまないかもだけど、開発中にスキーマ変えまくった時とか便利
- alias_colum
- バイナリデータをDBに格納するカラムがある時に、カラムにエイリアスを張ることで文字列形式とバイナリ形式の両方の形を利用できる
- CREATE TABLE
- auto incrementの流儀の違いなどを吸収
- 透過キャッシュ
- キャッシュがなければDBにアクセス
- mysql master slave
- slaveを一つしか設定できないが、LBでわけるのでそれでいい
- add methodでメソッドを生やせる
- mixin
- DBICのResultSet拡張的なこと
- Q4M
- queue_running
- transaction
- tx_scope, rollback, commit
DBIx::Skinny -simple OR mapper - モバイルファクトリー id:nekokak
どうして作ったか
DBICの問題点
DBICの素晴らしい部分
- 慣れれば簡単に色んなことができて開発効率あがる
- resultsetを使ったメンタルなsearchがかなり便利
- Pluginも豊富
- 有名なPerlHackerがメンテナンスしてるので安心
結局のところなんでDBICにしなかったか?どうしてDBIx::Skinny作ったか?
- 不満の部分をどうにかしたかった
- 周りと話をすると同じことを思ってる人が多かった
- 他にもモジュールあったけど、生のSQLをいい感じにしてくれるのがなかった
設計方針
ルールベースって?
- 取得したデータをオブジェクトにする際、特定のカラムについてはutf8,inflateの処理が必要
- 設定したルールにマッチしたカラム全てに対して処理
- 「このカラム名の場合はこうする」って決めで十分だと思ったので。
使い方
relationshipについて
- テーブル間のリレーションは特に何もしてない
- DBICのようなhas_many/belongs_toはない
- あると便利だからあると使っちゃうけど、それが問題になる
- 裏側ではたくさんクエリ発行されている可能性がある
ラッパー
- Skinnyはなるべく小さく設計している
- 拡張部分はラッパを書くことおすすめ
- nekoyaさんがDBIx::Skinny::ARを作ってる
- 拡張部分はラッパを書くことおすすめ
- コア部分で対応する部分は対応するの意見募集
まとめ
- CPANにあるので使ってみて
- githubに置いてある
Corporate Perl in Recruit, OpenSocial and Emoji - id:iandeth, id:kawanet
- 2人でリクルートのことと、絵文字のことについて発表
(まずはいしばしさんからリクルートについて)
- Recruit Web Service
- 結構な量ある
- コンテンツの再利用が難しいという問題点があった
- システムが再利用目的ではない
- コストが高い
社内の事例
Perlについて
- ModPerl::RegistryPrefork
アジャイル開発
- テストを書く
- 役割分担をしないでみんなでやる
- これが結構効果的
今後
- 10月にiPhoneのホットペッパー(FooMoo)アプリが新しくなるよ
- 去年出したやつはSafari+JavaScriptだったけどレスポンス遅過ぎたのでObjective-Cで作り直し
(次にかわさきさんの発表)
- 前夜祭にやったLiveSliesは時間がないので封印
Emoji
内部処理
- 内部的にはcp932に一回変換してtr//等で置換する仕組み
- utf8flagが立ってるtrだと3倍くらい遅いけどid:dankogaiが仕方ないと言ってるので仕方ない
例
- うんこの例
注意点
- googleのutfは4バイトあるのでMySQL5に格納できない
(話変わって)CREYLEについて
- http://creyle.jp/
- FastCGI + HTTP::Engine
- OpenSocial対応
- osapi(通称:オサピー)に対応している
- newIdSpec不要で簡潔に書ける
今年もMA5やるよ
- 今日から募集
LT
Moose Hacking Guide - id:gfx
- Mooseのソースコードでも読んでみるか
- モジュール多過ぎて読めない
- カテゴリ分け
- MooseとMoose::Role
- Moose::Util
- Moose::Error
- Moose::Object
- Moose::Exporter
- すさまじくでかい
- Moose::Meta::*
- 実際のコアの動き
- Moose::Meta::Instance
- MOPのインスタンスと同じ
- Moose::Meta::Class
- クラスを管理するクラス
- Moose::Meta::Attribute
- hasなど
- Moose::Meta::Method
- コードリファレンスの扱いやすいラッパ
- Moose::Meta::Role
- ロールの為のクラス
- Moose::Meta::TypeConstraints
- TCオブジェクトを実装
- ソースコードを読むにはNYTProf使えばいい
- いいソースコードビューア
- モジュールはたくさんあるけど10種類くらいに分けられる
Perlでsalefsforce - fujiwara 藤原 俊一郎
- Salesforceとは
- perlでどう使うか
- WWW::Salesforce
- kvsでなくSQLに似たSOQLという言語で問い合わせ
- API回数制限と速度がある
- なので接続確認はしない方がいい
- upsertを使う
- updateとinsertを両方一発でできる
- アメリカにあるのでたまに繋がらない
- 更新系はjob queueでやった方がいい
WebアプリケーションフレームワークMojoの紹介 - 木本裕紀(id:perlcodesample)
Test::TCP - id:tokuhirom
im.kayac.comの紹介 - Daisuke Murase(id:typester)
miyagawanize - ゆーすけべー(id:kamawada)
- purple thingについて
- CPANの紫色のアレ
- purple thingを画像に付けるscriptを作成
- OpenCVの顔認識で紫色のものを付ける
- 実例
- オバマもいける
- (「yes, we can!」で大盛り上がり)
- モー娘のような集合写真でもいける
- ギークじゃないのかゴマキだけいけない
- オバマもいける
nginxやlighttpdでMogileFSしてみた - id:kamipo
Server::Starter - kazuho oku(id:kazuhooku)
- ホットデプロイの話
- サーバをリスタートすることなくバージョンアップする
- Server::Starter
- SIGHUPすると新しいアプリをfork&execし、うまくいけば古いやつは消す
- 新しいアプリのコンパイルが失敗しても古いプロセスが生きているので問題ない
- SIGHUPすると新しいアプリをfork&execし、うまくいけば古いやつは消す
- deamontoolsと組み合わせるといい
Yuval Kogman(nothingmuch)
- ironmanプロジェクトに参加
- 今回はdieの話
- dieのcatchはevalでやるがeval is EVIL
- $@ = ""となってcatchできない時がある
- local $@を使っても問題ある
- $@ = ""となってcatchできない時がある
- 色々解決しようとしても問題が出て来て、解決法の解決法がどんどんでてくるので、
- Try::Tinyがいいよ