v0.48.13
thevoiceguy/siphon-aiv0.48.13Aug 10, 2026by github-actions[bot]
Upgrading?
AI Summary
Maintenance release fixing memory leaks in SIP dialog management by implementing a deferred reaper.
Key Highlights
- Fixed `DialogManager` memory leak where finished calls left dialogs in the store.
- Implemented deferred reaper with a 32s grace window (Timer H/J).
- Added `siphon_ai_dialogs_active` gauge.
- Fixed RSS growth from ~2.1 KB/call to ~0.78 KB/call.
New Features
- Dialog reaper mechanism to clean up completed dialogs.
Full Release Notes
### Fixed - **Finished calls no longer leave their SIP dialog in the shared store forever** (issue #458). `sip-uas` inserts one confirmed dialog per accepted INVITE and siphon-ai never removed it, so `DialogManager` grew for the life of the process — the per-call RSS growth reported against 0.48.10. **The memory was the smaller half of the problem:** `sip-dialog` caps the store at `MAX_CONFIRMED_DIALOGS = 10_000` and `sip-uas` discards the resulting `insert` error (`let _ = ...`), so a daemon past ten thousand cumulative calls silently stops tracking new dialogs altogether — and in-dialog requests (BYE, re-INVITE, the post-REFER NOTIFY, transfer) resolve through exactly that store. At 10k calls/day that is a one-day fuse on a busy node, and nothing in the daemon reported it. Located with a `dhat` heap profile diffing a 100-call run against an 800-call run at constant concurrency: `DialogManager::insert` ← `sip_uas::accept_invite_with_session_timer` ← `BridgingAcceptor::on_matched`, ~976 B/call, with the retained dialog's contact URI and two transaction-metrics `String`s never freed alongside it. Ruled out on the way: metrics cardinality (series count flat at 60 across 4,000 calls), the call registry (empty after every batch), multi-arena glibc fragmentation (`MALLOC_ARENA_MAX=2` was marginally *worse*), untrimmed heap (aggressive `MALLOC_TRIM_THRESHOLD_` changed nothing), and the transaction map (genuinely bounded — it evicts oldest at `max_server_transactions`). - The fix is a **deferred reaper** (`crates/core/src/dialog_reaper.rs`) rather than a removal at teardown, because the dialog store is what in-dialog requests match against: dropping a dialog the moment its call ends would race the very BYE that ended it, and a peer retransmitting BYE after our `200 OK` must still get a `200`, not "unknown dialog". Teardown *retires* a `DialogId`; a sweeper removes it once a 32 s grace window (SIP Timer H/J — the BYE retransmission window) has passed. Within that window behaviour is exactly as before. The upstream `terminate()` + `cleanup_terminated()` pairing was the intended shape but is unusable from here — `DialogManager::get` returns a *clone*, so `Dialog::terminate()` marks a copy and leaves the stored dialog untouched. - New gauge **`siphon_ai_dialogs_active`**, sampled each sweep, because there was previously no way for an operator to watch this grow — the other half of why it went unnoticed. It should track `calls_active` lagging by the grace window. - Verified live over 4,000 calls at constant concurrency: `dialogs_active` returns to **0** after every batch (it previously grew 1:1 with call count), all 4,000 terminated `caller_hangup`, SIPp reported zero failures, and the daemon logged **no warnings and no `481`s** — the retransmitted-BYE path the deferral protects. Steady-state RSS growth after pool warm-up fell from ~2.1 KB/call to ~0.78 KB/call; the residue is allocator overhead and the bounded transaction map, not retained dialogs. --- **Artifacts** - Static musl binaries for `x86_64` and `aarch64` (`.tar.gz`). - Debian packages (`.deb`) for `amd64` and `arm64` — `apt install ./siphon-ai_*_amd64.deb`. - `SHA256SUMS` — verify with `sha256sum -c SHA256SUMS`. - `*-sbom.cdx.json` — CycloneDX SBOM. - `SHA256SUMS.cosign.bundle` — cosign keyless signature over the checksums. - Container: `ghcr.io/thevoiceguy/siphon-ai:v0.48.13` (multi-arch, cosign-signed). Verify the checksums signature: ``` cosign verify-blob --bundle SHA256SUMS.cosign.bundle \ --certificate-oidc-issuer https://token.actions.githubusercontent.com \ --certificate-identity-regexp 'release.yml@' SHA256SUMS ```
Related Repositories
A cross-platform desktop All-in-One assistant for Claude Code, Codex, OpenCode, OpenClaw, Grok Build & Hermes Agent. Only official website: ccswitch.io
An open-source remote desktop application designed for self-hosting, as an alternative to TeamViewer.
Build smaller, faster, and more secure desktop and mobile applications with a web frontend.
π RuView turns commodity WiFi signals into real-time spatial intelligence, vital sign monitoring, and presence detection — all without a single pixel of video.
Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one