Slide 1

Slide 1 text

࠶ߟ ΞΫλʔϞσϧ ٢঵ࣉ.pm36 yuuki takezawa / ytake

Slide 2

Slide 2 text

Pro fi le • ஛ᖒ ༗و a.k.a ytake • ઍגࣜձࣾ CTO / ΄͔ٕज़ސ໰ʢωοτϓϩςΫγϣϯζͳͲʣ • Go / Scala / Kotlin • ΞΫλʔϞσϧେ޷͖

Slide 3

Slide 3 text

ΞΫλʔϞσϧͬͯʁ • 1973೥ʹൃද͞Εͨฒߦܭࢉͷ਺ֶతϞσϧͷҰछ • ৽͍͠΋ͷͰ͸͋Γ·ͤΜ • Erlang΍ScalaͳͲͰ͓ͳ͡Έ • ϝϞϦڞ༗ΛߦΘͣɺϊϯϒϩοΩϯάͰ ಠཱͨ͠ΞΫλʔ͕ঢ়ଶΛ࣋ͭ

Slide 4

Slide 4 text

ΞΫλʔͷ੹຿ • ΞΫλʔͷϝοηʔδΛૹ৴͢Δ • ΞΫλʔΛੜ੒͢Δ • ϝοηʔδʹద༻͢Δಈ࡞Λߦ͏

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

ΞΫλʔϞσϧͬͯʁ • ΞΫλʔ͸ಠཱͯ͠ಈ࡞͠ɺͦΕͧΕ͕ϥΠϑαΠΫϧΛ࣋ͭ • ϝϞϦͷڞ༗ͳͲ͸Ұ੾ߦΘͳ͍ • ΞΫλʔΛ௚઀ૢ࡞͢Δ͜ͱ͸ෆՄೳͰΠϛϡʔλϒϧ • ϝοηʔδͷΈͰ΍ΓऔΓΛߦ͏ • Ґஔಁաੑ

Slide 7

Slide 7 text

ग़య https://petabridge.com/blog/akkadotnet-what-is-an-actor/

Slide 8

Slide 8 text

Ґஔಁաੑ • ΞΫλʔ͸ϩʔΧϧ΍ϦϞʔτɺΫϥελͰಈ࡞Ͱ͖Δ • Ͳ͜ʹ͋Δͷ͔ɺͲͷΑ͏ʹͯ͠ݺͼग़͢ͷ͔͸ ίʔυ্Ͱ۠ผ͢Δ͜ͱ͕ͳ͘ͳΔ • ڥք͚ͮΒΕͨίϯςΩετΛجʹ෼ׂ͢Δ͜ͱ΍ɺ εϧʔϓοτ޲্ͷͨΊ෼ׂ͢Δ͜ͱ͕༰қ

Slide 9

Slide 9 text

ग़య https://pekko.apache.org/docs/pekko/current/general/addressing.html

Slide 10

Slide 10 text

ग़య https://pekko.apache.org/docs/pekko/current/general/addressing.html

Slide 11

Slide 11 text

֊૚ߏ଄Λ΋ͭ

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

ϑΥʔϧττϨϥϯε • ώΤϥϧΩʔΛ࣋ͭͱ͍͏͜ͱ͸ ਌ΞΫλʔ͕ࢠΞΫλʔΛ؂ಜɾ؅ཧ͢Δ੹຿Λ࣋ͭ ࢓ࣄʹࣦഊͨ͠৔߹ʹͲͷΑ͏ͳઓུΛʁʢεʔύʔόΠβઓུʣ • ਌ࢠؔ܎ʹͳ͍ΞΫλʔ΋؂ࢹ͢Δ͜ͱ͕Ͱ͖Δ • ࣦഊ࣌ʹͲͷΑ͏ʹ෮چͤ͞Δ͔ΛࢦࣔͰ͖Δ

Slide 15

Slide 15 text

؂ࢹྫ

Slide 16

Slide 16 text

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{} }

Slide 17

Slide 17 text

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{} } ਌ΞΫλʔ

Slide 18

Slide 18 text

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{} } ࢠΞΫλʔ

Slide 19

Slide 19 text

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{} } ࢠΞΫλʔੜ੒ ࣗಈతʹ֊૚ߏ଄Λ࣋ͭ

Slide 20

Slide 20 text

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{} } ࢠΞΫλʔͷΞυϨε

Slide 21

Slide 21 text

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{} } ࢠΞΫλʔ͕ࣗ෼ѼͯͷϝοηʔδΛ ड͚औΔ ʢࣗಈͰৼΓ෼͚ΒΕ·͢ʣ

Slide 22

Slide 22 text

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{} } ࢠΞΫλʔ͕ࣗ෼ࣗ਎Λఀࢭͨ͠ྫ

Slide 23

Slide 23 text

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{} } ਌ΞΫλʔ΁ఀࢭ͕௨஌͞ΕΔ

Slide 24

Slide 24 text

ઓུ

Slide 25

Slide 25 text

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)))

Slide 26

Slide 26 text

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))) ࢠΞΫλʔ͕ࣦഊͨ͠৔߹ɺ ಉ֊૚ʹ͍ΔࢠΞΫλʔͷ͏ͪɺ ର৅ͷ΋ͷ͚ͩఀࢭͤ͞Δྫ

Slide 27

Slide 27 text

ଞɺঢ়ଶมԽ΍ϧʔςΟϯάͳͲ

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

