Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Examples #627

Merged
merged 2 commits into from
Apr 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions _examples/actor-autorespond/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module autorespond

go 1.16

replace github.com/asynkron/protoactor-go => ../..

require (
github.com/asynkron/protoactor-go v0.0.0-00010101000000-000000000000
)
43 changes: 43 additions & 0 deletions _examples/actor-autorespond/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package main

import (
"fmt"
"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)
}
10 changes: 10 additions & 0 deletions _examples/actor-messagebatch/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module messagebatch

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
)
45 changes: 45 additions & 0 deletions _examples/actor-messagebatch/main.go
Original file line number Diff line number Diff line change
@@ -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()
}
5 changes: 5 additions & 0 deletions actor/root_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ func (rc *RootContext) RequestFuture(pid *PID, message interface{}, timeout time
Sender: future.PID(),
}
rc.sendUserMessage(pid, env)

return future
}

Expand All @@ -147,6 +148,7 @@ func (rc *RootContext) Spawn(props *Props) *PID {
if err != nil {
panic(err)
}

return pid
}

Expand All @@ -156,6 +158,7 @@ func (rc *RootContext) SpawnPrefix(props *Props, prefix string) *PID {
if err != nil {
panic(err)
}

return pid
}

Expand All @@ -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)
}

Expand Down