fix(fleet): worker_hello periodisch wiederholen (wie Satellit) — Box wird nach Diagnostic/Bridge-Neustart wieder sichtbar
Worker sendeten worker_hello nur EINMAL beim Connect. Startet das Diagnostic oder die Bridge NACH der Box neu, verpassen sie das hello (RVS spielt es nicht nach) und sehen nur noch worker_ping → die Box taucht nicht in der Compute- Flotte auf. Der Satellit ist genau deshalb zuverlaessig sichtbar: er wiederholt sat_hello periodisch. - alle vier Worker (f5tts/whisper/voxtral/llm-adapter): worker_hello wird jetzt zusaetzlich alle ~30s (jeder 3. Ping-Zyklus) wiederholt → ein neu gestartetes Diagnostic/Bridge lernt die Box innerhalb von 30s, ohne Box-Neustart. - diagnostic/server.js: Voice-Reconcile (f5tts) laeuft nur beim ERSTEN/erneuten Auftauchen der Box, nicht bei jedem 30s-hello-Resend (sonst Push/Pull-Dauerlauf). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1076,6 +1076,10 @@ function connectRVS(forcePlain) {
|
|||||||
const p = msg.payload || {};
|
const p = msg.payload || {};
|
||||||
if (p.instanceId) {
|
if (p.instanceId) {
|
||||||
const prev = workers.get(p.instanceId) || {};
|
const prev = workers.get(p.instanceId) || {};
|
||||||
|
// War die Box vor diesem hello schon frisch gesehen? worker_hello wird
|
||||||
|
// jetzt alle ~30s wiederholt — Reconcile nur beim ERSTEN/erneuten
|
||||||
|
// Auftauchen, nicht bei jedem Resend.
|
||||||
|
const wasFresh = prev.last_seen && (Date.now() - prev.last_seen < WORKER_OFFLINE_MS);
|
||||||
workers.set(p.instanceId, {
|
workers.set(p.instanceId, {
|
||||||
instanceId: p.instanceId, service: p.service || "",
|
instanceId: p.instanceId, service: p.service || "",
|
||||||
node: p.node || "", gpus: p.gpus || "", model: p.model || "",
|
node: p.node || "", gpus: p.gpus || "", model: p.model || "",
|
||||||
@@ -1083,8 +1087,8 @@ function connectRVS(forcePlain) {
|
|||||||
busy: !!prev.busy, last_seen: Date.now(),
|
busy: !!prev.busy, last_seen: Date.now(),
|
||||||
});
|
});
|
||||||
broadcastWorkers();
|
broadcastWorkers();
|
||||||
// Voice-Flotte: f5tts-Box gerade online → Stimmen abgleichen/provisionieren.
|
// Voice-Flotte: f5tts-Box NEU online → Stimmen abgleichen/provisionieren.
|
||||||
if ((p.service || "") === "f5tts") reconcileVoices(p.instanceId, p.voices);
|
if ((p.service || "") === "f5tts" && !wasFresh) reconcileVoices(p.instanceId, p.voices);
|
||||||
}
|
}
|
||||||
} else if (msg.type === "worker_ping") {
|
} else if (msg.type === "worker_ping") {
|
||||||
// Heartbeat eines Workers (traegt busy-Status).
|
// Heartbeat eines Workers (traegt busy-Status).
|
||||||
|
|||||||
+12
-6
@@ -842,17 +842,23 @@ async def _broadcast_status(ws, state: str, **extra) -> None:
|
|||||||
|
|
||||||
async def _worker_register(ws, *, model: str = "", busy_fn=None) -> None:
|
async def _worker_register(ws, *, model: str = "", busy_fn=None) -> None:
|
||||||
"""Meldet diesen Worker bei der aria-bridge an (worker_hello) und haelt die
|
"""Meldet diesen Worker bei der aria-bridge an (worker_hello) und haelt die
|
||||||
Flotten-Registry per periodischem worker_ping (mit busy-Status) frisch."""
|
Flotten-Registry per periodischem worker_ping frisch. worker_hello wird
|
||||||
|
zusaetzlich alle ~30s WIEDERHOLT (wie der Satellit sat_hello), damit auch ein
|
||||||
|
neu gestartetes Diagnostic/Bridge uns lernt — RVS spielt hellos nicht nach."""
|
||||||
|
def _hello():
|
||||||
|
return {"instanceId": INSTANCE_ID, "service": WORKER_SERVICE,
|
||||||
|
"node": NODE_NAME, "gpus": GPU_IDS, "model": model,
|
||||||
|
"voices": _local_voice_names()}
|
||||||
try:
|
try:
|
||||||
await _send(ws, "worker_hello", {
|
await _send(ws, "worker_hello", _hello())
|
||||||
"instanceId": INSTANCE_ID, "service": WORKER_SERVICE,
|
n = 0
|
||||||
"node": NODE_NAME, "gpus": GPU_IDS, "model": model,
|
|
||||||
"voices": _local_voice_names(), # fuer Voice-Provisioning-Reconciliation
|
|
||||||
})
|
|
||||||
while True:
|
while True:
|
||||||
await asyncio.sleep(WORKER_PING_INTERVAL_S)
|
await asyncio.sleep(WORKER_PING_INTERVAL_S)
|
||||||
|
n += 1
|
||||||
busy = bool(busy_fn()) if busy_fn else False
|
busy = bool(busy_fn()) if busy_fn else False
|
||||||
await _send(ws, "worker_ping", {"instanceId": INSTANCE_ID, "busy": busy})
|
await _send(ws, "worker_ping", {"instanceId": INSTANCE_ID, "busy": busy})
|
||||||
|
if n % 3 == 0:
|
||||||
|
await _send(ws, "worker_hello", _hello())
|
||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
raise
|
raise
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|||||||
@@ -260,10 +260,14 @@ async def _worker_register(ws) -> None:
|
|||||||
Flotten-Registry per periodischem worker_ping (mit busy-Status) frisch."""
|
Flotten-Registry per periodischem worker_ping (mit busy-Status) frisch."""
|
||||||
try:
|
try:
|
||||||
await _announce(ws)
|
await _announce(ws)
|
||||||
|
n = 0
|
||||||
while True:
|
while True:
|
||||||
await asyncio.sleep(WORKER_PING_INTERVAL_S)
|
await asyncio.sleep(WORKER_PING_INTERVAL_S)
|
||||||
|
n += 1
|
||||||
await _send(ws, "worker_ping",
|
await _send(ws, "worker_ping",
|
||||||
{"instanceId": INSTANCE_ID, "busy": _inflight > 0})
|
{"instanceId": INSTANCE_ID, "busy": _inflight > 0})
|
||||||
|
if n % 3 == 0: # ~30s worker_hello wiederholen (wie der Satellit) →
|
||||||
|
await _announce(ws) # auch neu gestartetes Diagnostic/Bridge lernt uns
|
||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
raise
|
raise
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|||||||
@@ -713,15 +713,19 @@ async def _broadcast_status(ws, state: str, **extra) -> None:
|
|||||||
async def _worker_register(ws, *, model: str = "", busy_fn=None) -> None:
|
async def _worker_register(ws, *, model: str = "", busy_fn=None) -> None:
|
||||||
"""Meldet diesen Worker bei der aria-bridge an (worker_hello) und haelt die
|
"""Meldet diesen Worker bei der aria-bridge an (worker_hello) und haelt die
|
||||||
Flotten-Registry per periodischem worker_ping (mit busy-Status) frisch."""
|
Flotten-Registry per periodischem worker_ping (mit busy-Status) frisch."""
|
||||||
|
def _hello():
|
||||||
|
return {"instanceId": INSTANCE_ID, "service": WORKER_SERVICE,
|
||||||
|
"node": NODE_NAME, "gpus": GPU_IDS, "model": model}
|
||||||
try:
|
try:
|
||||||
await _send(ws, "worker_hello", {
|
await _send(ws, "worker_hello", _hello())
|
||||||
"instanceId": INSTANCE_ID, "service": WORKER_SERVICE,
|
n = 0
|
||||||
"node": NODE_NAME, "gpus": GPU_IDS, "model": model,
|
|
||||||
})
|
|
||||||
while True:
|
while True:
|
||||||
await asyncio.sleep(WORKER_PING_INTERVAL_S)
|
await asyncio.sleep(WORKER_PING_INTERVAL_S)
|
||||||
|
n += 1
|
||||||
busy = bool(busy_fn()) if busy_fn else False
|
busy = bool(busy_fn()) if busy_fn else False
|
||||||
await _send(ws, "worker_ping", {"instanceId": INSTANCE_ID, "busy": busy})
|
await _send(ws, "worker_ping", {"instanceId": INSTANCE_ID, "busy": busy})
|
||||||
|
if n % 3 == 0: # ~30s worker_hello wiederholen (wie der Satellit)
|
||||||
|
await _send(ws, "worker_hello", _hello())
|
||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
raise
|
raise
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|||||||
+11
-5
@@ -837,16 +837,22 @@ async def _broadcast_status(ws, state: str, **extra) -> None:
|
|||||||
|
|
||||||
async def _worker_register(ws, *, model: str = "", busy_fn=None) -> None:
|
async def _worker_register(ws, *, model: str = "", busy_fn=None) -> None:
|
||||||
"""Meldet diesen Worker bei der aria-bridge an (worker_hello) und haelt die
|
"""Meldet diesen Worker bei der aria-bridge an (worker_hello) und haelt die
|
||||||
Flotten-Registry per periodischem worker_ping (mit busy-Status) frisch."""
|
Flotten-Registry per periodischem worker_ping frisch. worker_hello wird alle
|
||||||
|
~30s WIEDERHOLT (wie der Satellit), damit ein neu gestartetes Diagnostic/
|
||||||
|
Bridge uns lernt — RVS spielt hellos nicht nach."""
|
||||||
|
def _hello():
|
||||||
|
return {"instanceId": INSTANCE_ID, "service": WORKER_SERVICE,
|
||||||
|
"node": NODE_NAME, "gpus": GPU_IDS, "model": model}
|
||||||
try:
|
try:
|
||||||
await _send(ws, "worker_hello", {
|
await _send(ws, "worker_hello", _hello())
|
||||||
"instanceId": INSTANCE_ID, "service": WORKER_SERVICE,
|
n = 0
|
||||||
"node": NODE_NAME, "gpus": GPU_IDS, "model": model,
|
|
||||||
})
|
|
||||||
while True:
|
while True:
|
||||||
await asyncio.sleep(WORKER_PING_INTERVAL_S)
|
await asyncio.sleep(WORKER_PING_INTERVAL_S)
|
||||||
|
n += 1
|
||||||
busy = bool(busy_fn()) if busy_fn else False
|
busy = bool(busy_fn()) if busy_fn else False
|
||||||
await _send(ws, "worker_ping", {"instanceId": INSTANCE_ID, "busy": busy})
|
await _send(ws, "worker_ping", {"instanceId": INSTANCE_ID, "busy": busy})
|
||||||
|
if n % 3 == 0:
|
||||||
|
await _send(ws, "worker_hello", _hello())
|
||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
raise
|
raise
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|||||||
Reference in New Issue
Block a user