From 75aa635dad197af0eac46fa1e5e6134af8c33669 Mon Sep 17 00:00:00 2001 From: Matteo Nastasi Date: Sun, 13 Sep 2026 12:38:27 +0200 Subject: [PATCH] the watchdog reloaded the page even while data was arriving If for 16 seconds (keepalives_eq_max x watchdog_checktm x watchdog_timeout) the keepalive counter does not move forward, the client declares the connection dead and reloads the page, splash included. But that counter only moves forward when the client manages to CONSUME the incoming data. If the browser is busy - redrawing the list of a crowded room, say - the data arrives regularly and sits there waiting to be parsed: the counter stays put and the watchdog reloads a perfectly healthy connection, throwing away the work done. Now, before declaring it dead, it looks at whether there is still something to consume: bytes received and not parsed yet, commands already extracted and not executed yet, or slow actions in progress (st_loc < st_loc_new, which is the client itself saying it is busy). In those cases the connection is alive and it gets another round instead of a reload. The timeout stays at 16 seconds: what changes is the criterion, not the patience. A connection that really is gone receives nothing any more, so the three indicators are at zero and the reload happens as before. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_014M1jiEq9cHdE5SE5j6vFuE --- web/xynt-streaming.js | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/web/xynt-streaming.js b/web/xynt-streaming.js index b9ef124..f18cfba 100644 --- a/web/xynt-streaming.js +++ b/web/xynt-streaming.js @@ -866,11 +866,39 @@ xynt_streaming.prototype = { } if (this.keepalives_equal >= this.keepalives_eq_max) { - this.log("hs::watchdog: MAX ACHIEVED "+this.keepalives_equal); - this.reload(); - // alert("watchdog return reload"); - this.hbit_status(); - return; + /* The keepalive counter only moves forward when the client + manages to consume the incoming data. If it is stuck it can + mean two very different things: that nothing arrives any + more (the connection is gone) or that it does arrive but we + are late in processing it, for instance because the browser + is busy redrawing the list of a crowded room. + In the second case reloading the page throws the work away + for nothing, and the user gets the splash back. + So, before declaring it dead, we look at whether there is + still something left to consume. */ + var to_consume = 0; + try { + if (this.transp.ctx_new_is_set() && this.transp.ctx_old_len_is_set()) { + to_consume = this.transp.ctx_new_curlen_get() - this.transp.ctx_old_len_get(); + } + } + catch (b) { + to_consume = 0; + } + if (to_consume > 0 || this.gst.comms.length > 0 + || this.gst.st_loc < this.gst.st_loc_new) { + this.log("hs::watchdog: still to consume ("+to_consume + +" bytes, "+this.gst.comms.length + +" commands): the connection is alive, not reloading"); + this.keepalives_equal = 0; + } + else { + this.log("hs::watchdog: MAX ACHIEVED "+this.keepalives_equal); + this.reload(); + // alert("watchdog return reload"); + this.hbit_status(); + return; + } } } -- 2.47.3