Overview
GoAkt supports multiple clusters across datacenters. A pluggable control plane (NATS JetStream or etcd) propagates topology and placement decisions across sites. Actors can be spawned or messaged across DCs. Each datacenter runs its own cluster; the control plane coordinates which DCs are active and where to route cross-DC traffic.Architecture
- Control plane β Manages datacenter registration, heartbeats, state transitions, and event watching. Implementations: NATS JetStream, etcd.
- DC leader β Only the cluster leader in each DC runs the datacenter controller. It registers the local DC with the control plane using cluster membersβ remoting addresses.
- DataCenterRecord β Each DC has a record: ID, metadata (Name, Region, Zone, Labels), Endpoints (remoting addresses), State, LeaseExpiry, Version.
When to use
- Geographic distribution β Run actors close to users or data in different regions.
- Disaster recovery and failover β Replicate or fail over to another DC.
- DC-aware placement β Spawn actors in a specific datacenter via
SpawnOnwithWithDataCenter.
Control plane backends
| Backend | Package | Use case |
|---|---|---|
| NATS JetStream | datacenter/controlplane/nats | Lightweight, good for cloud-native setups |
| etcd | datacenter/controlplane/etcd | Strong consistency, Kubernetes-friendly |
NATS JetStream
etcd
Configuration
Multi-DC requires cluster mode. Configure the datacenter viaWithDataCenter on the cluster config:
Datacenter config options
| Option | Default | Purpose |
|---|---|---|
HeartbeatInterval | 10s | How often the DC renews its liveness lease |
CacheRefreshInterval | 10s | How often the DC registry cache is refreshed |
MaxCacheStaleness | 30s | Max age of cached DC data before routing is restricted |
FailOnStaleCache | true | If true, SpawnOn with WithDataCenter returns ErrDataCenterStaleRecords when cache is stale. If false, proceeds with best-effort routing. |
WatchEnabled | true | Use watch-based cache refresh when the control plane supports it |
Data center states
| State | Meaning |
|---|---|
REGISTERED | Record exists but not yet eligible for routing |
ACTIVE | Eligible for routing as long as lease is valid |
DRAINING | Avoid new placements; existing traffic may continue |
INACTIVE | Not eligible for routing |
Heartbeat renews the lease. Expired records should not be routed to.
DC-aware actor placement
UseSpawnOn with WithDataCenter to spawn an actor in a specific datacenter:
DataCenterRecord.Endpoints, selected uniformly at random. Which node runs the actor depends on what that DC registeredβif it registered all nodesβ remoting addresses, the actor is placed on a random node in that DC.
The actor kind must be registered on the target DCβs actor systems; otherwise the remote node returns ErrTypeNotRegistered.
Messaging across DCs
Once an actor is spawned (locally or in another DC), messaging is location-transparent. UseTell, Ask, Request as usual; the framework routes to the correct node.
Grains can also be addressed by identity across DCs when multi-DC is enabled: the system uses the control planeβs cached
active datacenter records and attempts delivery to the first endpoint that successfully handles the request.
Readiness and errors
| API | Purpose |
|---|---|
system.DataCenterReady() | Returns whether the multi-DC controller is operational |
system.DataCenterLastRefresh() | Time of last successful DC cache refresh |
| Error | When |
|---|---|
ErrDataCenterNotReady | Controller not ready; SpawnOn with WithDataCenter fails |
ErrDataCenterStaleRecords | Cache older than MaxCacheStaleness and FailOnStaleCache is true |
ErrDataCenterRecordNotFound | Target DC not in active records or not in ACTIVE state |
Custom control plane
Implement thedatacenter.ControlPlane interface:
Register,Heartbeat,SetState,ListActive,Watch,Deregister
datacenter/controlplane/nats and datacenter/controlplane/etcd as reference implementations. Wire it in by passing the control plane to the datacenter config when creating the actor system.
See also
- Clustered β Cluster setup and discovery
- Relocation β Actor relocation within a cluster
- Remoting β Cross-node messaging