Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
再考 アクターモデル/ reconsider actor model
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
yuuki takezawa
September 17, 2024
Technology
1.7k
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.3k
PHPでアクターモデルを活用したSagaパターンの実践法 / php-saga-pattern-with-actor-model
ytake
0
3.2k
PHP ステートレス VS ステートフル 状態管理と並行性 / php-stateless-stateful
ytake
0
410
PHPでアクターモデルを理解・体験しよう / Understand and experience the actor model in PHP
ytake
2
1k
GoとアクターモデルでES+CQRSを実践! / proto_actor_es_cqrs
ytake
1
750
Phluxorでアクターモデルを 理解・体験しよう / toolkit-for-flexible-actor-models-in-php-phluxor
ytake
1
410
オブジェクトのおしゃべり大失敗 メッセージングアンチパターン集 / 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
新卒エンジニア、 介護士になる
ryu1013
1
690
[General] 개발자로 해외 기업에서 일하기
skydoves
1
300
コードレビューをなくして見えたもの
henteko
0
140
セキュリティ専任チームなしで攻撃を先回りするSREが実践したSIEM on Amazon OpenSearch Service
cscengineer
PRO
0
450
DBTS2026 盛り上がってますか!?Databricksが実現するAI時代のデータ基盤
akuwano
1
190
分析作業をどこまで任せるか自分で決められる AIネイティブBI『Golden Analytics』が 良さげな話 /golden-analytics-is-ai-native-bi
shinyaa31
0
120
自律的なチームを作るためにTechPMがやらないこと
ny7760
1
520
Deep Data Security 機能解説
oracle4engineer
PRO
3
1k
TSKaigi Sendai 2026 - tsgo時代のTypeScript Playgroundはどう動くか
teamlab
PRO
0
110
あなたのDartコードは丸見えかもしれない ~reFlutterで暴くFlutterアプリの中身と多層防御~
zozotech
PRO
0
780
「いつか使う」の「いつか」は来ない 〜AI駆動開発における「作らない」判断について〜
ikki0006
0
150
IoTとは〜? 数字で見るSORACOM UG【SORACOM UG Explorer 2026】
soracom
PRO
0
200
Featured
See All Featured
Believing is Seeing
oripsolob
1
270
Fireside Chat
paigeccino
43
4.1k
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.7k
The #1 spot is gone: here's how to win anyway
tamaranovitovic
4
1.2k
Practical Orchestrator
shlominoach
192
12k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
22k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
630
30 Presentation Tips
portentint
PRO
1
460
Everyday Curiosity
cassininazir
0
390
Evolving SEO for Evolving Search Engines
ryanjones
0
360
Building an army of robots
kneath
307
47k
Build your cross-platform service in a week with App Engine
jlugia
234
19k
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
͍͞͝ʹ • ϓϩάϥϛϯάύϥμΠϜ͕ͪΐͬͱҧ͏ͷ • ฉ͚ͩ͘Ͱͳ͔ͳ͔͍͠ͷͰɺͥͻ৮ͬͯΈ͍ͯͩ͘͞ • ཧղͰ͖ΔͱීஈͷϓϩάϥϛϯάɺϞσϦϯάʹ׆͔ͤΔʂ