diff --git a/README.md b/README.md index ca4ad0b..e6caac8 100644 --- a/README.md +++ b/README.md @@ -250,6 +250,7 @@ Any event that fulfills the `actor.LogEvent` interface will be logged to the def message and the attributes of the event set by the `actor.LogEvent` `log()` method. ### List of internal system events +* `actor.ActorInitializedEvent`, an actor has been initialized but did not processed its `actor.Started message` * `actor.ActorStartedEvent`, an actor has started * `actor.ActorStoppedEvent`, an actor has stopped * `actor.DeadLetterEvent`, a message was not delivered to an actor diff --git a/actor/engine_test.go b/actor/engine_test.go index 6eed2d0..8f0e327 100644 --- a/actor/engine_test.go +++ b/actor/engine_test.go @@ -36,6 +36,16 @@ func newTickReceiver(wg *sync.WaitGroup) Producer { } } +func TestRegistryGetPID(t *testing.T) { + e, _ := NewEngine(nil) + expectedPID1 := e.SpawnFunc(func(c *Context) {}, "foo", WithID("1")) + expectedPID2 := e.SpawnFunc(func(c *Context) {}, "foo", WithID("2")) + pid := e.Registry.GetPID("foo", "1") + assert.True(t, pid.Equals(expectedPID1)) + pid = e.Registry.GetPID("foo", "2") + assert.True(t, pid.Equals(expectedPID2)) +} + func TestSendToNilPID(t *testing.T) { e, _ := NewEngine(nil) e.Send(nil, "foo") diff --git a/actor/event.go b/actor/event.go index 209ff56..3162790 100644 --- a/actor/event.go +++ b/actor/event.go @@ -26,6 +26,17 @@ func (e ActorStartedEvent) Log() (slog.Level, string, []any) { return slog.LevelInfo, "Actor started", []any{"pid", e.PID} } +// ActorInitializedEvent is broadcasted over the eventStream before an actor +// received and processed its started event. +type ActorInitializedEvent struct { + PID *PID + Timestamp time.Time +} + +func (e ActorInitializedEvent) Log() (slog.Level, string, []any) { + return slog.LevelDebug, "Actor initialized", []any{"pid", e.PID} +} + // ActorStoppedEvent is broadcasted over the eventStream each time // a process is terminated. type ActorStoppedEvent struct { diff --git a/actor/process.go b/actor/process.go index 94f5730..de08d6a 100644 --- a/actor/process.go +++ b/actor/process.go @@ -126,6 +126,7 @@ func (p *process) Start() { }() p.context.message = Initialized{} applyMiddleware(recv.Receive, p.Opts.Middleware...)(p.context) + p.context.engine.BroadcastEvent(ActorInitializedEvent{PID: p.pid, Timestamp: time.Now()}) p.context.message = Started{} applyMiddleware(recv.Receive, p.Opts.Middleware...)(p.context) diff --git a/actor/registry.go b/actor/registry.go index b9d8e04..0bf5869 100644 --- a/actor/registry.go +++ b/actor/registry.go @@ -19,6 +19,16 @@ func newRegistry(e *Engine) *Registry { } } +// GetPID returns the process id associated for the given kind and its id. +// GetPID returns nil if the process was not found. +func (r *Registry) GetPID(kind, id string) *PID { + proc := r.getByID(kind + pidSeparator + id) + if proc != nil { + return proc.PID() + } + return nil +} + // Remove removes the given PID from the registry. func (r *Registry) Remove(pid *PID) { r.mu.Lock()