Top Banner
つながりをゆるふわにしよう ActiveSupport::Notifications 2013-11-02 広島Ruby勉強会 #035
53

つながりをゆるふわにしよう Active supprt notifications

Jul 09, 2015

Download

Technology

Tomohiko Himura

広島Ruby勉強会 #035 にて http://hiroshimarb.github.io/blog/2013/11/02/hiroshimarb-35/

ActiveSupport::Notifications について。
スライドをつくるための原稿はこっちにある。

https://gist.github.com/eiel/7177959

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: つながりをゆるふわにしよう Active supprt notifications

つながりをゆるふわにしよう ActiveSupport::Notifications2013-11-02 広島Ruby勉強会 #035

Page 2: つながりをゆるふわにしよう Active supprt notifications

Rails のコードリーディング

•コード読んでるので毎月ピックアップ • http://railsdoc.eiel.info/ • 今回は ActiveSupport::Notifications

Page 3: つながりをゆるふわにしよう Active supprt notifications
Page 4: つながりをゆるふわにしよう Active supprt notifications
Page 5: つながりをゆるふわにしよう Active supprt notifications

ActiveSupport::Notifications

•通知を実現するためのクラス •オブジェクト間を緩い繋りに

Page 6: つながりをゆるふわにしよう Active supprt notifications

オブジェクトの繋り

•オブジェクトはメッセージで繋る •メッセージを送る方法 •メソッドの呼び出し

Page 7: つながりをゆるふわにしよう Active supprt notifications

オブジェクトの繋り

•直接メソッド呼び出し •繋りが強い •ちょっと回り道をする •繋りを緩くできる

Page 8: つながりをゆるふわにしよう Active supprt notifications

どうして緩くしたいか

•変更箇所を減らしたい •本質と関係ないものを分離

Page 9: つながりをゆるふわにしよう Active supprt notifications

どうして通知が欲しいかみていく

•普通の呼び出し •処理を後から登録 •通知を使う

Page 10: つながりをゆるふわにしよう Active supprt notifications

普通の呼び出し

•強い繋り • 1対1の繋り

Page 11: つながりをゆるふわにしよう Active supprt notifications

普通の呼び出し

a b

作る

メソッドを呼ぶ

Page 12: つながりをゆるふわにしよう Active supprt notifications

問題点

•後から処理を追加するのに •コードの変更が必要

Page 13: つながりをゆるふわにしよう Active supprt notifications

class A def hoge # hogeする

end end !a = A.new a.hoge

Page 14: つながりをゆるふわにしよう Active supprt notifications

a を hoge するときに b.hoge して欲しい

Page 15: つながりをゆるふわにしよう Active supprt notifications

例class B def hoge # B hoge する

end end !class A def hoge # hoge する

B.new.hoge end end

Page 16: つながりをゆるふわにしよう Active supprt notifications

さらに追加したくなった

Page 17: つながりをゆるふわにしよう Active supprt notifications

例class B def hoge # B hoge する

end end !class A def hoge # hoge する

B.new.hoge B.new.hoge end end

Page 18: つながりをゆるふわにしよう Active supprt notifications

Aを変更しなきゃいけない

Page 19: つながりをゆるふわにしよう Active supprt notifications

Aが変えたくない場合がある

• Aがライブラリやフレームワーク •完成しているので変えられない • Aが自分が作ったBを知ってるわけがない

Page 20: つながりをゆるふわにしよう Active supprt notifications

処理を後から登録する

•少し弱くなった繋り • 1対多の繋り

Page 21: つながりをゆるふわにしよう Active supprt notifications

処理を後から登録する

•ルールを決める •オブジェクトを登録できるように •決めたメソッドを呼ぶ

Page 22: つながりをゆるふわにしよう Active supprt notifications

b

処理を後から登録する

a

b

メソッドを呼ぶ b

b

オブジェクトを登録

0個からn個

Page 23: つながりをゆるふわにしよう Active supprt notifications

例class A def hoge # hoge する

objects.each do |object| object.hoge end end ! def objects @objects ||= [] end end !a = A.new a.hoge

Page 24: つながりをゆるふわにしよう Active supprt notifications

b.hoge を追加したい

Page 25: つながりをゆるふわにしよう Active supprt notifications

a = A.new a.objects << B.new a.hoge

Page 26: つながりをゆるふわにしよう Active supprt notifications

Aの外側で Aに処理を追加できる

Page 27: つながりをゆるふわにしよう Active supprt notifications

問題点

• b を追加するのに a を知ってる必要がある •オブジェクトへの参照が必要

Page 28: つながりをゆるふわにしよう Active supprt notifications

通知を使う

•文字列で繋りを作る •だいぶ ゆるふわ •多対多の繋り

Page 29: つながりをゆるふわにしよう Active supprt notifications

通知を使う

•通知を呼び出す側 •相手のことを意識する必要がない •呼ばれる側 •相手のことを意識する必要がない

Page 30: つながりをゆるふわにしよう Active supprt notifications

a

処理を後から登録する

b

メソッドを呼ぶb

b

処理をお願いする 通知システム

a

b登録しておく

Page 31: つながりをゆるふわにしよう Active supprt notifications

通知システムを経由することで a と b の直接的な繋りを無くせる

