maxpool 1.5.51 → 1.5.52
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/package.json +1 -1
- package/src/server.js +17 -1
- package/src/sleep-guard.js +6 -1
package/package.json
CHANGED
package/src/server.js
CHANGED
|
@@ -60,6 +60,13 @@ const DEFAULT_QUEUE = {
|
|
|
60
60
|
maxWaitMs: 24 * 60 * 60 * 1000,
|
|
61
61
|
autoMaxWaitMs: null,
|
|
62
62
|
capacityMaxWaitMs: 15 * 60 * 1000,
|
|
63
|
+
// NETWORK-cause hold ceiling. A quota/capacity hold is worth waiting out — a reset is
|
|
64
|
+
// genuinely coming. A NETWORK hold is not: the connection is dead, and holding it just
|
|
65
|
+
// parks the caller on a socket nothing is watching. On 2026-07-28 a request was held
|
|
66
|
+
// 10,445s (2h54m) having produced ZERO bytes; nothing aborted it until the user touched
|
|
67
|
+
// the keyboard. Give up quickly instead and return a retryable 429, so the client
|
|
68
|
+
// reconnects on a FRESH connection — which is what actually self-heals a dead route.
|
|
69
|
+
networkMaxWaitMs: 2 * 60 * 1000,
|
|
63
70
|
weeklyMaxWaitMs: 24 * 60 * 60 * 1000, // legacy bound; streaming holds use streamHoldMaxMs
|
|
64
71
|
// STREAMING hold ceiling: how long a streaming request may be HELD ALIVE on
|
|
65
72
|
// the SSE heartbeat waiting for any account to free up. Defaults to 7d (the
|
|
@@ -1387,7 +1394,7 @@ function formatRetryDuration(seconds) {
|
|
|
1387
1394
|
function computeQueueWindowMs({
|
|
1388
1395
|
cause, stream, retryPlanCause,
|
|
1389
1396
|
maxWaitMs, capacityMaxWaitMs, nonStreamMaxWaitMs, streamHoldMaxMs, streamClientToleranceMs,
|
|
1390
|
-
isCountTokens, countTokensMaxWaitMs,
|
|
1397
|
+
isCountTokens, countTokensMaxWaitMs, networkMaxWaitMs,
|
|
1391
1398
|
}) {
|
|
1392
1399
|
let windowMs;
|
|
1393
1400
|
if (!stream) {
|
|
@@ -1408,6 +1415,11 @@ function computeQueueWindowMs({
|
|
|
1408
1415
|
// the upstream processing once acquired) so a non-heartbeated metadata call fast-
|
|
1409
1416
|
// fails with a retryable 429 instead of hanging past the client's idle window.
|
|
1410
1417
|
if (isCountTokens && countTokensMaxWaitMs != null) windowMs = Math.min(windowMs, countTokensMaxWaitMs);
|
|
1418
|
+
// A dead ROUTE is not a scheduled reset: holding it out is waiting for nothing. Cap it
|
|
1419
|
+
// hard, independent of how patient the client is — a raised CLAUDE_STREAM_IDLE_TIMEOUT_MS
|
|
1420
|
+
// (the `cc` alias sets 3h) otherwise licenses a multi-hour hold on a connection that is
|
|
1421
|
+
// simply gone. Error-fast + client reconnect beats an unattended hold.
|
|
1422
|
+
if (cause === 'network' && networkMaxWaitMs != null) windowMs = Math.min(windowMs, networkMaxWaitMs);
|
|
1411
1423
|
return windowMs;
|
|
1412
1424
|
}
|
|
1413
1425
|
|
|
@@ -1950,6 +1962,9 @@ async function queueAndRetry(
|
|
|
1950
1962
|
const streamClientToleranceMs = queueConfig.streamClientToleranceMs == null
|
|
1951
1963
|
? 3 * 60 * 60 * 1000
|
|
1952
1964
|
: Math.max(0, Number(queueConfig.streamClientToleranceMs) || 0);
|
|
1965
|
+
const networkMaxWaitMs = queueConfig.networkMaxWaitMs == null
|
|
1966
|
+
? 2 * 60 * 1000
|
|
1967
|
+
: Math.max(0, Number(queueConfig.networkMaxWaitMs) || 0);
|
|
1953
1968
|
const queueWindowMs = computeQueueWindowMs({
|
|
1954
1969
|
cause,
|
|
1955
1970
|
stream: Boolean(requestInfo.stream),
|
|
@@ -1957,6 +1972,7 @@ async function queueAndRetry(
|
|
|
1957
1972
|
maxWaitMs,
|
|
1958
1973
|
capacityMaxWaitMs,
|
|
1959
1974
|
nonStreamMaxWaitMs,
|
|
1975
|
+
networkMaxWaitMs,
|
|
1960
1976
|
streamHoldMaxMs,
|
|
1961
1977
|
streamClientToleranceMs,
|
|
1962
1978
|
isCountTokens: Boolean(requestInfo.isCountTokens),
|
package/src/sleep-guard.js
CHANGED
|
@@ -11,7 +11,12 @@
|
|
|
11
11
|
import { spawn as realSpawn } from 'node:child_process';
|
|
12
12
|
|
|
13
13
|
const POLL_MS = 5_000; // re-check the in-flight signal (idle-sleep timers are minutes)
|
|
14
|
-
|
|
14
|
+
// Stay awake this long after the last request. 60s lost a measured race on 2026-07-28: a
|
|
15
|
+
// network outage drained all in-flight work, the guard released exactly 74s later, and
|
|
16
|
+
// macOS (idle-sleep timer) slept in the SAME SECOND — so the machine went down while the
|
|
17
|
+
// outage was still in progress and recovery had to wait for a keystroke. 5 minutes bridges
|
|
18
|
+
// an outage-shaped gap without meaningfully delaying a genuinely idle sleep.
|
|
19
|
+
const GRACE_MS = 300_000;
|
|
15
20
|
|
|
16
21
|
export class SleepGuard {
|
|
17
22
|
constructor({ getWorkPending, log = () => {}, spawn = realSpawn, enabled, pollMs = POLL_MS, graceMs = GRACE_MS } = {}) {
|