• webv4/root/api/events.ssjs

    From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Wed Jul 29 20:43:50 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/7399e3a62d1acd5a679e59d7
    Modified Files:
    webv4/root/api/events.ssjs
    Log Message:
    webv4: bound the lifetime of an event stream

    api/events.ssjs looped for as long as client.socket.is_connected, which
    for a client that goes away without closing its socket is forever: the
    pings are small enough to keep being accepted, nothing forces a write
    failure, and no TCP keepalive is in play to notice the peer is gone.

    Nothing else bounded it either. A session sitting inside a long-running
    script never returns to the request read path, and MaxInactivity is
    enforced only there (in sockreadline), so the one timeout the web server
    has cannot reach it. Each stranded stream holds a client slot, a session thread, an output thread and a JS runtime until the server recycles.

    Measured on this host while its 200-client web pool was saturated and
    refusing roughly a thousand connections per ten minutes: of 195 connected clients, 172 were addresses that had opened one of these streams, the
    median connection age was 6.7 hours and the oldest 20.3 hours.

    Stop after settings.event_stream_duration seconds (default 3600; 0
    restores the old unbounded behavior). The close is graceful and
    EventSource reconnects on its own, so a reader sees at most a brief gap in
    the node list - and the reconnect lets the accept-time filters re-evaluate
    a client that has held one socket for hours.

    Related to #1154, which proposes the server-side connection-age cap that
    would bound this for any script, not just this one.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net