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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
MIRU 2026 チュートリアル
keisuke198619
0
870
クラウドセキュリティ入門 ~安全なクラウド利用のための基礎知識~
lhazy
12
8.5k
DatadogのBits Chatが開発組織にもたらしたもの / What Bits Chat Has Brought Us
sms_tech
1
150
Master Dataグループ紹介資料
sansan33
PRO
1
4.8k
Flutterをカメラで動かしたかった話
sony
1
130
Agent 時代の Kaggle 展望 / kaggle-in-the-agentic-era
upura
1
680
事業価値と Engineering 2026年度版
recruitengineers
PRO
45
22k
モダンフロントエンド 開発研修
recruitengineers
PRO
4
580
Goでデータパイプラインを作ろう
sansantech
PRO
1
360
AIは実装を速くする。では、私たちは何を今作るべきか?-立場を越えてリリースに向き合ったチーム開発の実践 / 20260801 Hiromi Nakaya and Naoki Takahashi
shift_evolve
PRO
3
460
20分でわかるセキュアAPI
nwiizo
2
220
【CEDEC2026】『GRANBLUE FANTASY: Relink - Endless Ragnarok』のバトル制作事例 ~最高のキャラゲーを目指して~
cygames
PRO
0
230
Featured
See All Featured
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
790
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
270
New Earth Scene 8
popppiees
3
2.5k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
270
RailsConf 2023
tenderlove
30
1.5k
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
230
Paper Plane (Part 1)
katiecoart
PRO
1
10k
Done Done
chrislema
186
16k
Ruling the World: When Life Gets Gamed
codingconduct
0
290
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.3k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
200
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
520
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
͍͞͝ʹ • ϓϩάϥϛϯάύϥμΠϜ͕ͪΐͬͱҧ͏ͷ • ฉ͚ͩ͘Ͱͳ͔ͳ͔͍͠ͷͰɺͥͻ৮ͬͯΈ͍ͯͩ͘͞ • ཧղͰ͖ΔͱීஈͷϓϩάϥϛϯάɺϞσϦϯάʹ׆͔ͤΔʂ