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
3k
PHP ステートレス VS ステートフル 状態管理と並行性 / php-stateless-stateful
ytake
0
340
PHPでアクターモデルを理解・体験しよう / Understand and experience the actor model in PHP
ytake
2
970
GoとアクターモデルでES+CQRSを実践! / proto_actor_es_cqrs
ytake
1
670
Phluxorでアクターモデルを 理解・体験しよう / toolkit-for-flexible-actor-models-in-php-phluxor
ytake
1
390
オブジェクトのおしゃべり大失敗 メッセージングアンチパターン集 / messaging anti-pattern collection
ytake
2
1.4k
DRE/SREのプラクティス融合によるクラウドネイティブなデータ基盤作り / dre_sre
ytake
0
1.1k
技術的負債と向き合う取り組みでよかったもの / positive_efforts_to_tackle_technical_debt
ytake
10
4.1k
Other Decks in Technology
See All in Technology
Goでデータパイプラインを作ろう
sansantech
PRO
1
360
JavaScript 研修 (2026)
recruitengineers
PRO
2
480
【CEDEC2026】専門性の高いデフォルメチームが挑んだ人材育成戦略 〜Cygames Academiaの企画から実施まで〜
cygames
PRO
0
540
モバイルアプリ開発概論2026
recruitengineers
PRO
5
520
強化学習「理論」入門
enakai00
3
3.6k
第3回しろおびセキュリティスポンサーセッション
log0417
0
160
Breaking the Seal: Static Deobfuscation of Compiled V8 JavaScript Bytecode Malware
hshrzd
0
680
20分でわかるセキュアAPI
nwiizo
2
210
ガバメント AI 源内を地方自治体は活用できるのか可能性と課題、期待について
takeda_h
1
380
Forza Horizon 6 のテレメトリ機能で 自動運転に使えそうな学習データを集める話
henjin0
0
150
【CEDEC2026】コードレビュー支援ツール開発から学ぶ:LLMを用いた業務システムの実践的な運用設計と誤出力対策
cygames
PRO
0
630
FPGAが実現する遠方宇宙の高空間分解能天体撮影 -大型地上望遠鏡の視力を補正する「補償光学」とは?-
komei_mt
0
200
Featured
See All Featured
Designing for Performance
lara
611
70k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
270
Facilitating Awesome Meetings
lara
57
7.1k
Optimising Largest Contentful Paint
csswizardry
37
3.9k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
440
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
630
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.4k
Evolving SEO for Evolving Search Engines
ryanjones
0
250
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.1k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.3k
Agile that works and the tools we love
rasmusluckow
331
22k
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
͍͞͝ʹ • ϓϩάϥϛϯάύϥμΠϜ͕ͪΐͬͱҧ͏ͷ • ฉ͚ͩ͘Ͱͳ͔ͳ͔͍͠ͷͰɺͥͻ৮ͬͯΈ͍ͯͩ͘͞ • ཧղͰ͖ΔͱීஈͷϓϩάϥϛϯάɺϞσϦϯάʹ׆͔ͤΔʂ