@nowcrew/daemon 0.6.46 → 0.6.48
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.
|
@@ -4,6 +4,8 @@ export function createCompletionRetransmitter(options) {
|
|
|
4
4
|
const maxAttempts = options.maxAttempts ?? 20;
|
|
5
5
|
const maxAgeMs = options.maxAgeMs ?? 10 * 60 * 1_000;
|
|
6
6
|
const pending = new Map();
|
|
7
|
+
// This set suppresses duplicate exhaustion telemetry across reconnects. It must
|
|
8
|
+
// never gate journal replay: an unacknowledged completion remains deliverable.
|
|
7
9
|
const exhausted = new Set();
|
|
8
10
|
let active = false;
|
|
9
11
|
let stopped = false;
|
|
@@ -16,12 +18,14 @@ export function createCompletionRetransmitter(options) {
|
|
|
16
18
|
const expire = (entry, reason) => {
|
|
17
19
|
clear(entry);
|
|
18
20
|
pending.delete(entry.frame.executionId);
|
|
19
|
-
exhausted.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
if (!exhausted.has(entry.frame.executionId)) {
|
|
22
|
+
exhausted.add(entry.frame.executionId);
|
|
23
|
+
options.onRetryExhausted?.({
|
|
24
|
+
executionId: entry.frame.executionId,
|
|
25
|
+
attempts: entry.attempts,
|
|
26
|
+
reason,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
25
29
|
};
|
|
26
30
|
const ageRemainingMs = (entry) => maxAgeMs - (Date.now() - entry.startedAtMs);
|
|
27
31
|
function schedule(entry) {
|
|
@@ -74,7 +78,7 @@ export function createCompletionRetransmitter(options) {
|
|
|
74
78
|
}
|
|
75
79
|
return {
|
|
76
80
|
track(frame) {
|
|
77
|
-
if (stopped || pending.has(frame.executionId)
|
|
81
|
+
if (stopped || pending.has(frame.executionId))
|
|
78
82
|
return;
|
|
79
83
|
const entry = { frame, startedAtMs: Date.now(), attempts: 0, timer: null };
|
|
80
84
|
pending.set(frame.executionId, entry);
|
|
@@ -86,8 +86,10 @@ function reservation(prerequisite, acquire) {
|
|
|
86
86
|
granted = true;
|
|
87
87
|
return lease;
|
|
88
88
|
});
|
|
89
|
-
const
|
|
90
|
-
|
|
89
|
+
const ready = acquisition.then((lease) => {
|
|
90
|
+
if (lease === null)
|
|
91
|
+
throw new HostReservationCancelledError();
|
|
92
|
+
});
|
|
91
93
|
void ready.catch(() => undefined);
|
|
92
94
|
return {
|
|
93
95
|
ready,
|
package/dist/serve.js
CHANGED
|
@@ -571,9 +571,8 @@ export function serve(config, opts = {}) {
|
|
|
571
571
|
});
|
|
572
572
|
};
|
|
573
573
|
const cancellation = cancellationFor(spec.executionId);
|
|
574
|
-
const slotForReservation = (attemptReservation, queueEnteredAt) =>
|
|
575
|
-
|
|
576
|
-
ready: attemptReservation.ready.then(() => {
|
|
574
|
+
const slotForReservation = (attemptReservation, queueEnteredAt) => {
|
|
575
|
+
const ready = attemptReservation.ready.then(() => {
|
|
577
576
|
markExecutionTaskKeyActive();
|
|
578
577
|
attemptReservation.markPreparing();
|
|
579
578
|
concurrencyTelemetry.transition(executionConcurrencyIdentity, "preparing", {
|
|
@@ -597,8 +596,16 @@ export function serve(config, opts = {}) {
|
|
|
597
596
|
memory_prune_starting_total: snapshot.memoryPruneStartingTotal,
|
|
598
597
|
memory_prune_running_total: snapshot.memoryPruneRunningTotal,
|
|
599
598
|
});
|
|
600
|
-
})
|
|
601
|
-
|
|
599
|
+
});
|
|
600
|
+
// Cancellation can win while this derived promise is still queued. Keep the
|
|
601
|
+
// rejection observable to the runner while preventing an unhandled rejection
|
|
602
|
+
// when the runner has already stopped waiting for the slot.
|
|
603
|
+
void ready.catch(() => undefined);
|
|
604
|
+
return {
|
|
605
|
+
state: attemptReservation.state ?? (attemptReservation.isQueued() ? "queued" : "ready"),
|
|
606
|
+
ready,
|
|
607
|
+
};
|
|
608
|
+
};
|
|
602
609
|
const onRetry = async ({ attempt, reason, }) => {
|
|
603
610
|
if (stopped || cancellation.isRequested())
|
|
604
611
|
return undefined;
|