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
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.2k
PHPでアクターモデルを活用したSagaパターンの実践法 / php-saga-pattern-with-actor-model
ytake
0
3.1k
PHP ステートレス VS ステートフル 状態管理と並行性 / php-stateless-stateful
ytake
0
390
PHPでアクターモデルを理解・体験しよう / Understand and experience the actor model in PHP
ytake
2
1k
GoとアクターモデルでES+CQRSを実践! / proto_actor_es_cqrs
ytake
1
740
Phluxorでアクターモデルを 理解・体験しよう / toolkit-for-flexible-actor-models-in-php-phluxor
ytake
1
400
オブジェクトのおしゃべり大失敗 メッセージングアンチパターン集 / 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
大型犬好きによるPugの紹介
yamanoku
1
160
DGX Spark でどこまでハッキングができるのか?
kash1064
3
1.3k
実体験から学ぶ分析エージェントの開発と運⽤
recruitengineers
PRO
8
2.4k
UniFi(ユニファイ)AIカメラの現場活用
ludicmind
1
430
実践! SRE × AI - ABEMA における AIOps -
tetsuya28
8
3.1k
Rustuna: Rustによる高速なOptuna実装
pfn
PRO
0
190
分析AIエージェントを育てる、動く環境を育てる
codatum
1
1.1k
Code for Security プロジェクト紹介 2026年10月
yu23ki14
0
110
QA4AI 2026-Oct 生成AI時代の品質保証
tokuty
1
850
DevelopersIO 2026 知識の地図を描く ─ オントロジーとは何か?
ishikawa_satoru
1
1.6k
今さら理解するウェブフォントver.2026
takanorip
3
750
会社説明資料
persolserverworks
0
9.8k
Featured
See All Featured
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
1
570
Embracing the Ebb and Flow
colly
88
5.2k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.6k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
6
1.2k
Automating Front-end Workflow
addyosmani
1369
210k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
YesSQL, Process and Tooling at Scale
rocio
174
15k
Writing Fast Ruby
sferik
630
63k
Exploring anti-patterns in Rails
aemeredith
4
540
RailsConf 2023
tenderlove
30
1.6k
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.6k
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
850
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
͍͞͝ʹ • ϓϩάϥϛϯάύϥμΠϜ͕ͪΐͬͱҧ͏ͷ • ฉ͚ͩ͘Ͱͳ͔ͳ͔͍͠ͷͰɺͥͻ৮ͬͯΈ͍ͯͩ͘͞ • ཧղͰ͖ΔͱීஈͷϓϩάϥϛϯάɺϞσϦϯάʹ׆͔ͤΔʂ