Page 32: つながりをゆるふわにしよう Active supprt notifications

代わりに 通知システムに 強い繋りが

Page 33: つながりをゆるふわにしよう Active supprt notifications

具体例class Notifications @@regists = Hash.new([]) ! def self.regist(key,object) @@regists[key] << object end ! def self.notify(key) @@regists[key].each do |object| object.hoge end end end

Page 34: つながりをゆるふわにしよう Active supprt notifications

具体例

# 通知 hoge があったときにすることを登録

Notifications.regist(‘hoge’, B.new) !# 通知 hoge を発生させる

Notifications.notify(‘hoge’)

Page 35: つながりをゆるふわにしよう Active supprt notifications

ActiveSupport::Notifications

• Rails で通知を使うためのクラス • Rails 3 で追加 • Developmentモードで • HTMLの生成時間と • SQLの実行時間

Page 36: つながりをゆるふわにしよう Active supprt notifications

ActiveSupport::Notifications

•やりすぎ注意 •処理の流れを明確にしたいところでは使わないように

• Rails の中にも通知ポイントがある

Page 37: つながりをゆるふわにしよう Active supprt notifications

使い方

•通知の仕方 • ActiveSupport::Notifications.instrument • 処理の登録 • ActiveSupport::Notifications.subscribe

Page 38: つながりをゆるふわにしよう Active supprt notifications

通知の仕方

•後で処理を追加したくなりそうだなー。 • ActiveSupport::Notifications.instrument(name, payload)

• name •処理を登録する時に使う名前 • payload • 登録した処理に渡す追加情報

Page 39: つながりをゆるふわにしよう Active supprt notifications

処理の登録

• ActiveSupport::Notifications.subscribe(pattern,&block)

• pattern • 通知のした際の name •正規表現が使える • block • したい処理

Page 40: つながりをゆるふわにしよう Active supprt notifications

pattern

• pattern には正規表現が • /hoge/ であれば • instrument の name が • hoge.mogu • mogu.hoge • でも実行される

Page 41: つながりをゆるふわにしよう Active supprt notifications

block

• block の中で使える情報 • name • start • finish • id • payload

Page 42: つながりをゆるふわにしよう Active supprt notifications

name

• Notifications.instrument した時の引数 • pattern で指定しているので 正確な名前が欲しい時に

Page 43: つながりをゆるふわにしよう Active supprt notifications

例require ‘active_support/notifications’ !include ActiveSupport !Notifications.subscribe(/hoge/) do |name| puts name end !Notifications.instrument(“hoge.goro”) Notifications.instrument(“goro.hoge”) # >> hoge.goro # >> goro.hoge

Page 44: つながりをゆるふわにしよう Active supprt notifications

start finish

• instrument側の 処理の時間を測定できる

•始めの時間と終わりの時間 • instrumentする際にブロックを使う

Page 45: つながりをゆるふわにしよう Active supprt notifications

例require ‘active_support/notifications’ !include ActiveSupport Notifications.subscribe(/hoge/) do |name, start, finish| p [start, finish] end !Notifications.instrument(“hoge”) do sleep(1) end # >> [2013-11-01 15:54:13 +0900, 2013-11-01 15:54:14 +0900]

Page 46: つながりをゆるふわにしよう Active supprt notifications

id

•通知システム内の通知者のID •スレッドごとに変化する • (別に知らなくて良い気がする)

Page 47: つながりをゆるふわにしよう Active supprt notifications

例require ‘active_support/notifications’ require ‘thread’ !include ActiveSupport Notifications.subscribe(‘hoge’) do |name, s, f, id| p [name, id] end !Notifications.instrument(‘hoge’) Notifications.instrument(‘hoge’) Thread.new { Notifications.instrument(‘hoge’) }.run

Page 48: つながりをゆるふわにしよう Active supprt notifications

例 結果

["hoge", "8c71812749ca24e5a40e"] ["hoge", "8c71812749ca24e5a40e"] ["hoge", "c1050d011fe625537e41"]

Page 49: つながりをゆるふわにしよう Active supprt notifications

payload

•メソッドのように引数を使いたい

Page 50: つながりをゆるふわにしよう Active supprt notifications

例require ‘active_support/notifications’ !include ActiveSupport Notifications.subscribe(‘hoge’) do |n, s, f, i, payload| p payload end !Notifications.instrument(‘hoge’, :hoge) Notifications.instrument(‘hoge’,{hoge: 1}) # >> :hoge # >> {:hoge => 1}

Page 51: つながりをゆるふわにしよう Active supprt notifications

より深いどうでもいいところ

• ActiveSupport::Notifications::Instrumenter • 通知処理を実質的にしているクラス •スレッド毎に存在

Page 52: つながりをゆるふわにしよう Active supprt notifications

より深いどうでもいいところ

• ActiveSupport::Notifications::Fanout • 登録した処理を管理しているところ • ActiveSupport::Notifications::Fanout::Subscribers • 処理はこのモジュールの中にあるクラスのいずれかにラップされる

• finish がいるかどうかとかで区分される •呼ばれる予定処理を確認したりもできる

Page 53: つながりをゆるふわにしよう Active supprt notifications

ご清聴ありがとうございました