@dudousxd/nestjs-durable-core 0.74.0 → 0.75.0
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/dist/index.cjs +35 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +35 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2350,12 +2350,14 @@ var ScheduleClient = class {
|
|
|
2350
2350
|
const store = this.requireStore();
|
|
2351
2351
|
const started = [];
|
|
2352
2352
|
for (let round = 0; round < 50; round++) {
|
|
2353
|
+
if (this.host.isDraining?.()) break;
|
|
2353
2354
|
const due = await store.listSchedules({
|
|
2354
2355
|
dueBy: nowMs,
|
|
2355
2356
|
namespace: this.options.namespace,
|
|
2356
2357
|
limit: TICK_BATCH
|
|
2357
2358
|
});
|
|
2358
2359
|
for (const record of due) {
|
|
2360
|
+
if (this.host.isDraining?.()) return started;
|
|
2359
2361
|
const runId = await this.fire(record, nowMs);
|
|
2360
2362
|
if (runId) started.push(runId);
|
|
2361
2363
|
}
|
|
@@ -3868,6 +3870,8 @@ var WorkflowEngine = class {
|
|
|
3868
3870
|
/** Executions currently in flight, so a graceful shutdown can wait for them to settle. */
|
|
3869
3871
|
inflight = /* @__PURE__ */ new Set();
|
|
3870
3872
|
draining = false;
|
|
3873
|
+
/** Wait already spent on this shutdown before `drain()` (see `beginDrain`). */
|
|
3874
|
+
drainSpentMs = 0;
|
|
3871
3875
|
constructor(deps) {
|
|
3872
3876
|
this.store = deps.store;
|
|
3873
3877
|
this.pool = new TransportPool(deps.transports ?? (deps.transport ? [
|
|
@@ -3916,7 +3920,8 @@ var WorkflowEngine = class {
|
|
|
3916
3920
|
});
|
|
3917
3921
|
this.schedules = new ScheduleClient(this.store, {
|
|
3918
3922
|
start: /* @__PURE__ */ __name((workflow, input, runId, opts) => this.start(workflow, input, runId, opts), "start"),
|
|
3919
|
-
getRun: /* @__PURE__ */ __name((runId) => this.store.getRun(runId), "getRun")
|
|
3923
|
+
getRun: /* @__PURE__ */ __name((runId) => this.store.getRun(runId), "getRun"),
|
|
3924
|
+
isDraining: /* @__PURE__ */ __name(() => this.draining, "isDraining")
|
|
3920
3925
|
}, {
|
|
3921
3926
|
namespace: this.namespace,
|
|
3922
3927
|
clock: this.clock
|
|
@@ -4541,15 +4546,34 @@ var WorkflowEngine = class {
|
|
|
4541
4546
|
return p;
|
|
4542
4547
|
}
|
|
4543
4548
|
/**
|
|
4549
|
+
* Stop picking up new work without waiting: recovery, timer, schedule and timeout sweeps (and
|
|
4550
|
+
* their per-run lock loops) start nothing once this is called, and {@link runOne} returns null. A
|
|
4551
|
+
* poller calls it on its own shutdown so an in-flight sweep stops locking runs before it is awaited.
|
|
4552
|
+
*
|
|
4553
|
+
* `spentMs` is wait time ALREADY spent on this shutdown (the poller awaiting its in-flight sweep).
|
|
4554
|
+
* It is deducted from the budget of a later {@link drain}, so that wait plus the drain stay within
|
|
4555
|
+
* one `shutdownTimeoutMs`. Only time actually spent waiting is charged: time that merely passes
|
|
4556
|
+
* between this call and `drain()` (other hooks, the HTTP server closing) never is. Calls add up.
|
|
4557
|
+
*/
|
|
4558
|
+
beginDrain(spentMs = 0) {
|
|
4559
|
+
this.draining = true;
|
|
4560
|
+
this.drainSpentMs += Math.max(0, spentMs);
|
|
4561
|
+
}
|
|
4562
|
+
/**
|
|
4544
4563
|
* Graceful shutdown: stop picking up new runs (recovery/timer become no-ops) and wait for
|
|
4545
4564
|
* in-flight executions to settle, up to `timeoutMs`. Call from your app's shutdown hook so a
|
|
4546
4565
|
* deploy hands off cleanly instead of leaving runs to the lease timeout.
|
|
4566
|
+
*
|
|
4567
|
+
* `timeoutMs` is the total budget for waiting on in-flight runs; any wait already reported through
|
|
4568
|
+
* {@link beginDrain} (`spentMs`) is deducted, so a shutdown that already waited on the timer poll
|
|
4569
|
+
* for part of it waits only for the remainder. With nothing reported, the full `timeoutMs` applies.
|
|
4547
4570
|
*/
|
|
4548
4571
|
async drain(timeoutMs = 1e4) {
|
|
4549
|
-
this.
|
|
4572
|
+
this.beginDrain();
|
|
4573
|
+
const budget = Math.max(0, timeoutMs - this.drainSpentMs);
|
|
4550
4574
|
if (this.inflight.size === 0) return;
|
|
4551
4575
|
const timer = new Promise((resolve) => {
|
|
4552
|
-
const t = setTimeout(resolve,
|
|
4576
|
+
const t = setTimeout(resolve, budget);
|
|
4553
4577
|
t.unref?.();
|
|
4554
4578
|
});
|
|
4555
4579
|
await Promise.race([
|
|
@@ -4591,6 +4615,7 @@ var WorkflowEngine = class {
|
|
|
4591
4615
|
*/
|
|
4592
4616
|
async sweepTimeouts(now = this.clock()) {
|
|
4593
4617
|
for (const reg of new Set(this.latest.values())) {
|
|
4618
|
+
if (this.draining) return;
|
|
4594
4619
|
if (reg.executionTimeoutMs == null) continue;
|
|
4595
4620
|
const deadline = now - reg.executionTimeoutMs;
|
|
4596
4621
|
const inflight = [
|
|
@@ -4606,6 +4631,7 @@ var WorkflowEngine = class {
|
|
|
4606
4631
|
})
|
|
4607
4632
|
];
|
|
4608
4633
|
for (const run of inflight) {
|
|
4634
|
+
if (this.draining) return;
|
|
4609
4635
|
if (run.createdAt.getTime() > deadline) continue;
|
|
4610
4636
|
const error2 = {
|
|
4611
4637
|
message: "execution timeout",
|
|
@@ -4635,6 +4661,7 @@ var WorkflowEngine = class {
|
|
|
4635
4661
|
if (this.draining) return [];
|
|
4636
4662
|
const results = [];
|
|
4637
4663
|
for (const listed of await this.store.listIncompleteRuns(this.namespace)) {
|
|
4664
|
+
if (this.draining) break;
|
|
4638
4665
|
const acquired = await this.store.tryLockRun(listed.id, this.instanceId, nowMs + this.leaseMs, nowMs);
|
|
4639
4666
|
if (!acquired) continue;
|
|
4640
4667
|
const run = await this.store.getRun(listed.id);
|
|
@@ -5070,8 +5097,13 @@ var WorkflowEngine = class {
|
|
|
5070
5097
|
if (this.draining) return [];
|
|
5071
5098
|
const results = [];
|
|
5072
5099
|
for (const run of runs) {
|
|
5100
|
+
if (this.draining) break;
|
|
5073
5101
|
const acquired = await this.store.tryLockRun(run.id, this.instanceId, nowMs + this.leaseMs, nowMs);
|
|
5074
5102
|
if (!acquired) continue;
|
|
5103
|
+
if (this.draining) {
|
|
5104
|
+
await this.store.releaseRunLock(run.id);
|
|
5105
|
+
break;
|
|
5106
|
+
}
|
|
5075
5107
|
try {
|
|
5076
5108
|
const settled = onLocked ? await onLocked(run) : void 0;
|
|
5077
5109
|
results.push(settled ?? await this.resumeImplicit(run.id));
|