Changelog
View SourceAll notable changes to this project are documented here. The format follows Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]
[0.1.2] - 2026-05-08
Documentation
- Operational considerations section added to the README,
documenting two production footguns:
- Sender restart producing a new
{ip, port}peer identity from the Listener's perspective (because Sender uses ephemeral source ports). Recommends:node_resolveras the standard production setup. - DNS resolution cost and failure modes in Sender. Recommends pre-resolved IP tuples for deployments with unreliable DNS.
- Sender restart producing a new
- Listener moduledoc reframes
:node_resolveras the recommended production setup, not just a "static topology" option. - Sender moduledoc expands the DNS resolution note.
No behaviour change.
[0.1.1] - 2026-05-08
Changed
- Listener flow control.
PhiAccrualUdp.Listenernow opens its UDP socket withactive: N(defaultN=100, configurable via the:active_countoption) instead ofactive: true. Re-arms on:udp_passive. This bounds the per-burst mailbox growth under packet floods.
Added
- Telemetry event
[:phi_accrual_udp, :listener, :passive], emitted each time the listener re-arms after consumingactive_countpackets. Useful for observing ingress saturation.
[0.1.0] - 2026-05-07
Initial public release. Alpha — public API and wire format may
change before v1.0 based on real-deployment feedback.
Added
- Wire format v1 (
PhiAccrualUdp.Packet) — 12-byte fixed format with magic0xCEA6, version0x01, reserved flags byte (must be zero in v1), and 64-bit unsigned millisecond timestamp. - UDP listener (
PhiAccrualUdp.Listener) — opens a UDP socket on a configurable port, decodes incoming packets, callsPhiAccrual.observe/2with local monotonic receipt time. Decode failures emit[:phi_accrual_udp, :decode, :error]telemetry with reason classification. - Periodic UDP sender (
PhiAccrualUdp.Sender) — sends heartbeat packets to a list of{host, port}targets at a configurable interval. Configurable timestamp source. - Custom node resolution — listener accepts a
:node_resolverfunction mapping(ip, port)to user-defined node identifiers. Default:{ip, port}tuple. - Telemetry schema —
[:listener, :started],[:sample, :received],[:decode, :error],[:sender, :started],[:sender, :tick].
Notes
- Wire format and telemetry schema are not yet committed. Both
may change before
v1.0. Magic/version/flags structure is deliberately chosen to permit format evolution without breaking on-the-wire compatibility for v1 senders. - Receiver-driven clock discipline: the EWMA uses local monotonic
receipt time, never the packet timestamp. This preserves
phi_accrual's contract that cross-node timestamps are meaningless.