ShardedDaemonProcess starts a fixed number of long-running actor behaviors across an Akka cluster. It is useful when work has known partitions—such as journal tags—and each partition should run once while cluster nodes share the load. As nodes join, behaviors can be rebalanced onto the new nodes. section 10.3.3 section 10.3.4
Unlike Akka Sharding, it requires the instance count at initialization time and does not provide a sharded-region proxy for directly messaging the spawned behaviors. The behaviors are suited to autonomous processes; a receptionist can be used when discovery is needed. section 10.3.3
Start three tagged daemon behaviors
Create a cluster ActorSystem, keep the tags in a Vector, then call init with a process name, tags.size, and a factory from index to behavior. The index selects the tag, so three tags create three LoggerBehavior instances. When a second node joins, one behavior may move there; with three nodes, each can host one behavior. section 10.3.4 section 10.3.4
Listing 10.10 Using a ShardedDaemonProcess
import akka.cluster.sharding.typed.scaladsl.ShardedDaemonProcess
object MiniCluster {
def main(args: Array[String]): Unit = {
startup(args(0).toInt)
}
def startup(port: Int): Unit = {
val config = ConfigFactory
.parseString(s"""
akka.remote.artery.canonical.port=$port
""")
.withFallback(ConfigFactory.load("shardeddeamon")) #1
val system = ActorSystem[Nothing](Behaviors.empty, "MiniCluster", config)
val tags = Vector("container-tag-1",
"container-tag-2",
"container-tag-3") #2
ShardedDaemonProcess(system)
.init(
"loggers",
tags.size,
index => LoggerBehavior(tags(index))) #3
}
}
The initialization listing shows the essential API shape: name the process, set its fixed instance count from tags.size, and build each behavior from its index. section 10.3.4
For projections, wrap the projection in ProjectionBehavior because ShardedDaemonProcess spawns behaviors rather than projections directly. Use tags as partition keys so each process reads a distinct tagged event stream. A stop message lets a behavior close resources before rebalance or cluster shutdown. section 10.3.5 section 10.4
Operational details for projection processes:
- Pass ShardedDaemonProcessSettings to read sharded-daemon-process configuration, including the keep-alive interval. section 10.3.5
- The cluster pings ProjectionBehavior every 10 seconds by default; after a rebalance stops a behavior, keep-alive helps ensure it starts again. section 10.3.5
- Supply Some(ProjectionBehavior.Stop) when a projection must perform cleanup, such as closing a database connection, before stopping. section 10.3.5
Scale tagged projections
A cargos-per-container projection starts one process per tag. After another node starts on a different port, it takes over one tag and its projection; each projection keeps its own journal offset while updating the projected data. section 10.4 section 10.4
The same pattern initializes BetProjection and MarketProjection: create as many wrapped projection behaviors as entity tags, then distribute them across the cluster. A market projection can use its handler to publish serialized events to Kafka while ShardedDaemonProcess partitions the projection work. section 15.1.2 section 15.1.2
