Closed
Description
Bug description
The PostStop
function is being executed an indeterminate number of times.
How to reproduce it?
Run the following code a few times:
Reproduction Code (click to expand)
package main
import (
"context"
"fmt"
"os"
"github.com/tochemey/goakt/v3/actor"
"github.com/tochemey/goakt/v3/goaktpb"
)
const numActors = 1
func main() {
ctx := context.Background()
actorSystem := startActorSystem(ctx)
for i := range numActors {
spawnActor(ctx, actorSystem, fmt.Sprintf("actor%d", i+1))
}
stopActorSystem(ctx, actorSystem)
}
func startActorSystem(ctx context.Context) actor.ActorSystem {
actorSystem, err := actor.NewActorSystem("test-system")
if err != nil {
fmt.Printf("Error creating actor system: %v\n", err)
os.Exit(1)
}
if err := actorSystem.Start(ctx); err != nil {
fmt.Printf("Error starting actor system: %v\n", err)
os.Exit(1)
}
return actorSystem
}
func stopActorSystem(ctx context.Context, actorSystem actor.ActorSystem) {
if err := actorSystem.Stop(ctx); err != nil {
fmt.Printf("Error stopping actor system: %v\n", err)
os.Exit(1)
}
}
func spawnActor(ctx context.Context, actorSystem actor.ActorSystem, actorName string) {
if _, err := actorSystem.Spawn(ctx, actorName, &MyActor{}); err != nil {
fmt.Printf("Error spawning actor %s: %v\n", actorName, err)
os.Exit(1)
}
}
type MyActor struct{}
func (x *MyActor) PreStart(ctx *actor.Context) error {
fmt.Printf("%s PreStart\n", ctx.ActorName())
return nil
}
func (x *MyActor) Receive(ctx *actor.ReceiveContext) {
switch ctx.Message().(type) {
case *goaktpb.PostStart:
fmt.Printf("%s PostStart\n", ctx.Self().Name())
default:
ctx.Unhandled()
}
}
func (x *MyActor) PostStop(ctx *actor.Context) error {
fmt.Printf("%s PostStop\n", ctx.ActorName())
return nil
}
With numActors = 1
, sometimes you will see actor1 PostStop
once, but sometimes you will see it twice.
With a larger number of actors, it's more evident. For example, with numActors = 5
, in one attempt I got:
actor1 PreStart
actor2 PreStart
actor1 PostStart
actor2 PostStart
actor3 PreStart
actor3 PostStart
actor4 PreStart
actor4 PostStart
actor5 PreStart
actor5 PostStart
actor1 PostStop
actor1 PostStop
actor5 PostStop
actor3 PostStop
actor4 PostStop
actor2 PostStop
actor4 PostStop
Adding some time.Sleep
delays did not seem to help, but I would hope I wouldn't need them anyway.
Expected behavior
I expect PostStop
to run once and only once for each actor.
Library Version:
- Go-Akt version: v3.6.3
- Go version: 1.24.4