datum-cluster-sharding 0.10.6

Datum cluster sharding core: envelopes, coordinator, regions, and entities
Documentation

datum-cluster-sharding

datum-cluster-sharding is the v0.10 cluster-sharding satellite for Datum. It ships ShardEnvelope, shard extraction, deterministic oldest-member coordinator allocation, peer ShardRegion routing over C2 DCP node-session shard pipes, bounded buffering while a shard is allocated, bounded handoff buffering while a shard is rebalanced, and first-message entity actor startup. The data path uses long-lived per-peer pipes with batch-when-behind/no-linger flushing; shard allocation misses remain on the control-plane request/response path.

The default shard extractor uses a stable FNV-1a hash for cross-version and cross-platform shard IDs. Upgrading from 0.10.0 causes a one-time remap for deployments that used the old default extractor.

Delivery in v0.10 is intentionally modest: at-most-once per send attempt, ordering per entity from a single sender that awaits each send, in-memory allocation tables, and no persistent shard allocation store. When a node is downed, the coordinator reallocates its shards with the least-shards strategy; entity state is not migrated. Graceful join-driven rebalance uses the same strategy with rebalance_per_round as the Akka-style per-round cap.

Remember-entities is opt-in per entity type via register_remembered_entity_type. A configured RememberEntitiesStore records entity starts/stops through a bounded write-behind queue, so store writes do not block normal message delivery. When a remembered shard starts locally after rebalance, restart recovery, or coordinator takeover, the region lists the shard's remembered ids and starts those entity actors without waiting for the next message.

Two stores ship with the SPI. InMemoryStore is for tests and single-process development: it survives rebalance only when all regions share the same store value, and it does not survive process death. FileStore writes one append log per shard under a configured directory and compacts the shard log on passivation. Its default fsync policy fsyncs appends and compactions, but delivery is still write-behind: a message can be acknowledged before the start record is durable. FileStoreFsyncPolicy::Never and OnCompaction trade durability for less storage overhead. A future datum-cdc/persistent store is a follow-up, not part of this crate.

Passivation removes remembered ids: EntityRef::passivate() stops the current entity actor and deletes it from the remember store, while passivation_idle_timeout passivates idle local entities on the region tick. If a passivation command or user envelope reaches a moving shard, it is ordered through the same bounded handoff buffer before the new owner sees later messages. Ordinary entity actor failure/restart and node stop are not passivation and do not remove the id from the store.

Coordinator takeover rebuilds the allocation table from surviving regions and keeps the highest generation for each shard. Any rebuilt entry that still points at a non-eligible member is reallocated by the new coordinator, so an in-flight migration can be lost as a generation update but cannot orphan the shard. Remember store failures publish RememberEntitiesEvent shard-level errors. FailOpen keeps routing after an event; FailClosed marks that shard failed so future messages fail fast until the region is restarted or replaced.