Watch and Unwatch
Watch and Unwatch provide a mechanism for actors to monitor the lifecycle of other actors and receive notifications when they terminate. This is essential for building fault-tolerant, reactive systems that can respond to actor failures or shutdowns.
Watch is a mechanism that allows one actor (the watcher) to subscribe to termination notifications for another actor (the watched). When the watched actor terminatesβeither gracefully or due to a failureβthe watcher receives a Terminated message.
Key characteristics:
Non-intrusive: The watched actor is unaware it's being watched
Asynchronous: Notification arrives as a regular message
Idempotent: Watching the same actor multiple times has no adverse effect
Automatic cleanup: Watch relationships are removed when either actor terminates
Local only: Only local actors can be watched (not remote actors)
Importance
Use watch when you need to:
Monitor dependencies: Detect when a service or dependency actor fails
Coordinate lifecycle: Perform cleanup when related actors terminate
Build resilient patterns: Implement circuit breakers, health checks
Resource management: Release resources when actors shutdown
Dynamic supervision: Implement custom supervision logic beyond the built-in supervisor
State synchronization: React to actor termination in distributed systems
Connection management: Detect disconnections and reconnect
Watching
An actor can watch another actor while handling messages in the Receive method using the ctx.Watch or when having using its PID.Watch method.
An actor can watch multiple actors; each termination sends one Terminated. Watch is local only (no remote actors).
Un-watching
To un-watch an actor can use the ctx.Unwatch or PID.Unwatch methods.
Automatic Cleanup
Watch relationships are automatically cleaned up when:
The watched actor terminates (you receive
Terminatedmessage)The watcher terminates
The actor system shuts down
Idempotent operations:
Watching an already-watched actor is safe (no duplicate notifications)
Un-watching an actor that isn't watched is safe (no-op)
Un-watching after receiving
Terminatedis safe (already cleaned up)
Terminated message
When a watched actor terminates, the watcher receives a Terminated message defined in the goaktpb package:
Handling Terminated Messages
Handle *goaktpb.Terminated in Receive; use msg.GetAddress() to identify the actor (compare with pid.ID()). Clean up your state and optionally restart or notify other.
Terminated Message Properties
address :
Unique identifier of the terminated actor
Format:
name@system:host:portCan be compared with
PID.ID()to identify which actor terminated
terminated_at :
Timestamp when the actor was terminated
Type:
google.protobuf.TimestampAccess via
msg.GetTerminatedAt().AsTime()for Gotime.Time
Watch vs Supervision
Watch and supervision serve different purposes and work together:
Supervision: Parent supervises children; automatic restart/stop/resume via strategies. Use for built-in fault tolerance (see Supervision).
Watch: Any actor can watch any other; you receive
Terminatedand implement custom logic. Use for lifecycle awareness, resource cleanup, and monitoring non-children.
Standard error recovery
Supervision
Child actor restart on failure
Supervision
Custom termination logic
Watch
Monitor non-child actors
Watch
Resource cleanup on termination
Watch
Both together
Supervision + Watch for full fault handling
Best Practices
Always handle
Terminated: Add acase *goaktpb.Terminated:inReceive; unhandled notifications go to dead letters.Match by address: Use
msg.GetAddress()and compare withpid.ID()to identify which actor terminated.Un-watch when done: Call
ctx.UnWatch(pid)when you no longer need the notification (e.g. on unregister).Combine with supervision: Use supervision for automatic recovery and watch for custom cleanup or coordination.
Don't watch yourself:
ctx.Watch(ctx.Self())is unnecessary overhead.Don't assume immediate delivery: After
pid.Shutdown(ctx), theTerminatedmessage is asynchronous; don't rely on it having arrived yet.Don't leak watches:
Unwatchor handle termination so relationships don't accumulate indefinitely.
Notes
Watching the same actor multiple times does not create duplicate notifications. Un-watching an actor you are not watching is a no-op.
Watch relationships are removed when the watched actor terminates (you get
Terminated), when the watcher terminates, or when the system shuts down.Terminatedis delivered like a normal message: queued in the watcher's mailbox and processed in order. Delivery is best-effort if the watcher is alive; it may be delayed if the mailbox is full.Watch works only with local actors in the same actor system. Remote actors cannot be watched.
Last updated