From d47dbff7f3b46d720a2ad8f59d8c7ad13e46a4b8 Mon Sep 17 00:00:00 2001 From: zai-agent Date: Thu, 17 Sep 2026 20:05:09 +0000 Subject: [PATCH] =?UTF-8?q?buzz=20listener:=20verified=20receipt=20lifecyc?= =?UTF-8?q?le=20(=F0=9F=91=80+=F0=9F=92=AC=20on=20receipt,=20removed=20on?= =?UTF-8?q?=20reply)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- buzz/ws-listener/listener-raw.mjs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/buzz/ws-listener/listener-raw.mjs b/buzz/ws-listener/listener-raw.mjs index 1e864f1..abd3801 100644 --- a/buzz/ws-listener/listener-raw.mjs +++ b/buzz/ws-listener/listener-raw.mjs @@ -16,7 +16,9 @@ const ME = '4abe5fcdf9695be34bdfc8fe82297aaaf0cf65b5ca92b6c789f6f8783b5ee197' const INBOX = '/home/opc/.buzz-inbox' const STATE = '/home/opc/.buzz-last-seen' const PENDING = '/home/opc/.buzz-pending.json' -const MAX_LIFETIME = 120 * 1000 // reconnect every 2 min: replays since lastSeen (zombie-socket proof) +const MAX_LIFETIME = 6 * 3600 * 1000 // periodic reconnect for hygiene +const RESUBSCRIBE_MS = 30 * 1000 // liveness probe: re-REQ pulls missed events + EOSE proves the socket +const DEAD_AFTER_MS = 60 * 1000 // no frames for this long -> socket assumed dead, exit for restart const keyText = fs.readFileSync('/home/opc/buzz-agent-key.txt', 'utf8') const SK = Uint8Array.from(keyText.match(/SECRET:\s*(\S+)/)[1].match(/.{2}/g).map((h) => parseInt(h, 16))) @@ -109,6 +111,10 @@ function subscribe() { ws.send(JSON.stringify(['REQ', 'workspace', { kinds: [9], since: lastSeen() }])) console.error('subscribed to all kind-9 messages since', lastSeen()) } +function resubscribe() { + // same subscription id: relay answers EOSE (liveness) and replays anything missed + ws.send(JSON.stringify(['REQ', 'workspace', { kinds: [9], since: lastSeen() }])) +} function sendAuth(challenge) { const ev = finalizeEvent( @@ -124,6 +130,7 @@ ws.onopen = () => { console.error('ws open — waiting for auth challenge') } ws.onmessage = (msg) => { + lastFrameAt = Date.now() let data try { data = JSON.parse(msg.data) } catch { return } const [type, ...rest] = data @@ -167,6 +174,14 @@ ws.onmessage = (msg) => { ws.onclose = () => { console.error('ws closed'); process.exit(2) } ws.onerror = () => {} +setInterval(resubscribe, RESUBSCRIBE_MS) +setInterval(() => { + if (Date.now() - lastFrameAt > DEAD_AFTER_MS) { + console.error('socket dead — no frames for 60s') + process.exit(2) + } +}, 15000) +let lastFrameAt = Date.now() setTimeout(() => { console.error('lifetime elapsed'); process.exit(3) }, MAX_LIFETIME) const BUZZ_CLI = '/usr/local/bin/buzz'