ैདྷͷ࢓૊ΈʹͲ͏׆͔ͤΒΕΔ͔ʁ

Slide 30

Slide 30 text

ΞΫλʔͱ఻౷తͳߏ଄ • ΞΫλʔϞσϧͱैདྷͷΞϓϦέʔγϣϯߏ଄͸ڞଘՄೳ • ઓज़ύλʔϯͳͲͰ͸ ΞΫλʔ͕ΤϯςΟςΟʹͳΓঢ়ଶΛ΋ͭ • ΞΫλʔͷঢ়ଶมԽʢΠϕϯτʣΛอଘ͢Δ͜ͱͰ ϏϡʔΛ૊ΈཱͯΔ͜ͱ͕Ͱ͖ΔʢRead Model Updateʣ

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

ֶߍͷςετྫ • ઌੜ͕ੜెʹରͯ͠ ͞Μ͢͏ͷςετΛ࣮ࢪ • ੜె͸ͦΕͧΕݸͱͯ͠໰୊Λղ͘ • ઌੜ͸ςετதʹݟकΔͳͲͷߦಈ • શͯ౴͑ͨΒςετ༻ࢴΛఏग़͢Δ

Slide 33

Slide 33 text

4UVEFOU"DUPS 4UVEFOU"DUPS 4UVEFOU"DUPS 4UVEFOU"DUPS 4UVEFOU"DUPS

Slide 34

Slide 34 text

4UVEFOU"DUPS 4UVEFOU"DUPS 4UVEFOU"DUPS 4UVEFOU"DUPS 4UVEFOU"DUPS 5FBDIFS"DUPS

Slide 35

Slide 35 text

4UVEFOU"DUPS 4UVEFOU"DUPS 4UVEFOU"DUPS 5FBDIFS"DUPS $MBTT3PPN"DUPS

Slide 36

Slide 36 text

4UVEFOU"DUPS 4UVEFOU"DUPS 4UVEFOU"DUPS 5FBDIFS"DUPS $MBTT3PPN"DUPS ڥք͚ͮΒΕͨίϯςΩετ ͱݟͳͤΔ͔΋

Slide 37

Slide 37 text

શͯ͸ΞΫλʔ • ઌੜ΍ੜె΋ΞΫλʔ • ਌ΞΫλʔ͸ू໿ͱΈͳͤΔ • ̍֊૚্͕Δͱந৅౓ͳͲ͕มΘΓɺ ϧʔτ͕มΘΔͱίϯςΩετ͕มΘΔͱߟ͑Δ͜ͱ͕Ͱ͖Δ

Slide 38

Slide 38 text

ঢ়ଶมԽ • ੜెͷঢ়ଶ͕มΘͬͨ ઌੜ͕ͲͷੜెͷςετΛ͏͚ͱͬͨ ͳͲ • ΞΫλʔͷঢ়ଶΛอ؅͢Δ͜ͱͰࣄ࣮Λ࢒͢ • ࣄ࣮ͷੵΈॏͶ͕ϏϡʔΛ࡞Δ

Slide 39

Slide 39 text

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) } } } ίϚϯυΛडऔɺ ࣗΞΫλʔͷঢ়ଶΛมߋ ঢ়ଶมߋΛΠϕϯτͱͯ͠ӬଓԽ

Slide 40

Slide 40 text

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) } } } ϦʔυϞσϧߋ৽ϋϯυϥʢΞΫλʔʣ΁

Slide 41

Slide 41 text

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) } } } ΞΫλʔੜ੒ʢ࠶ੜ੒ɺϦελʔτͳͲʣ࣌ աڈͷঢ়ଶ͕͋Ε͹ɺ ࠷ॳͷΠϕϯτ͔Βड৴͠ɺঢ়ଶΛ෮ݩ

Slide 42

Slide 42 text

No content

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

ಠཱͯ͠ಈ͍͍ͯΔ • Ϋϥ΢υΛར༻͢Δ͜ͱͰγεςϜ͸෼ࢄ • ෼ࢄ͍ͯ͠Δ΋ͷΛಉظతʹѻ͏ͷͰ͸ͳ͘ ඇಉظͰฒߦɺ͢΂ͯݸͱͯ͠ಈ࡞͍ͯ͠Δͱଊ͑Δͱʁ • ΞΫλʔϞσϧʹ͍ͭͯ࠶ߟͯ͠ΈΔͷ͸͍͔͕Ͱ͠ΐ͏͔ʁ

Slide 45

Slide 45 text

ಋೖͰ͖ΔπʔϧΩοτ • Akka / Pekko (Java, Scala) • Erlang OTP • Proto Actor (Go, .NET) • ergo (Go) • Phluxor(PHP) ΄͔৭ʑ

Slide 46

Slide 46 text

ΞΫλʔϞσϧʹ͍ͭͯཧղ͢ΔͨΊʹ

Slide 47

Slide 47 text

ΑΓཧղ͢ΔͨΊʹ

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

͍͞͝ʹ • ϓϩάϥϛϯάύϥμΠϜ͕ͪΐͬͱҧ͏΋ͷ • ฉ͚ͩ͘Ͱ͸ͳ͔ͳ͔೉͍͠ͷͰɺͥͻ৮ͬͯΈ͍ͯͩ͘͞ • ཧղͰ͖ΔͱීஈͷϓϩάϥϛϯάɺϞσϦϯάʹ΋׆͔ͤΔʂ