@adonis-agora/durable 0.55.0 → 0.56.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/CHANGELOG.md +39 -0
- package/dist/providers/dashboard_provider.d.ts +7 -2
- package/dist/providers/dashboard_provider.d.ts.map +1 -1
- package/dist/providers/dashboard_provider.js +34 -8
- package/dist/providers/dashboard_provider.js.map +1 -1
- package/dist/src/dashboard/define_config.d.ts +37 -5
- package/dist/src/dashboard/define_config.d.ts.map +1 -1
- package/dist/src/dashboard/define_config.js +19 -0
- package/dist/src/dashboard/define_config.js.map +1 -1
- package/dist/src/dashboard/index.d.ts +3 -3
- package/dist/src/dashboard/index.d.ts.map +1 -1
- package/dist/src/dashboard/index.js +2 -2
- package/dist/src/dashboard/index.js.map +1 -1
- package/dist/src/engine.d.ts.map +1 -1
- package/dist/src/engine.js +22 -13
- package/dist/src/engine.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/stores/lucid.d.ts +6 -0
- package/dist/src/stores/lucid.d.ts.map +1 -1
- package/dist/src/stores/lucid.js +48 -29
- package/dist/src/stores/lucid.js.map +1 -1
- package/dist/stubs/config/durable_dashboard.stub +3 -1
- package/package.json +1 -1
package/dist/src/engine.js
CHANGED
|
@@ -13,7 +13,7 @@ import { Entities } from './entities.js';
|
|
|
13
13
|
import { ContinueAsNew, GatherError, NonDeterminismError, RemoteStepTimeout, RemoteWorkflowTimeout, WorkflowSuspended, } from './errors.js';
|
|
14
14
|
import { EventAccumulators } from './event-accumulators.js';
|
|
15
15
|
import { eventMatches, eventMatchOf, eventPrefix } from './events.js';
|
|
16
|
-
import { childIdsOf, FOLDED_PREFIX, fanOfWaiter, parseStepFanGroup, stepFanGroup, } from './fan-join.js';
|
|
16
|
+
import { childIdsOf, FOLDED_PREFIX, fanOfWaiter, parentRunIdOf, parseStepFanGroup, stepFanGroup, } from './fan-join.js';
|
|
17
17
|
import { aggregateAnnouncements } from './handshake/announced.js';
|
|
18
18
|
import { buildWorkflowDirectory } from './handshake/directory.js';
|
|
19
19
|
import { isNonEmptyRunScope, TERMINAL_RUN_STATUSES } from './interfaces.js';
|
|
@@ -1396,8 +1396,7 @@ export class WorkflowEngine {
|
|
|
1396
1396
|
await registered.validateInput?.(parsed);
|
|
1397
1397
|
// Idempotent by run id: a redelivered trigger (at-least-once queues) or a scheduler re-tick for
|
|
1398
1398
|
// the same id is a no-op, returning the existing run's state instead of starting a duplicate.
|
|
1399
|
-
const
|
|
1400
|
-
if (prior) {
|
|
1399
|
+
const existing = async (prior) => {
|
|
1401
1400
|
// A PENDING prior still needs an executor: re-nudge the dispatcher so a redelivered trigger —
|
|
1402
1401
|
// or a continuation persisted pre-settle (see the ContinueAsNew handoff) picked up by a custom
|
|
1403
1402
|
// dispatcher — doesn't sit `pending` until the next poll. Idempotent: execution is leased, so
|
|
@@ -1409,6 +1408,15 @@ export class WorkflowEngine {
|
|
|
1409
1408
|
});
|
|
1410
1409
|
}
|
|
1411
1410
|
return { runId, status: prior.status, output: prior.output, error: prior.error };
|
|
1411
|
+
};
|
|
1412
|
+
// A quota or a singleton can reject a start, and must not reject one for a run that already
|
|
1413
|
+
// exists, so those workflows look the run up first. Any other start goes straight to the insert,
|
|
1414
|
+
// whose duplicate-id rejection finds the existing run below.
|
|
1415
|
+
const admits = registered.singleton || registered.concurrency || opts?.concurrency;
|
|
1416
|
+
if (admits) {
|
|
1417
|
+
const prior = await this.store.getRun(runId);
|
|
1418
|
+
if (prior)
|
|
1419
|
+
return existing(prior);
|
|
1412
1420
|
}
|
|
1413
1421
|
// Start-time concurrency quota (per-start override, else the workflow's): reject BEFORE creating
|
|
1414
1422
|
// anything when the key's in-flight runs already reach the limit. See {@link ConcurrencyQuota}.
|
|
@@ -1456,17 +1464,15 @@ export class WorkflowEngine {
|
|
|
1456
1464
|
await this.store.createRun(run);
|
|
1457
1465
|
}
|
|
1458
1466
|
catch (err) {
|
|
1459
|
-
//
|
|
1460
|
-
// `signalWithStart`s for one entity id)
|
|
1461
|
-
//
|
|
1462
|
-
//
|
|
1463
|
-
//
|
|
1464
|
-
//
|
|
1465
|
-
// store failure: rethrow it.
|
|
1467
|
+
// The run id exists: a redelivered trigger, or a start that lost the insert to a racing one
|
|
1468
|
+
// (two pods scheduler-ticking the same window, concurrent `signalWithStart`s for one entity id).
|
|
1469
|
+
// Converge on the existing run — re-read and report ITS state, exactly like the prior-run
|
|
1470
|
+
// branch — instead of surfacing a unique-constraint error (which would abort a scheduler tick,
|
|
1471
|
+
// or worse, lose the signal half of a signalWithStart). A re-read that finds nothing means the
|
|
1472
|
+
// throw was a real store failure: rethrow it.
|
|
1466
1473
|
const winner = await this.store.getRun(runId);
|
|
1467
|
-
if (winner)
|
|
1468
|
-
return
|
|
1469
|
-
}
|
|
1474
|
+
if (winner)
|
|
1475
|
+
return existing(winner);
|
|
1470
1476
|
throw err;
|
|
1471
1477
|
}
|
|
1472
1478
|
// The run is durably enqueued; a dispatcher (in-process by default) executes it — `start` does
|
|
@@ -3353,6 +3359,9 @@ export class WorkflowEngine {
|
|
|
3353
3359
|
await this.deliverSignal(waiter, completion);
|
|
3354
3360
|
return;
|
|
3355
3361
|
}
|
|
3362
|
+
// No waiter, and no parent that could consume a buffered copy (a root run): nothing to do.
|
|
3363
|
+
if (parentRunIdOf(token.slice(CHILD_TOKEN_PREFIX.length)) === undefined)
|
|
3364
|
+
return;
|
|
3356
3365
|
// No waiter: the parent may already have settled this child from its run row (see
|
|
3357
3366
|
// `markChildDelivered`); a buffered copy would then never be consumed.
|
|
3358
3367
|
const delivered = async () => childId !== undefined &&
|