Crafting Rails4 Applications
7. Managing Application Events with
Mountable Engines
morimorihoge
この章で解説すること
• 大きなテーマは三つ
– Mountable Engineによって汎用性の高い機能を
mountする様なコードを書く
• Chap. 5でやったのはEngineそのものをextendしていた
が,もっとうまくやれるぜ
–...
Mountable/Isolated Engines
• 独自にEngineをExtendすると・・・
– Routing namespace等が共有されるため,名前の衝
突が怖い
• rake routesしたときに,Engine拡張して作っ...
とりあえずrails plugin new
• --mountableオプションを付ける
--mountableあり
--mountableなし
Rails.application.routesを直接拡張しないようになる
Mountable e...
アプリ側でmountする
これで/mongo_metrics以下にmountable engineのroutesが組み込まれる
Mountable engine
Routing的にも別々(Engine別)に表示される
mountの内部
• routingの内部的には
get/post/put/delete/resources/resource等は全
てmatch()のwrapper
• mount()はそもそも挙動が全く別物で,Engineを
指定URL以下...
Namespace Isolation
Isolated engine
PluginのEngine側にisolate_namespaceを記述することで,Engine内で使う
クラスが自動的にnamespaceを補完する様になる
pp.133
ActiveSupport::Notifications API
• よくあるpub/sub式のevent API
– Publish : ActiveSupport::Notifications.instrument(event_name, ...
MongoDB/Mongoid gem
• MongoidはMongoDB
を楽に使うためのGem
• Mongoid::Documentを
includeし,store!を実
装すれば良いよ!
MongoDB/Mongoid
MongoMetrics::Engineの実装
MongoMetrics::Engine
普通のRailsアプリの様に実装して良いが,MongoMetrics moduleに入れる必要が
あることに注意(Isolated Engine)
(以下...
テストコード
MongoMetrics::Engine
適当なRouting呼び出しをさせればNotificationが飛ぶので,test/dummy以下で
$ rails new controller Home foo bar baz
してお...
Rack Basics
Rack
Rackの基本
・リクエストをcall()に投げる
・callの返値は[STATUS_CODE, HEADER, RESPONSE_BODY]
・RESPONSE_BODYはeachを実装していること
conf...
Rack on Rails
Rack
Railsのconfig.ru
Rails RouterとRackのカンケイ
Rack
Config/routes.rbはこんな書き方ができる
Rackのcall(env)メソッドそのもの
toが文字列の場合,自動的に呼び出し先を変換している.
”post#index”なら以...
Rack middleware
Rack middleware stack
rake middleware
Rack middleware stack
インストールされたミドルウェア一覧を取得できるrakeコマンド
この順序を眺めながらメシが食える
(上に行くほど先に適用される)
rake middlewares (1)
Rack middleware stack
rake middlewares (2)
Rack middleware stack
Adding Rack Middlewares
Rack middleware stack
Controllerで任意のmiddlewareを使うには,useすれば良いだけ
MuteMiddleware
Rack middleware stack
MongoMetricsはそのままだと全てのアクセスに対してログを記録してうるさいので,
それを黙らせるmiddlewareを作る
こんな感じでブロックでmuteさせたい
MuteMiddleware
Rack middleware stack
特に何事も無い感じの実装
MuteMiddlewareをどこに入れるか?
Rack middleware stack
MuteMiddlewareをインストールする
Rack middleware stack
MongoMetricsのEngineではデフォルトmute
アプリケーション側ではMuteしたいもので個別にmute
必要の無いdependencyを減らす
Gem optimization
Gemspecにrailsのdependencyを書くと,ActionMailerやActiveRecordなど,plugin
に本来必要無いgemもdependしてしま...
Streaming plugin
Another sample of plugin development
MongoMetricsのデータをCSV streamingで出すぜ
Content-Lengthを削除することでstreamingにな...
Rack-level v.s. Rails-level
Another sample of plugin development
Streaming的なことは,Rack middlewareレベルで書くこともできる
Rackアプリとして#eac...
まとめ
• Mountable/Isolated Engineの説明をして,
MountableなEngineを含むMongoMetricsプラ
グインを作成したよ!
• Rack middlewareの挙動を追いかけて
middleware ...
Upcoming SlideShare
Loading in …5
×

Crafting Rails4 Applications読み回 7. Managing Application Events with Mountable Engines

1,380 views
1,287 views

Published on

身内向けにやったCrafting Rails 4 Applicationsの読み会資料です

Published in: Software
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,380
On SlideShare
0
From Embeds
0
Number of Embeds
251
Actions
Shares
0
Downloads
3
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Crafting Rails4 Applications読み回 7. Managing Application Events with Mountable Engines

  1. 1. Crafting Rails4 Applications 7. Managing Application Events with Mountable Engines morimorihoge
  2. 2. この章で解説すること • 大きなテーマは三つ – Mountable Engineによって汎用性の高い機能を mountする様なコードを書く • Chap. 5でやったのはEngineそのものをextendしていた が,もっとうまくやれるぜ – ActiveSupport::NotificationによるRailsの提供する pub/sub event API – Rack middlewareの仕組みと内部構造 • Railsのバックエンドを覗いてmiddlewareを作りつつ動 きを見るぜ
  3. 3. Mountable/Isolated Engines • 独自にEngineをExtendすると・・・ – Routing namespace等が共有されるため,名前の衝 突が怖い • rake routesしたときに,Engine拡張して作ったplugin routes なのか,アプリ用に作ったroutesなのか分からなくなる • HelperやらModelも同様 • Mountable Engineを使うと – アプリ側のrouterと別々の名前空間でroutingが使え る • Isolated Engineを使うと – model/controller/view/assets/helperをpluginの名前 空間内に閉じ込められる
  4. 4. とりあえずrails plugin new • --mountableオプションを付ける --mountableあり --mountableなし Rails.application.routesを直接拡張しないようになる Mountable engine
  5. 5. アプリ側でmountする これで/mongo_metrics以下にmountable engineのroutesが組み込まれる Mountable engine Routing的にも別々(Engine別)に表示される
  6. 6. mountの内部 • routingの内部的には get/post/put/delete/resources/resource等は全 てmatch()のwrapper • mount()はそもそも挙動が全く別物で,Engineを 指定URL以下に指定し,処理をブン投げる pp.142 env[“SCRIPT_NAME”]/env[“PATH_INFO”]から/mongo_metricsを削除して Engineに投げることで,MongoMetrics::Engine内部ではそもそも /mongo_metrics部分は見えない (元アプリ側の参照はmain_app()で取得可能) Mountable engine
  7. 7. Namespace Isolation Isolated engine PluginのEngine側にisolate_namespaceを記述することで,Engine内で使う クラスが自動的にnamespaceを補完する様になる pp.133
  8. 8. ActiveSupport::Notifications API • よくあるpub/sub式のevent API – Publish : ActiveSupport::Notifications.instrument(event_name, payload) • Blockを渡すとBlock部分の時間がsubscriberに通知される – Subscribe: ActiveSupport::Notifications.subscribe(event_name) pp.133 pp.134 ※instrumentは全てのsubscriberに通知される Loggerなんかで使われることを想定 Notifications API
  9. 9. MongoDB/Mongoid gem • MongoidはMongoDB を楽に使うためのGem • Mongoid::Documentを includeし,store!を実 装すれば良いよ! MongoDB/Mongoid
  10. 10. MongoMetrics::Engineの実装 MongoMetrics::Engine 普通のRailsアプリの様に実装して良いが,MongoMetrics moduleに入れる必要が あることに注意(Isolated Engine) (以下略) Routingは普通のRailsアプリの様に書ける
  11. 11. テストコード MongoMetrics::Engine 適当なRouting呼び出しをさせればNotificationが飛ぶので,test/dummy以下で $ rails new controller Home foo bar baz しておく main_appでアプリ側を参照できる
  12. 12. Rack Basics Rack Rackの基本 ・リクエストをcall()に投げる ・callの返値は[STATUS_CODE, HEADER, RESPONSE_BODY] ・RESPONSE_BODYはeachを実装していること config.ru pp.141 config.ruがあるディレクトリで $ rackup すればRack serverが起動する(-sでWeb serverを選べる)
  13. 13. Rack on Rails Rack Railsのconfig.ru
  14. 14. Rails RouterとRackのカンケイ Rack Config/routes.rbはこんな書き方ができる Rackのcall(env)メソッドそのもの toが文字列の場合,自動的に呼び出し先を変換している. ”post#index”なら以下のController.action()を返す(action()の戻り値はcall()を実装している)
  15. 15. Rack middleware Rack middleware stack
  16. 16. rake middleware Rack middleware stack インストールされたミドルウェア一覧を取得できるrakeコマンド この順序を眺めながらメシが食える (上に行くほど先に適用される)
  17. 17. rake middlewares (1) Rack middleware stack
  18. 18. rake middlewares (2) Rack middleware stack
  19. 19. Adding Rack Middlewares Rack middleware stack Controllerで任意のmiddlewareを使うには,useすれば良いだけ
  20. 20. MuteMiddleware Rack middleware stack MongoMetricsはそのままだと全てのアクセスに対してログを記録してうるさいので, それを黙らせるmiddlewareを作る こんな感じでブロックでmuteさせたい
  21. 21. MuteMiddleware Rack middleware stack 特に何事も無い感じの実装
  22. 22. MuteMiddlewareをどこに入れるか? Rack middleware stack
  23. 23. MuteMiddlewareをインストールする Rack middleware stack MongoMetricsのEngineではデフォルトmute アプリケーション側ではMuteしたいもので個別にmute
  24. 24. 必要の無いdependencyを減らす Gem optimization Gemspecにrailsのdependencyを書くと,ActionMailerやActiveRecordなど,plugin に本来必要無いgemもdependしてしまう Dependencyを個別に書くことで,pluginの依存関係はすっきりする # ただし,これをやるとdummyアプリケーションの方でActionMailerやActiveRecord # に依存する部分の定義を外さないとテストが通らなくなるので注意 pp.149
  25. 25. Streaming plugin Another sample of plugin development MongoMetricsのデータをCSV streamingで出すぜ Content-Lengthを削除することでstreamingになる 詳細はpp.151辺りを参照.見ればわかります
  26. 26. Rack-level v.s. Rails-level Another sample of plugin development Streaming的なことは,Rack middlewareレベルで書くこともできる Rackアプリとして#eachをstreaming ぽく返す様に作ればstreamingで返せる Rack-levelで実装した方がmiddlewareの読み込み数が減るのでオーバーヘッドは小さい が,Rails-levelで実装した方がデータサイズに応じた処理などがやりやすい. どっちで実装すべきかは実装時に考えましょう
  27. 27. まとめ • Mountable/Isolated Engineの説明をして, MountableなEngineを含むMongoMetricsプラ グインを作成したよ! • Rack middlewareの挙動を追いかけて middleware chainを覗いたよ • 使わないgem dependencyを削って最適化し たよ!やったね!

×