Upgrade to Pro — share decks privately, control downloads, hide ads and more …

再考 アクターモデル/ reconsider actor model

yuuki takezawa
September 17, 2024

再考 アクターモデル/ reconsider actor model

吉祥寺.pm36でのトークです

yuuki takezawa

September 17, 2024
Tweet

More Decks by yuuki takezawa

Other Decks in Technology

Transcript

  1. Pro fi le • ஛ᖒ ༗و a.k.a ytake • ઍגࣜձࣾ

    CTO / ΄͔ٕज़ސ໰ʢωοτϓϩςΫγϣϯζͳͲʣ • Go / Scala / Kotlin • ΞΫλʔϞσϧେ޷͖
  2. 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{} }
  3. 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{} } ਌ΞΫλʔ
  4. 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{} } ࢠΞΫλʔ
  5. 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{} } ࢠΞΫλʔੜ੒ ࣗಈతʹ֊૚ߏ଄Λ࣋ͭ
  6. 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{} } ࢠΞΫλʔͷΞυϨε
  7. 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{} } ࢠΞΫλʔ͕ࣗ෼ѼͯͷϝοηʔδΛ ड͚औΔ ʢࣗಈͰৼΓ෼͚ΒΕ·͢ʣ
  8. 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{} } ࢠΞΫλʔ͕ࣗ෼ࣗ਎Λఀࢭͨ͠ྫ
  9. 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{} } ਌ΞΫλʔ΁ఀࢭ͕௨஌͞ΕΔ
  10. 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)))
  11. 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))) ࢠΞΫλʔ͕ࣦഊͨ͠৔߹ɺ ಉ֊૚ʹ͍ΔࢠΞΫλʔͷ͏ͪɺ ର৅ͷ΋ͷ͚ͩఀࢭͤ͞Δྫ
  12. 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) } } } ίϚϯυΛडऔɺ ࣗΞΫλʔͷঢ়ଶΛมߋ ঢ়ଶมߋΛΠϕϯτͱͯ͠ӬଓԽ
  13. 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) } } } ϦʔυϞσϧߋ৽ϋϯυϥʢΞΫλʔʣ΁
  14. 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) } } } ΞΫλʔੜ੒ʢ࠶ੜ੒ɺϦελʔτͳͲʣ࣌ աڈͷঢ়ଶ͕͋Ε͹ɺ ࠷ॳͷΠϕϯτ͔Βड৴͠ɺঢ়ଶΛ෮ݩ
  15. ಋೖͰ͖ΔπʔϧΩοτ • Akka / Pekko (Java, Scala) • Erlang OTP

    • Proto Actor (Go, .NET) • ergo (Go) • Phluxor(PHP) ΄͔৭ʑ