From 614bb60c83717b2208c05245c5d00f9b27113d43 Mon Sep 17 00:00:00 2001 From: Roger Johansson Date: Thu, 14 Apr 2022 11:07:32 +0200 Subject: [PATCH 1/2] more examples --- _examples/actor-autorespond/go.mod | 10 +++++++ _examples/actor-autorespond/main.go | 46 +++++++++++++++++++++++++++++ _examples/actor-messagebatch/go.mod | 3 ++ actor/root_context.go | 5 ++++ 4 files changed, 64 insertions(+) create mode 100644 _examples/actor-autorespond/go.mod create mode 100644 _examples/actor-autorespond/main.go create mode 100644 _examples/actor-messagebatch/go.mod diff --git a/_examples/actor-autorespond/go.mod b/_examples/actor-autorespond/go.mod new file mode 100644 index 000000000..a99d2d066 --- /dev/null +++ b/_examples/actor-autorespond/go.mod @@ -0,0 +1,10 @@ +module autorespond + +go 1.16 + +replace github.com/asynkron/protoactor-go => ../.. + +require ( + github.com/asynkron/goconsole v0.0.0-20160504192649-bfa12eebf716 + github.com/asynkron/protoactor-go v0.0.0-00010101000000-000000000000 +) diff --git a/_examples/actor-autorespond/main.go b/_examples/actor-autorespond/main.go new file mode 100644 index 000000000..b2a80641c --- /dev/null +++ b/_examples/actor-autorespond/main.go @@ -0,0 +1,46 @@ +package main + +import ( + "fmt" + console "github.com/asynkron/goconsole" + "github.com/asynkron/protoactor-go/actor" + "time" +) + +//Auto Response in Proto.Actor is a special kind of message that can create its own response message +//it is received just like any other message by the actor +//but the actor context sees the AutoResponse interface and calls GetAutoReplyMessage() to get the response message +//this is useful if you want to guarantee some form of Ack from an actor. without forcing the developer of the actor to +//use context.Respond manually + +//e.g. ClusterPubSub feature uses this to Ack back to the Topic actor to let it know the message has been received + +type myAutoResponder struct { + name string +} + +func (m myAutoResponder) GetAutoResponse(context actor.Context) interface{} { + + //return some response-message + //you have full access to the actor context + + return &myAutoResponse{ + name: m.name + " " + context.Self().Id, + } +} + +type myAutoResponse struct { + name string +} + +func main() { + system := actor.NewActorSystem() + props := actor.PropsFromFunc(func(ctx actor.Context) {}) + pid := system.Root.Spawn(props) + + res, _ := system.Root.RequestFuture(pid, &myAutoResponder{name: "hello"}, 10*time.Second).Result() + + fmt.Printf("%v", res) + + console.ReadLine() +} diff --git a/_examples/actor-messagebatch/go.mod b/_examples/actor-messagebatch/go.mod new file mode 100644 index 000000000..1848c4cf4 --- /dev/null +++ b/_examples/actor-messagebatch/go.mod @@ -0,0 +1,3 @@ +module messagebatch + +go 1.18 diff --git a/actor/root_context.go b/actor/root_context.go index 4a8acd137..f0c356afa 100644 --- a/actor/root_context.go +++ b/actor/root_context.go @@ -124,6 +124,7 @@ func (rc *RootContext) RequestFuture(pid *PID, message interface{}, timeout time Sender: future.PID(), } rc.sendUserMessage(pid, env) + return future } @@ -147,6 +148,7 @@ func (rc *RootContext) Spawn(props *Props) *PID { if err != nil { panic(err) } + return pid } @@ -156,6 +158,7 @@ func (rc *RootContext) SpawnPrefix(props *Props, prefix string) *PID { if err != nil { panic(err) } + return pid } @@ -169,9 +172,11 @@ func (rc *RootContext) SpawnNamed(props *Props, name string) (*PID, error) { if props.guardianStrategy != nil { rootContext = rc.Copy().WithGuardian(props.guardianStrategy) } + if rootContext.spawnMiddleware != nil { return rc.spawnMiddleware(rc.actorSystem, name, props, rootContext) } + return props.spawn(rc.actorSystem, name, rootContext) } From 2e1c21d435e3fefa0d8b6f0dbfd1102137d28fb1 Mon Sep 17 00:00:00 2001 From: Roger Johansson Date: Thu, 14 Apr 2022 11:20:16 +0200 Subject: [PATCH 2/2] more examples --- _examples/actor-autorespond/go.mod | 1 - _examples/actor-autorespond/main.go | 3 -- _examples/actor-messagebatch/go.mod | 9 +++++- _examples/actor-messagebatch/main.go | 45 ++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 _examples/actor-messagebatch/main.go diff --git a/_examples/actor-autorespond/go.mod b/_examples/actor-autorespond/go.mod index a99d2d066..c2c76ea22 100644 --- a/_examples/actor-autorespond/go.mod +++ b/_examples/actor-autorespond/go.mod @@ -5,6 +5,5 @@ go 1.16 replace github.com/asynkron/protoactor-go => ../.. require ( - github.com/asynkron/goconsole v0.0.0-20160504192649-bfa12eebf716 github.com/asynkron/protoactor-go v0.0.0-00010101000000-000000000000 ) diff --git a/_examples/actor-autorespond/main.go b/_examples/actor-autorespond/main.go index b2a80641c..9f1aa6429 100644 --- a/_examples/actor-autorespond/main.go +++ b/_examples/actor-autorespond/main.go @@ -2,7 +2,6 @@ package main import ( "fmt" - console "github.com/asynkron/goconsole" "github.com/asynkron/protoactor-go/actor" "time" ) @@ -41,6 +40,4 @@ func main() { res, _ := system.Root.RequestFuture(pid, &myAutoResponder{name: "hello"}, 10*time.Second).Result() fmt.Printf("%v", res) - - console.ReadLine() } diff --git a/_examples/actor-messagebatch/go.mod b/_examples/actor-messagebatch/go.mod index 1848c4cf4..aaad01788 100644 --- a/_examples/actor-messagebatch/go.mod +++ b/_examples/actor-messagebatch/go.mod @@ -1,3 +1,10 @@ module messagebatch -go 1.18 +go 1.16 + +replace github.com/asynkron/protoactor-go => ../.. + +require ( + github.com/asynkron/goconsole v0.0.0-20160504192649-bfa12eebf716 + github.com/asynkron/protoactor-go v0.0.0-00010101000000-000000000000 +) diff --git a/_examples/actor-messagebatch/main.go b/_examples/actor-messagebatch/main.go new file mode 100644 index 000000000..c44be2319 --- /dev/null +++ b/_examples/actor-messagebatch/main.go @@ -0,0 +1,45 @@ +package main + +import ( + "fmt" + console "github.com/asynkron/goconsole" + "github.com/asynkron/protoactor-go/actor" + "strconv" +) + +// MessageBatch is a message that is sent to the actor and unpacks its payload in the mailbox +// This allows you to group messages together and send them as a single message +// while processing them as individual messages +// this is used by the Cluster PubSub feature to send a batch of messages and then Ack to the entire batch +// In that specific case, both MessageBatch and AutoRespond are required + +type myMessageBatch struct { + messages []interface{} +} + +func (m myMessageBatch) GetMessages() []interface{} { + return m.messages +} + +func main() { + system := actor.NewActorSystem() + props := actor.PropsFromFunc(func(ctx actor.Context) { + if m, ok := ctx.Message().(string); ok { + fmt.Println(m) + } + }) + pid := system.Root.Spawn(props) + + messages := make([]interface{}, 0) + + for i := 0; i < 100; i++ { + messages = append(messages, "Hello"+strconv.Itoa(i)) + } + + batch := &myMessageBatch{ + messages: messages, + } + system.Root.Send(pid, batch) + + console.ReadLine() +}