diff options
| author | Adam Soltys <[email protected]> | 2026-06-04 18:17:47 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-06-04 18:17:47 -0700 |
| commit | bd1ece38e42751575ac2e03a5c795b5b109653ac (patch) | |
| tree | ce5f648953b89db5ce94f6f8218ed35799a4f960 /lib/countries.js.map | |
| parent | be896868de55ef82b268d8c9f92c3f0ba857fed8 (diff) | |
| download | coinos-server-bd1ece38e42751575ac2e03a5c795b5b109653ac.tar.gz coinos-server-bd1ece38e42751575ac2e03a5c795b5b109653ac.zip | |
ln/lightning: watchdog recycles zombie receive-listener socket
On 2026-06-04 cl restarted (autoheal, after its 15s healthcheck timed out),
and the app's waitanyinvoice long-poll hung on the now-dead listen socket.
listenerActive stayed true forever, so ensureListenerAlive never restarted
it, and incoming lightning payments stopped crediting for ~2h until a manual
app restart. The per-call RPC timeout in ln.ts can't catch this: waitanyinvoice
is intentionally in NO_TIMEOUT (it's meant to block).
Fix: ensureListenerAlive (runs every 120s) now also detects a stalled listener
— active but blocked in waitanyinvoice for >5min. It probes cl via the main
ln socket (getinfo); only if cl is actually alive does it treat the listen
socket as a zombie, call lnListen.reset() (new: drops the proxy's socket so the
next call reconnects), and re-arm. A listenerEpoch guard makes the wedged
invocation bow out when its waitanyinvoice finally rejects, so we never run two
listeners concurrently and never double-credit. Verified with a state-machine
test covering normal receive, quiet-but-healthy (left alone), stall+cl-alive
(recycled), stall+cl-down (left alone), and the no-double-listener race.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Diffstat (limited to 'lib/countries.js.map')
0 files changed, 0 insertions, 0 deletions
