v0.4.2 (2026-10-04)
Enahancements
- Support retrieving tenant via anonymous function
v0.4.1 (2026-09-04)
Bug fixes
- Fixed a race where an unregister could delete a binding it didn't own, freeing a name twice under ordinary concurrency.
- Fixed the DST harness's readiness poll hanging on a virtual clock deadline.
- Fixed a lock holder that was busted mid-run releasing its successor's lock.
- Fixed a lock holder that was busted mid-run overwriting its successor's writes.
Enhancements
dgen_registryis now stable, and no longer experimental.- The
dgen_serverlock is now fenced. A busted holder is refused at commit and its message is retried, solock_timeoutcan be tuned for recovery speed.handle_locked/4must be safe to run twice. Seedocs/design/dgen_server_design.md§4.4. - Added tests for
lock_timeoutand theconsume_batchexit points. dgen_registry_memberrewritten as agen_statemwith explicit searching/assuming/leader/follower states.sys:get_state/1now returns{State, Data}.- Leadership handoff sped up (~2x faster election window at 200k names) by cutting map allocations, shrinking the snapshot encoding, and deferring monitor setup off the critical path.
- Expanded TLA+ model and DST invariants covering replication and leader handoff.
- Added a per-registry
connectivityoption (provided_externally) to let a registry share another registry's distribution mesh instead of running its own. Seedocs/dgen_registry_design.md§4.6 and §8.
v0.4.0 (2026-07-12)
Enhancements
dgen_registry— a defined consistency model (still experimental). Full contract indocs/dgen_registry_design.md. Highlights:- CP and fenced — the leader is fenced on a backend key, so a deposed leader cannot commit; no split-brain, minority partitions refuse writes.
- Singleton uniqueness across any single member failure; pids never persisted (~2 durable keys per registry).
- Two-holder addressability — an acked registration is held by ≥2 members;
tunable via
register_replicas/replicate_timeout/strict_replication. - Dynamic membership with an automatic mesh — nodes join/leave by starting/stopping the registry; no external discovery.
- Lock-free snapshot reads —
whereis_name/1is anets:lookup/2in the calling process (eventually-consistent snapshot; empty briefly after member restart). - Per-registration metadata — an
indexmap + opaquedata, set viaregister_name/3/set_metadata/2, read viaget_metadata/1orget_metadata_consistent/1; lifetime is exactly the registration's (§4.7). - Indexed queries —
query/2/query_consistent/2match AND-equal constraints over indexed attributes against a batch-consistent snapshot. - Durable presence — subscriptions (watch + notify queries under a
SubId) push{dgen_presence, SubId, Events}on membership changes; stored durably, so they survive full cluster restarts. - Formally verified replication — core safety properties checked against a
TLA+ model (
formal/).
dgen_transaction(new behaviour) — owns a single backend transaction in its own process with caller-controlled retry; substrate for the registry's group commit.dgen_server—consume_kdocumented; whenconsume_k > 1, inlinecallhandling is disabled so batching stays in effect.priority_call/priority_caststill bypass the queue.
Behavioral notes
- The registry may forcibly kill a registered process to enforce uniqueness.
Register only restart-safe processes. Configurable via
terminate_on_conflict(defaulttrue); see §5.6.
Breaking changes
dgen_registry:start_link/3(SupNamevariant) removed — the registry supervisor is nameless by design; hold the returned pid instead.elector_name/1removed in favor ofelector_pid/1;member_name/1andnames_table/1are now identity functions.register_name/2,3exits on call timeout instead of returningno—nois now strictly an adjudicated verdict. Timeout configurable viaregister_timeout(default 5000 ms).
v0.3.0 (2026-06-17)
Enhancements
- Transactional callbacks — optional
handle_cast_tx/3,handle_call_tx/4,handle_info_tx/3receive atx_ctx()(open transaction + directory) so callbacks can read/write keys atomically with the state commit. lock_timeoutoption fordgen_server— backstop timer clears a stale distributed lock left by a killed consumer. Defaultinfinity(old behavior);dgen_registryuses 6000 ms.dgen_registry(experimental) — OTP-compatible process registry over the storage backend, addressed via{via, dgen_registry, {Name, LogicalName}}. Writes and consistent reads go through an elected leader;whereis_name/1is a local snapshot read. Partition recovery is token-fenced so stalemember_downmessages can't undo a rejoin.
Breaking changes
DGenServer→DGen.Server(lib/dgen/server.ex).handle_locked/3→handle_locked/4— adb_ctx()map is prepended as the first argument.
v0.2.0 (2026-04-05)
Enhancements
- Dead-letter queue — opt-in via
dead_letter_threshold; messages crashing the consumer that many times move to a DLQ, callers raise{dead_letter, N}, and the optionalhandle_dead_letter/2callback fires. dgen_server:outbox_cast/1,2— returns a closure for enqueuing a cast atomically inside the caller's own backend transaction.
v0.1.0 (2026-02-22)
Initial release.