Executive Summary
v4.0.0 delivers simplification and performance:Quick Reference Table
Breaking Changes
1. Message types: proto.Message → any
All message-passing APIs now accept any instead of proto.Message:
Migration: Replace
proto.Message in Receive handlers and call sites with any. Serialization is handled by the
remote.Serializer layer.
2. System messages: goaktpb → actor
The goaktpb package has been removed. System message types are plain Go structs in actor:
Use constructors (e.g.
actor.NewDeadletter(...)) instead of protobuf struct literals. Timestamps are time.Time
instead of *timestamppb.Timestamp.
3. Actor reference: ActorRef → *PID
ActorRef has been removed. *PID is the sole actor reference for both local and remote actors. Use pid.IsLocal() or
pid.IsRemote() when location matters.
Migration: Replace ActorRef with *PID; methods returning ActorRef slices now return []*PID.
4. Lookup: unified ActorOf
LocalActor, RemoteActor, and ActorRefs are replaced by a single ActorOf(ctx, name):
Migration: Use
pid.Path() for host/port/name/system; pid.IsLocal() / pid.IsRemote() for location.
5. Actors merged with ActorRefs
timeout bounds cluster scan and is ignored when not in cluster mode.
6. Remote scheduler methods removed
RemoteScheduleOnce, RemoteSchedule, RemoteScheduleWithCron are removed.
Migration: Obtain remote PID via ActorOf and use unified ScheduleOnce, Schedule, or ScheduleWithCron.
7. GetPartition renamed to Partition
Migration: sys.GetPartition(name) → sys.Partition(name).
8. Address → Path
pid.Address() is replaced by pid.Path(), which returns a Path interface. The address package is now internal.
Path() returns nil for nil PID. Guard accordingly (e.g. for NoSender).
9. Remoting configuration
The remoting client is internal. Theremote package exposes only configuration and protocol types (Config,
Serializer, Compression, ContextPropagator, etc.).
Migration: Replace remote.Remoting / remote.Client — use actor system and client.Node APIs. Replace
remote.NewRemoting() / remote.NewClient() — use WithRemote(config) when creating the actor system. For tests:
mockremote.NewClient(t) for mock injection.
10. Log package
CustomLogger implementations must implement additional methods:
Migration: Use
log.DiscardLogger in tests if you need a no-op.
11. Testkit & ReceiveContext
New Additions
Pluggable serialization
- ProtoSerializer — Default for
proto.Message. No change for protobuf users. - CBORSerializer — For arbitrary Go types. Register via
remote.WithSerializers(new(MyMessage), remote.NewCBORSerializer()); types are auto-registered. - Custom — Implement
remote.Serializer; register viaWithSerializersonremote.Config.
Path interface
pid.Path() returns a Path interface—location-transparent actor identity.
See Location Transparency.
New sentinel errors
errors.ErrRemotingDisabled— Remote operation attempted but remoting not configurederrors.ErrNotLocal— Operation requires local PID but remote PID provided
PID.Kind()
pid.Kind() returns the reflected type name of the actor backing the PID. Empty string for remote PIDs.
Log implementations
log.NewSlog(level, writers...)— stdlib slog with low-GC optimizationslog.NewZap(level, writers...)— Zap with buffered file outputlog.DiscardLogger— No-op for tests
Remoting Capabilities
Remoting is configured viaremote.NewConfig(bindAddr, bindPort, opts...) and passed to WithRemote(config).
Transport
- Length-prefixed TCP frames; pooled connections
- Optional TLS
- Compression:
NoCompression(default),GzipCompression,ZstdCompression,BrotliCompression
Server options
Remote spawn options
When spawning on a remote node viaWithHostAndPort(host, port):
Migration Checklist
- Update import path:
goakt/v3→goakt/v4 - Replace
proto.Messagewithanyin handlers and call sites - Replace
goaktpb.*withactor.*; use constructors for structs - Replace
ActorRefwith*PID - Replace
LocalActor/RemoteActorwithActorOf(ctx, name) - Replace
pid.Address()withpid.Path() - Replace
ctx.SenderAddress()/ctx.ReceiverAddress()withctx.Sender().Path()/ctx.Self().Path() - Replace
GetPartitionwithPartition - Replace
WithRemotingwithWithRemote(config) - Remove
addresspackage imports; usePathinterface - Update custom
Loggerimplementations with new methods - Update tests:
Probe.SenderAddress()→Sender()+Path() - Remove
RemoteSchedule*usage; useSchedule*withActorOfPID