Skip to content

Instantly share code, notes, and snippets.

@oklahomer
Created November 24, 2018 04:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save oklahomer/d6fb6337d5aa5915e9457c77fbe1b0a9 to your computer and use it in GitHub Desktop.
Save oklahomer/d6fb6337d5aa5915e9457c77fbe1b0a9 to your computer and use it in GitHub Desktop.
package main
import (
"github.com/AsynkronIT/protoactor-go/actor"
"log"
"os"
"os/signal"
"syscall"
"time"
)
func newInboundMiddleware() actor.InboundMiddleware {
cnt := 0
return func(next actor.ActorFunc) actor.ActorFunc {
return func(ctx actor.Context) {
cnt++
log.Printf("Start handling incoming message #%d: %#v", cnt, ctx.Message())
next(ctx)
log.Printf("End handling incoming message #%d: %#v", cnt, ctx.Message())
}
}
}
func newOutboundMiddleware() actor.OutboundMiddleware {
cnt := 0
return func(next actor.SenderFunc) actor.SenderFunc {
return func(ctx actor.Context, target *actor.PID, envelope *actor.MessageEnvelope) {
cnt++
log.Printf("Start sending message #%d to %s", cnt, target.Id)
next(ctx, target, envelope)
log.Printf("End sending message #%d to %s", cnt, target.Id)
}
}
}
type ping struct{}
type pong struct{}
func main() {
pongProps := actor.
FromFunc(func(ctx actor.Context) {
switch ctx.Message().(type) {
case *ping:
ctx.Respond(&pong{})
}
})
pongPid, _ := actor.SpawnNamed(pongProps, "pong")
// Output should be somewhat like below.
// Because ping actor receives both signal of struct{}{} and a pong message of &pong{},
// the printed number of execution is doubled comparing to that of pong actor.
//
// 2018/11/24 12:59:25 Start handling incoming message #1: &actor.Started{}
// 2018/11/24 12:59:25 End handling incoming message #1: &actor.Started{}
// 2018/11/24 12:59:26 Start handling incoming message #2: struct {}{}
// 2018/11/24 12:59:26 Received signal
// 2018/11/24 12:59:26 Start sending message #1 to pong
// 2018/11/24 12:59:26 End sending message #1 to pong
// 2018/11/24 12:59:26 End handling incoming message #2: struct {}{}
// 2018/11/24 12:59:26 Start handling incoming message #3: &main.pong{}
// 2018/11/24 12:59:26 Received pong
// 2018/11/24 12:59:26 End handling incoming message #3: &main.pong{}
// 2018/11/24 12:59:27 Start handling incoming message #4: struct {}{}
// 2018/11/24 12:59:27 Received signal
// 2018/11/24 12:59:27 Start sending message #2 to pong
// 2018/11/24 12:59:27 End sending message #2 to pong
// 2018/11/24 12:59:27 End handling incoming message #4: struct {}{}
// 2018/11/24 12:59:27 Start handling incoming message #5: &main.pong{}
// 2018/11/24 12:59:27 Received pong
// 2018/11/24 12:59:27 End handling incoming message #5: &main.pong{}
// 2018/11/24 12:59:28 Start handling incoming message #6: struct {}{}
// 2018/11/24 12:59:28 Received signal
// 2018/11/24 12:59:28 Start sending message #3 to pong
// 2018/11/24 12:59:28 End sending message #3 to pong
// 2018/11/24 12:59:28 End handling incoming message #6: struct {}{}
// 2018/11/24 12:59:28 Start handling incoming message #7: &main.pong{}
// 2018/11/24 12:59:28 Received pong
// 2018/11/24 12:59:28 End handling incoming message #7: &main.pong{}
// ^C2018/11/24 12:59:29 Finish
pingProps := actor.
FromFunc(func(ctx actor.Context) {
switch ctx.Message().(type) {
case struct{}:
log.Print("Received signal")
ctx.Request(pongPid, &ping{})
case *pong:
log.Print("Received pong")
}
}).
WithMiddleware(newInboundMiddleware()).
WithOutboundMiddleware(newOutboundMiddleware())
pingPid, _ := actor.SpawnNamed(pingProps, "ping")
finish := make(chan os.Signal, 1)
signal.Notify(finish, os.Interrupt)
signal.Notify(finish, syscall.SIGTERM)
ticker := time.NewTicker(1 * time.Second)
defer ticker.Stop()
for {
select {
case <-ticker.C:
pingPid.Tell(struct{}{})
case <-finish:
pingPid.Stop()
pongPid.Stop()
log.Print("Finish")
return
}
}
}
@rocc0
Copy link

rocc0 commented Aug 7, 2019

Hi, this example doesn't work with current version of protoactor, I corrected it a little bit in my fork https://gist.github.com/rocc0/49e8623ff83859cf5028f6ecd5fbfe73

@oklahomer
Copy link
Author

Thanks for the fix, @rocc0.
As described in the very first article of my blog entries, it used the latest version possible at the moment: asynkron/protoactor-go@3992780.
Lately, I've added go.mod/go.sum for example repositories for version management.
I'll do something to these gist code fragments and blog entries to keep updated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment