https://gitlab.synchro.net/main/sbbs/-/commit/d411e916a9ea1d6a4f27808e
Added Files:
exec/tests/ircd/timeout.js
Modified Files:
docs/v322_new.md exec/ircd.js exec/load/ircd/core.js
Log Message:
ircd: survive a stalled callback engine instead of splitting the net
vert's IRCd froze for ~37 minutes today and every linked server dropped.
The daemon is a single-threaded callback engine and its ctrl_dir is on an
SMB share that wedged: the once-a-second file_date() of ircd.rehash
blocked in the redirector, so no socket was serviced and no PING
answered, and all 69 links timed out. When the share came back, the
network re-linked in one burst.
Two changes, neither of which pretends a stall can't happen:
- Poll the rehash semaphore every 15 seconds instead of every second,
and back off geometrically (to 5 minutes) for as long as the stat
itself takes a second or more, logging the back-off and the recovery.
How often we stat ctrl_dir is how often we're willing to block on it.
The re-arm moved to a self-scheduling timeout in a finally, so a throw
out of Read_Config_File() can't quietly end rehash checking.
- Watch the gap between our own watchdog ticks. A gap of 10 seconds or
more means the engine was frozen, not that the network went silent, so
bump a stall generation (logged, and reported to opers) and let
IRCClient_check_timeout() give every connection one more ping round to
answer before closing it. A PONG that queued up during the stall
clears the ping first, and peers that really are gone still die on the
next round.
This can't stop remote servers from dropping us while we're frozen --
nothing running here can -- but we no longer close every link ourselves
on the way back, and a stall now leaves a log entry behind.
exec/tests/ircd/timeout.js covers both the unchanged ping/close schedule
and the new forgiveness (spent once per stall, never on a connection's
first check).
Co-Authored-By: Claude Opus 5 (1M context) <
noreply@anthropic.com>
---
þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net