ADAMANT Notification Service v0.5.0 — .NET 8 modernization, reliability and privacy fixes #73
adamantmm
started this conversation in
Ecosystem & Integrations
Replies: 1 comment
|
Awaited release. |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
ADAMANT Notification Service (ANS) — the service that delivers Apple Push Notifications for the ADAMANT iOS app without ANS or Apple ever learning who is messaging whom — just shipped v0.5.0, its first tagged release since 0.4.1 back in 2019.
This wasn't a rewrite. ANS is planned to be succeeded by adamant-ns eventually, so the goal here was narrow: get the service off end-of-life dependencies and fix the bugs that were actually causing production incidents, without touching its architecture or its privacy model.
What changed
Runtime.
netcoreapp3.0(EOL, unsupported since 2020) → .NET 8 LTS, across every project. This is what unblocks native Ubuntu 22.04+ deployment — no more EOL-library containers to keep the old runtime alive.A real socket leak, fixed. The API client allocated a new
HttpClientper request and never disposed it. On production this showed up as a steady climb of sockets stuck inCLOSE-WAIT— confirmed at roughly 30+ file descriptors per minute on a running instance. Past a point, that takes out DNS resolution for the whole process. It's now a single shared, reused client.Failover that actually fails over. Node selection used to pick one random configured node and never retry — any error on that node, including a transient one, crashed the whole service. It now retries against a different node before giving up, and a total outage across every configured node degrades to "skip this cycle," not "crash."
An EF Core surprise. The plan was to leave EF Core alone and only raise the app's own target framework. That held for the ORM core (EF Core 2.2 targets
netstandard2.0, so it still compiles against .NET 8), but the MySQL provider —MySql.Data.EntityFrameworkCore— turned out not to run at all: aAmbiguousMatchExceptionon the very first query, caught by a new SQLite-backed smoke test before it reached anywhere near production. Replaced withPomelo.EntityFrameworkCore.MySql, the actively maintained provider most of the .NET ecosystem has already standardized on.Privacy fixes. Three log statements were quietly printing sensitive data: a device token on every successful push, a decrypted signal payload (which embeds the device token) on a parse failure, and an APNs certificate password on a load failure. All three violated the project's own stated privacy rules and are gone now.
Graceful shutdown. Neither worker used to observe
SIGTERM, so a routinedocker stoporsystemctl restartalways looked like a crash in the logs. They now shut down cleanly.Found running it in production, after the above landed: a
~path-expansion bug that could stop both workers from starting at all on a headless server, a startup edge case that could burst-notify every registered device about old transactions after a network hiccup, a thread-safety issue in node selection under concurrent use, a missing HTTP timeout, and a null reference on a particular malformed APNs response.Tests and version tracking. 35 tests now cover this (up from a handful), including the EF Core/SQLite smoke test mentioned above. Builds also carry a real version number now — previously every build silently shipped as
1.0.0.0regardless of what the project file claimed.Security
Links
Questions or feedback welcome below.
All reactions