Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
再考 アクターモデル/ reconsider actor model
Search
yuuki takezawa
September 17, 2024
Technology
1.6k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
再考 アクターモデル/ reconsider actor model
吉祥寺.pm36でのトークです
yuuki takezawa
September 17, 2024
More Decks by yuuki takezawa
See All by yuuki takezawa
なぜAI時代に 「イベント」を中心に考えるのか? / Why focus on "events" in the age of AI?
ytake
4
2.1k
PHPでアクターモデルを活用したSagaパターンの実践法 / php-saga-pattern-with-actor-model
ytake
0
2.6k
PHP ステートレス VS ステートフル 状態管理と並行性 / php-stateless-stateful
ytake
0
330
PHPでアクターモデルを理解・体験しよう / Understand and experience the actor model in PHP
ytake
2
950
GoとアクターモデルでES+CQRSを実践! / proto_actor_es_cqrs
ytake
1
670
Phluxorでアクターモデルを 理解・体験しよう / toolkit-for-flexible-actor-models-in-php-phluxor
ytake
1
380
オブジェクトのおしゃべり大失敗 メッセージングアンチパターン集 / messaging anti-pattern collection
ytake
2
1.3k
DRE/SREのプラクティス融合によるクラウドネイティブなデータ基盤作り / dre_sre
ytake
0
1k
技術的負債と向き合う取り組みでよかったもの / positive_efforts_to_tackle_technical_debt
ytake
10
4.1k
Other Decks in Technology
See All in Technology
小さいから、全部わかる。— 常駐AI "xangi" のすすめ
sugupoko
0
250
スタートアップにおけるアジャイルの実践について #shibuyagile
murabayashi
3
2k
そのタスクオンスケですか?
poropinai1966
0
120
きのこカンファレンス2026_肩書きを外したとき私は誰か
yamasatimi
1
130
フルAIで個人開発して学んだあれこれ / yuruai vol.1
isaoshimizu
0
170
HookでSAST、CIでSAST、SCAでどうにかしている話 / layered-security-for-ai-written-code-with-sast-and-sca
yamaguchitk333
0
100
依頼文化をやめる日 EM視点で語るPlatform EngineeringとInclusive SRE / Discussing Platform Engineering and Inclusive SRE from an EM's Perspective
shin1988
0
150
CSに"SLO"は要らない、経営層に"99.9%"は伝わらない - SREを全社に"翻訳"する3原則
cscengineer
PRO
0
100
LiDAR SLAMの実装とセンサ融合 ~Lie群からContinuous-Time LIOまで~
naokiakai
1
920
AIペネトレーションテスト・ セキュリティ検証「AgenticSec」紹介資料
laysakura
2
8k
RAGの精度向上とエージェント活用
kintotechdev
2
120
Text-to-SQLをAgentCoreで実現し、生成されるSQLの精度を定量的に評価する
yakumo
2
470
Featured
See All Featured
Optimising Largest Contentful Paint
csswizardry
37
3.8k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
180
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
180
Rebuilding a faster, lazier Slack
samanthasiow
85
9.5k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.1k
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
180
Side Projects
sachag
455
43k
The Spectacular Lies of Maps
axbom
PRO
1
840
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.3k
Designing for Performance
lara
611
70k
Transcript
࠶ߟ ΞΫλʔϞσϧ ٢ࣉ.pm36 yuuki takezawa / ytake
Pro fi le • ᖒ ༗و a.k.a ytake • ઍגࣜձࣾ
CTO / ΄͔ٕज़ސʢωοτϓϩςΫγϣϯζͳͲʣ • Go / Scala / Kotlin • ΞΫλʔϞσϧେ͖
ΞΫλʔϞσϧͬͯʁ • 1973ʹൃද͞ΕͨฒߦܭࢉͷֶతϞσϧͷҰछ • ৽͍͠ͷͰ͋Γ·ͤΜ • ErlangScalaͳͲͰ͓ͳ͡Έ • ϝϞϦڞ༗ΛߦΘͣɺϊϯϒϩοΩϯάͰ ಠཱͨ͠ΞΫλʔ͕ঢ়ଶΛ࣋ͭ
ΞΫλʔͷ • ΞΫλʔͷϝοηʔδΛૹ৴͢Δ • ΞΫλʔΛੜ͢Δ • ϝοηʔδʹద༻͢Δಈ࡞Λߦ͏
None
ΞΫλʔϞσϧͬͯʁ • ΞΫλʔಠཱͯ͠ಈ࡞͠ɺͦΕͧΕ͕ϥΠϑαΠΫϧΛ࣋ͭ • ϝϞϦͷڞ༗ͳͲҰߦΘͳ͍ • ΞΫλʔΛૢ࡞͢Δ͜ͱෆՄೳͰΠϛϡʔλϒϧ • ϝοηʔδͷΈͰΓऔΓΛߦ͏ •
Ґஔಁաੑ
ग़య https://petabridge.com/blog/akkadotnet-what-is-an-actor/
Ґஔಁաੑ • ΞΫλʔϩʔΧϧϦϞʔτɺΫϥελͰಈ࡞Ͱ͖Δ • Ͳ͜ʹ͋Δͷ͔ɺͲͷΑ͏ʹͯ͠ݺͼग़͢ͷ͔ ίʔυ্Ͱ۠ผ͢Δ͜ͱ͕ͳ͘ͳΔ • ڥք͚ͮΒΕͨίϯςΩετΛجʹׂ͢Δ͜ͱɺ εϧʔϓοτ্ͷͨΊׂ͢Δ͜ͱ͕༰қ
ग़య https://pekko.apache.org/docs/pekko/current/general/addressing.html
ग़య https://pekko.apache.org/docs/pekko/current/general/addressing.html
֊ߏΛͭ
None
None
ϑΥʔϧττϨϥϯε • ώΤϥϧΩʔΛ࣋ͭͱ͍͏͜ͱ ΞΫλʔ͕ࢠΞΫλʔΛಜɾཧ͢ΔΛ࣋ͭ ࣄʹࣦഊͨ͠߹ʹͲͷΑ͏ͳઓུΛʁʢεʔύʔόΠβઓུʣ • ࢠؔʹͳ͍ΞΫλʔࢹ͢Δ͜ͱ͕Ͱ͖Δ • ࣦഊ࣌ʹͲͷΑ͏ʹ෮چͤ͞Δ͔ΛࢦࣔͰ͖Δ
ࢹྫ
func (state *parentActor) Receive(context actor.Context) { switch msg := context.Message().(type)
{ case *hello: props := actor.PropsFromProducer(newChildActor) child := context.Spawn(props) context.Send(child, msg) case *actor.Terminated: fmt.Println("child terminated", msg.Who) } } func newParentActor() actor.Actor { return &parentActor{} } type childActor struct{} func (state *childActor) Receive(context actor.Context) { switch msg := context.Message().(type) { case *actor.Restarting: fmt.Println("restarting") case *hello: fmt.Printf("Hello %v\n", msg.Who) context.Stop(context.Self()) } } func newChildActor() actor.Actor { return &childActor{} }
func (state *parentActor) Receive(context actor.Context) { switch msg := context.Message().(type)
{ case *hello: props := actor.PropsFromProducer(newChildActor) child := context.Spawn(props) context.Send(child, msg) case *actor.Terminated: fmt.Println("child terminated", msg.Who) } } func newParentActor() actor.Actor { return &parentActor{} } type childActor struct{} func (state *childActor) Receive(context actor.Context) { switch msg := context.Message().(type) { case *actor.Restarting: fmt.Println("restarting") case *hello: fmt.Printf("Hello %v\n", msg.Who) context.Stop(context.Self()) } } func newChildActor() actor.Actor { return &childActor{} } ΞΫλʔ
func (state *parentActor) Receive(context actor.Context) { switch msg := context.Message().(type)
{ case *hello: props := actor.PropsFromProducer(newChildActor) child := context.Spawn(props) context.Send(child, msg) case *actor.Terminated: fmt.Println("child terminated", msg.Who) } } func newParentActor() actor.Actor { return &parentActor{} } type childActor struct{} func (state *childActor) Receive(context actor.Context) { switch msg := context.Message().(type) { case *actor.Restarting: fmt.Println("restarting") case *hello: fmt.Printf("Hello %v\n", msg.Who) context.Stop(context.Self()) } } func newChildActor() actor.Actor { return &childActor{} } ࢠΞΫλʔ
func (state *parentActor) Receive(context actor.Context) { switch msg := context.Message().(type)
{ case *hello: props := actor.PropsFromProducer(newChildActor) child := context.Spawn(props) context.Send(child, msg) case *actor.Terminated: fmt.Println("child terminated", msg.Who) } } func newParentActor() actor.Actor { return &parentActor{} } type childActor struct{} func (state *childActor) Receive(context actor.Context) { switch msg := context.Message().(type) { case *actor.Restarting: fmt.Println("restarting") case *hello: fmt.Printf("Hello %v\n", msg.Who) context.Stop(context.Self()) } } func newChildActor() actor.Actor { return &childActor{} } ࢠΞΫλʔੜ ࣗಈతʹ֊ߏΛ࣋ͭ
func (state *parentActor) Receive(context actor.Context) { switch msg := context.Message().(type)
{ case *hello: props := actor.PropsFromProducer(newChildActor) child := context.Spawn(props) context.Send(child, msg) case *actor.Terminated: fmt.Println("child terminated", msg.Who) } } func newParentActor() actor.Actor { return &parentActor{} } type childActor struct{} func (state *childActor) Receive(context actor.Context) { switch msg := context.Message().(type) { case *actor.Restarting: fmt.Println("restarting") case *hello: fmt.Printf("Hello %v\n", msg.Who) context.Stop(context.Self()) } } func newChildActor() actor.Actor { return &childActor{} } ࢠΞΫλʔͷΞυϨε
func (state *parentActor) Receive(context actor.Context) { switch msg := context.Message().(type)
{ case *hello: props := actor.PropsFromProducer(newChildActor) child := context.Spawn(props) context.Send(child, msg) case *actor.Terminated: fmt.Println("child terminated", msg.Who) } } func newParentActor() actor.Actor { return &parentActor{} } type childActor struct{} func (state *childActor) Receive(context actor.Context) { switch msg := context.Message().(type) { case *actor.Restarting: fmt.Println("restarting") case *hello: fmt.Printf("Hello %v\n", msg.Who) context.Stop(context.Self()) } } func newChildActor() actor.Actor { return &childActor{} } ࢠΞΫλʔ͕ࣗѼͯͷϝοηʔδΛ ड͚औΔ ʢࣗಈͰৼΓ͚ΒΕ·͢ʣ
func (state *parentActor) Receive(context actor.Context) { switch msg := context.Message().(type)
{ case *hello: props := actor.PropsFromProducer(newChildActor) child := context.Spawn(props) context.Send(child, msg) case *actor.Terminated: fmt.Println("child terminated", msg.Who) } } func newParentActor() actor.Actor { return &parentActor{} } type childActor struct{} func (state *childActor) Receive(context actor.Context) { switch msg := context.Message().(type) { case *actor.Restarting: fmt.Println("restarting") case *hello: fmt.Printf("Hello %v\n", msg.Who) context.Stop(context.Self()) } } func newChildActor() actor.Actor { return &childActor{} } ࢠΞΫλʔ͕ࣗࣗΛఀࢭͨ͠ྫ
func (state *parentActor) Receive(context actor.Context) { switch msg := context.Message().(type)
{ case *hello: props := actor.PropsFromProducer(newChildActor) child := context.Spawn(props) context.Send(child, msg) case *actor.Terminated: fmt.Println("child terminated", msg.Who) } } func newParentActor() actor.Actor { return &parentActor{} } type childActor struct{} func (state *childActor) Receive(context actor.Context) { switch msg := context.Message().(type) { case *actor.Restarting: fmt.Println("restarting") case *hello: fmt.Printf("Hello %v\n", msg.Who) context.Stop(context.Self()) } } func newChildActor() actor.Actor { return &childActor{} } ΞΫλʔఀࢭ͕௨͞ΕΔ
ઓུ
decider := func(reason interface{}) actor.Directive { fmt.Println("handling failure for child")
return actor.StopDirective } supervisor := actor.NewOneForOneStrategy(10, time.Nanosecond, decider) rootContext := system.Root pid := rootContext.Spawn( actor.PropsFromProducer(newParentActor, actor.WithSupervisor(supervisor)))
decider := func(reason interface{}) actor.Directive { fmt.Println("handling failure for child")
return actor.StopDirective } supervisor := actor.NewOneForOneStrategy(10, time.Nanosecond, decider) rootContext := system.Root pid := rootContext.Spawn( actor.PropsFromProducer(newParentActor, actor.WithSupervisor(supervisor))) ࢠΞΫλʔ͕ࣦഊͨ͠߹ɺ ಉ֊ʹ͍ΔࢠΞΫλʔͷ͏ͪɺ ରͷͷ͚ͩఀࢭͤ͞Δྫ
ଞɺঢ়ଶมԽϧʔςΟϯάͳͲ
None
ैདྷͷΈʹͲ͏׆͔ͤΒΕΔ͔ʁ
ΞΫλʔͱ౷తͳߏ • ΞΫλʔϞσϧͱैདྷͷΞϓϦέʔγϣϯߏڞଘՄೳ • ઓज़ύλʔϯͳͲͰ ΞΫλʔ͕ΤϯςΟςΟʹͳΓঢ়ଶΛͭ • ΞΫλʔͷঢ়ଶมԽʢΠϕϯτʣΛอଘ͢Δ͜ͱͰ ϏϡʔΛΈཱͯΔ͜ͱ͕Ͱ͖ΔʢRead Model
Updateʣ
None
ֶߍͷςετྫ • ઌੜ͕ੜెʹରͯ͠ ͞Μ͢͏ͷςετΛ࣮ࢪ • ੜెͦΕͧΕݸͱͯ͠Λղ͘ • ઌੜςετதʹݟकΔͳͲͷߦಈ • શͯ͑ͨΒςετ༻ࢴΛఏग़͢Δ
4UVEFOU"DUPS 4UVEFOU"DUPS 4UVEFOU"DUPS 4UVEFOU"DUPS 4UVEFOU"DUPS
4UVEFOU"DUPS 4UVEFOU"DUPS 4UVEFOU"DUPS 4UVEFOU"DUPS 4UVEFOU"DUPS 5FBDIFS"DUPS
4UVEFOU"DUPS 4UVEFOU"DUPS 4UVEFOU"DUPS 5FBDIFS"DUPS $MBTT3PPN"DUPS
4UVEFOU"DUPS 4UVEFOU"DUPS 4UVEFOU"DUPS 5FBDIFS"DUPS $MBTT3PPN"DUPS ڥք͚ͮΒΕͨίϯςΩετ ͱݟͳͤΔ͔
શͯΞΫλʔ • ઌੜੜెΞΫλʔ • ΞΫλʔूͱΈͳͤΔ • ̍֊্͕ΔͱநͳͲ͕มΘΓɺ ϧʔτ͕มΘΔͱίϯςΩετ͕มΘΔͱߟ͑Δ͜ͱ͕Ͱ͖Δ
ঢ়ଶมԽ • ੜెͷঢ়ଶ͕มΘͬͨ ઌੜ͕ͲͷੜెͷςετΛ͏͚ͱͬͨ ͳͲ • ΞΫλʔͷঢ়ଶΛอ͢Δ͜ͱͰࣄ࣮Λ͢ • ࣄ࣮ͷੵΈॏͶ͕ϏϡʔΛ࡞Δ
func (u *Cart) Receive(context actor.Context) { defer context.Poison(context.Self()) switch msg
:= context.Message().(type) { case *persistence.RequestSnapshot: u.PersistSnapshot(u.state) case *persistence.ReplayComplete: // ϦϓϨΠ͕ྃͨ͠Β෦ঢ়ଶΛมߋ͢Δ context.Logger().Info( fmt.Sprintf("replay completed, internal state changed to '%v'", u.state)) case *command.AddItem: if u.IsStateExists(msg.Email) { context.Send(u.stream, &message.AddItemError{Message: "item already exists"}) return } // ུ u.persistence(context, ev) // xxxੜΠϕϯτΛΠϕϯτετϦʔϜ context.Send(u.stream, ev) case *event.ItemAdded: if msg.String() != "" { // event ͕ϦϓϨΠ͞Εͨ߹ঢ়ଶΛߋ৽͢Δ u.state = msg u.sendToReadModelUpdater(context, msg) } } } ίϚϯυΛडऔɺ ࣗΞΫλʔͷঢ়ଶΛมߋ ঢ়ଶมߋΛΠϕϯτͱͯ͠ӬଓԽ
func (u *Cart) Receive(context actor.Context) { defer context.Poison(context.Self()) switch msg
:= context.Message().(type) { case *persistence.RequestSnapshot: u.PersistSnapshot(u.state) case *persistence.ReplayComplete: // ϦϓϨΠ͕ྃͨ͠Β෦ঢ়ଶΛมߋ͢Δ context.Logger().Info( fmt.Sprintf("replay completed, internal state changed to '%v'", u.state)) case *command.AddItem: if u.IsStateExists(msg.Name) { context.Send(u.stream, &message.AddItemError{Message: "item already exists"}) return } // ུ u.persistence(context, ev) // xxxੜΠϕϯτΛΠϕϯτετϦʔϜ context.Send(u.stream, ev) case *event.ItemAdded: if msg.String() != "" { // event ͕ϦϓϨΠ͞Εͨ߹ঢ়ଶΛߋ৽͢Δ u.state = msg u.sendToReadModelUpdater(context, msg) } } } ϦʔυϞσϧߋ৽ϋϯυϥʢΞΫλʔʣ
func (u *Cart) Receive(context actor.Context) { defer context.Poison(context.Self()) switch msg
:= context.Message().(type) { case *persistence.RequestSnapshot: u.PersistSnapshot(u.state) case *persistence.ReplayComplete: // ϦϓϨΠ͕ྃͨ͠Β෦ঢ়ଶΛมߋ͢Δ context.Logger().Info( fmt.Sprintf("replay completed, internal state changed to '%v'", u.state)) case *command.AddItem: if u.IsStateExists(msg.Name) { context.Send(u.stream, &message.AddItemError{Message: "item already exists"}) return } // ུ u.persistence(context, ev) // xxxੜΠϕϯτΛΠϕϯτετϦʔϜ context.Send(u.stream, ev) case *event.ItemAdded: if msg.String() != "" { // event ͕ϦϓϨΠ͞Εͨ߹ঢ়ଶΛߋ৽͢Δ u.state = msg u.sendToReadModelUpdater(context, msg) } } } ΞΫλʔੜʢ࠶ੜɺϦελʔτͳͲʣ࣌ աڈͷঢ়ଶ͕͋Εɺ ࠷ॳͷΠϕϯτ͔Βड৴͠ɺঢ়ଶΛ෮ݩ
None
None
ಠཱͯ͠ಈ͍͍ͯΔ • ΫϥυΛར༻͢Δ͜ͱͰγεςϜࢄ • ࢄ͍ͯ͠ΔͷΛಉظతʹѻ͏ͷͰͳ͘ ඇಉظͰฒߦɺͯ͢ݸͱͯ͠ಈ࡞͍ͯ͠Δͱଊ͑Δͱʁ • ΞΫλʔϞσϧʹ͍ͭͯ࠶ߟͯ͠ΈΔͷ͍͔͕Ͱ͠ΐ͏͔ʁ
ಋೖͰ͖ΔπʔϧΩοτ • Akka / Pekko (Java, Scala) • Erlang OTP
• Proto Actor (Go, .NET) • ergo (Go) • Phluxor(PHP) ΄͔৭ʑ
ΞΫλʔϞσϧʹ͍ͭͯཧղ͢ΔͨΊʹ
ΑΓཧղ͢ΔͨΊʹ
None
͍͞͝ʹ • ϓϩάϥϛϯάύϥμΠϜ͕ͪΐͬͱҧ͏ͷ • ฉ͚ͩ͘Ͱͳ͔ͳ͔͍͠ͷͰɺͥͻ৮ͬͯΈ͍ͯͩ͘͞ • ཧղͰ͖ΔͱීஈͷϓϩάϥϛϯάɺϞσϦϯάʹ׆͔ͤΔʂ