@nelsonlongxiang/dsh-open-a2a-net 0.5.14 → 0.5.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +21 -2
- package/lib/types/index.d.ts +9 -0
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -38,6 +38,7 @@ export const Config = s.object({
|
|
|
38
38
|
dshHome: s.string().default(''),
|
|
39
39
|
sessionNodes: s.boolean().default(true),
|
|
40
40
|
wakeJoinedOnBoot: s.boolean().default(false),
|
|
41
|
+
wakeBootStaggerMs: s.number().default(3_000),
|
|
41
42
|
cardTtlMs: s.number().default(172_800_000),
|
|
42
43
|
flushTimeoutMs: s.number().default(300_000),
|
|
43
44
|
routeTimeoutMs: s.number().default(1_800_000),
|
|
@@ -464,13 +465,31 @@ export function apply(ctx, config) {
|
|
|
464
465
|
logger.warn('wakeJoinedOnBoot is on but no api gateway is composed; cold joined sessions stay asleep');
|
|
465
466
|
return;
|
|
466
467
|
}
|
|
468
|
+
// Serial with a configurable pause: one full log replay at a time
|
|
469
|
+
// keeps the decode from saturating the event loop (concurrent wakes
|
|
470
|
+
// of several huge logs stalled every request for tens of seconds).
|
|
471
|
+
// The first wake starts immediately; the re-check drops ids another
|
|
472
|
+
// path (wake-on-route, a manual open) already materialized.
|
|
473
|
+
let bootWakeChain = Promise.resolve();
|
|
474
|
+
let firstBootWake = true;
|
|
467
475
|
for (const id of joinedSessions.list()) {
|
|
468
476
|
if (liveRoots.has(id))
|
|
469
477
|
continue;
|
|
470
478
|
// The remount listener joins the node the moment the woken agent
|
|
471
479
|
// publishes; a failed wake keeps the cold row and its intent.
|
|
472
|
-
|
|
473
|
-
|
|
480
|
+
const pauseMs = firstBootWake ? 0 : config.wakeBootStaggerMs;
|
|
481
|
+
firstBootWake = false;
|
|
482
|
+
bootWakeChain = bootWakeChain.then(async () => {
|
|
483
|
+
if (pauseMs > 0)
|
|
484
|
+
await new Promise(resolve => setTimeout(resolve, pauseMs));
|
|
485
|
+
if (liveRoots.has(id))
|
|
486
|
+
return;
|
|
487
|
+
try {
|
|
488
|
+
await materialize(id);
|
|
489
|
+
}
|
|
490
|
+
catch (error) {
|
|
491
|
+
logger.warn(`boot wake of ${id} failed: ${String(error)}`);
|
|
492
|
+
}
|
|
474
493
|
});
|
|
475
494
|
}
|
|
476
495
|
};
|
package/lib/types/index.d.ts
CHANGED
|
@@ -89,6 +89,15 @@ export interface Config {
|
|
|
89
89
|
* the sidebar's wake button remain available).
|
|
90
90
|
*/
|
|
91
91
|
readonly wakeJoinedOnBoot: boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Pause between consecutive boot wakes. Each wake replays a full session
|
|
94
|
+
* log — the zstd decode yields the event loop only every 500ms — so
|
|
95
|
+
* unbounded concurrent wakes of several huge logs starve every request
|
|
96
|
+
* for tens of seconds after a restart. The serial queue with this pause
|
|
97
|
+
* keeps the preheat while capping decode saturation: the first wake
|
|
98
|
+
* starts immediately, and wake-on-route never waits on this queue.
|
|
99
|
+
*/
|
|
100
|
+
readonly wakeBootStaggerMs: number;
|
|
92
101
|
/**
|
|
93
102
|
* `final` reply budget: how long an inbound direct route waits for the
|
|
94
103
|
* session's next assistant message before answering with a timeout
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nelsonlongxiang/dsh-open-a2a-net",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.15",
|
|
4
4
|
"description": "Open A2A network plugin for DeepSeek Harness: signed agent cards, decentralized peer/zone discovery, direct routing model tools, and joinable session nodes with a sidebar control",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|