- Materialize per-shard exact and slash-prefix process-group cardinalities so
Group.member_count/3andGroup.local_member_count/3no longer scan memberships. Counts follow resident-row diffs across local writes, replication, snapshots, and peer eviction, and rebuild from primary ETS rows after a shard restart. - Add layered anti-entropy qualification: three-node StreamData lifecycle
models, seeded adversarial transport histories, TLA+ models for convergence,
chunk assembly, and permanent peer eviction, plus a Docker-backed Jepsen
oracle across distribution, a test-only sideband TCP lane, and
lossy/reordering transports.
mix testis the every-PR ExUnit/property/checker gate andmix test.soakruns the six-profile nightly/release campaign. - Breaking: move the replica transport API from
Group.Replica.Transport.*toGroup.Transport.*; the default adapter is nowGroup.Transport.DistErl. The boundary also names logical direction rather than implementation mechanics: adapters implementoutgoing/5, sideband adapters useGroup.Transport.Outbox.push/5, and receiving adapters callGroup.Transport.incoming/4orincoming_batch/4. No compatibility aliases are provided. - Rename the internal replica wire helper from
Group.Replica.ProtocoltoGroup.Replica.WireProtocolto avoid overloading Elixir protocol terminology. The standalone TCP adapter is retained only as hidden test infrastructure; Group ships the transport contract, dist-Erlang adapter, and outbox helper. - Breaking: replica protocol v3 streams exact snapshots as provisional,
transport-neutral byte-targeted chunks (
1 MiBby default) followed by an independently retryable terminal manifest. The sender scans once and retains only its current chunk; a concurrent mutation suppresses commit. Receivers stage in reusable shard-owned private ETS and advance the cursor only after one exact, authority-fenced assembly is complete. Chunk/commit loss, duplication, reordering, conflicting retransmission, supersession, expiry, and shard crashes remain repairable by anti-entropy. Sideband transports can use per-shard local outboxes for bounded batching without adding a hop to the default dist-Erlang adapter. Late-starting replica lanes now rebuild their view from shared exact authority when startup fanout races registration. - Replace replica state sends/snapshots with per-origin, generation- and
cluster-epoch-fenced streams: sequenced deltas repair gaps from a bounded
oplog and fall back to exact origin snapshots after pruning. Replica data now
uses a pluggable nonblocking transport (dist Erlang by default via
send_nosuspend), while dist Erlang remains the control plane. Nonblocking control heartbeats lease peer state, requesting a fresh authoritative hello on generation or epoch-revision changes, so a stopped Group on a connected VM cannot leave permanent registry or membership rows. Reconnects also sweep superseded per-shard receive cursors and reconstruct epochless PG rows, so reordered cluster controls cannot strand live rows from an older epoch. Full epoch authority is installed once by shard 0; matching data shards exchange constant-size lane hellos and retain shard-to-shard transport ordering. Authority capture is serialized with epoch activation, and exact versus incrementally observed revisions are tracked separately so a concurrent partial snapshot cannot be mistaken for complete authority. - Registry authority is retained per origin separately from the visible winner. Conflict callbacks select the winner; Group now records and propagates an authoritative loser delete, and each owner node terminates only its own losing process. This also applies to custom conflict callbacks.
- Add
Group.monitor_generation/1so long-lived registration owners can terminate and re-register when the local membership ETS generation is lost. - Breaking:
Group.disconnect/3now discards the complete local view of each departed cluster — remote entries included, and monitors receive:unregistered/:leftevents for them — instead of removing only locally owned rows. Reconnecting resyncs through the normal snapshot exchange.connect/disconnectalso raiseArgumentErrorfor non-binary cluster names instead of silently tolerating them. - The registry conflict resolver now consistently includes the winner's metadata in
the losing process's
{:group_registry_conflict, key, winner_meta}exit reason. - Breaking:
Group.dispatch/4remote sends and process-DOWN replication are now non-suspending and never auto-connect. Busy dispatch drops still force a disconnect and bounded reconnect retry; replica messages are dropped and repaired by anti-entropy without disturbing the dist-Erlang control connection. Previously dispatch could block the caller and initiate new connections. - Configured function-form
extract_metacallbacks are now applied on reads and lifecycle events (previously they were silently ignored and full metadata was exposed), and invalid:extract_metavalues raiseArgumentErrorat startup. Group.lookup/3no longer convertsArgumentErrorraised by metadata extraction callbacks into anilmiss; extractor errors now propagate to the caller.- Invalid
:shardsvalues (zero, negative, non-integer) raiseArgumentErrorat startup instead of failing later during key routing.
- Add bounded
Group.members/3queries withlimit:and local-owner process-group queries throughGroup.local_members/3
- remove deprecate message handling
- Use
send_nosuspendfor remote shard sends and add bounded reconnect retries after busy-link disconnects to avoid any single bad link from blocking a shard
- Fix local shard request reply leaks by using reply aliases and draining any already-delivered timeout replies
- Add bounded local PG turn-taking and bulk local PG ETS application
- Add sender-side replicated registry / PG batching by target node
- Add receiver-side batching and fairness for replicated registry traffic
- Add named-cluster
Group.connect(..., ttl: ms)leases
- Add configurable timeouts to the public register/unregister/join/leave/connect/disconnect APIs
- Add
Group.local_entries/1for local tagged registry and process-group entries - Buffer replicated PG join/leave receives with configurable receiver-side flush settings and bulk ETS application
- Optimize pg ops
- Optimize DOWN handling
- Initial release!