@adonis-agora/durable 0.1.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/LICENSE +21 -0
- package/README.md +29 -0
- package/dist/assets/dashboard.html +446 -0
- package/dist/commands/main.d.ts +15 -0
- package/dist/commands/main.d.ts.map +1 -0
- package/dist/commands/main.js +15 -0
- package/dist/commands/main.js.map +1 -0
- package/dist/commands/retry.d.ts +16 -0
- package/dist/commands/retry.d.ts.map +1 -0
- package/dist/commands/retry.js +34 -0
- package/dist/commands/retry.js.map +1 -0
- package/dist/commands/runs.d.ts +17 -0
- package/dist/commands/runs.d.ts.map +1 -0
- package/dist/commands/runs.js +40 -0
- package/dist/commands/runs.js.map +1 -0
- package/dist/commands/work.d.ts +18 -0
- package/dist/commands/work.d.ts.map +1 -0
- package/dist/commands/work.js +58 -0
- package/dist/commands/work.js.map +1 -0
- package/dist/configure.d.ts +15 -0
- package/dist/configure.d.ts.map +1 -0
- package/dist/configure.js +26 -0
- package/dist/configure.js.map +1 -0
- package/dist/providers/dashboard_provider.d.ts +27 -0
- package/dist/providers/dashboard_provider.d.ts.map +1 -0
- package/dist/providers/dashboard_provider.js +94 -0
- package/dist/providers/dashboard_provider.js.map +1 -0
- package/dist/providers/durable_provider.d.ts +36 -0
- package/dist/providers/durable_provider.d.ts.map +1 -0
- package/dist/providers/durable_provider.js +113 -0
- package/dist/providers/durable_provider.js.map +1 -0
- package/dist/src/admission-redis/index.d.ts +2 -0
- package/dist/src/admission-redis/index.d.ts.map +1 -0
- package/dist/src/admission-redis/index.js +2 -0
- package/dist/src/admission-redis/index.js.map +1 -0
- package/dist/src/admission-redis/redis-admission-backend.d.ts +83 -0
- package/dist/src/admission-redis/redis-admission-backend.d.ts.map +1 -0
- package/dist/src/admission-redis/redis-admission-backend.js +200 -0
- package/dist/src/admission-redis/redis-admission-backend.js.map +1 -0
- package/dist/src/admission.d.ts +49 -0
- package/dist/src/admission.d.ts.map +1 -0
- package/dist/src/admission.js +30 -0
- package/dist/src/admission.js.map +1 -0
- package/dist/src/backoff.d.ts +5 -0
- package/dist/src/backoff.d.ts.map +1 -0
- package/dist/src/backoff.js +11 -0
- package/dist/src/backoff.js.map +1 -0
- package/dist/src/checkpoints.d.ts +42 -0
- package/dist/src/checkpoints.d.ts.map +1 -0
- package/dist/src/checkpoints.js +57 -0
- package/dist/src/checkpoints.js.map +1 -0
- package/dist/src/codec-state-store.d.ts +60 -0
- package/dist/src/codec-state-store.d.ts.map +1 -0
- package/dist/src/codec-state-store.js +129 -0
- package/dist/src/codec-state-store.js.map +1 -0
- package/dist/src/commands/index.d.ts +3 -0
- package/dist/src/commands/index.d.ts.map +1 -0
- package/dist/src/commands/index.js +3 -0
- package/dist/src/commands/index.js.map +1 -0
- package/dist/src/commands/runs.d.ts +24 -0
- package/dist/src/commands/runs.d.ts.map +1 -0
- package/dist/src/commands/runs.js +39 -0
- package/dist/src/commands/runs.js.map +1 -0
- package/dist/src/commands/worker.d.ts +61 -0
- package/dist/src/commands/worker.d.ts.map +1 -0
- package/dist/src/commands/worker.js +74 -0
- package/dist/src/commands/worker.js.map +1 -0
- package/dist/src/completion.d.ts +15 -0
- package/dist/src/completion.d.ts.map +1 -0
- package/dist/src/completion.js +10 -0
- package/dist/src/completion.js.map +1 -0
- package/dist/src/dashboard/define_config.d.ts +48 -0
- package/dist/src/dashboard/define_config.d.ts.map +1 -0
- package/dist/src/dashboard/define_config.js +57 -0
- package/dist/src/dashboard/define_config.js.map +1 -0
- package/dist/src/dashboard/handlers.d.ts +47 -0
- package/dist/src/dashboard/handlers.d.ts.map +1 -0
- package/dist/src/dashboard/handlers.js +163 -0
- package/dist/src/dashboard/handlers.js.map +1 -0
- package/dist/src/dashboard/html.d.ts +7 -0
- package/dist/src/dashboard/html.d.ts.map +1 -0
- package/dist/src/dashboard/html.js +24 -0
- package/dist/src/dashboard/html.js.map +1 -0
- package/dist/src/dashboard/index.d.ts +8 -0
- package/dist/src/dashboard/index.d.ts.map +1 -0
- package/dist/src/dashboard/index.js +6 -0
- package/dist/src/dashboard/index.js.map +1 -0
- package/dist/src/define_config.d.ts +72 -0
- package/dist/src/define_config.d.ts.map +1 -0
- package/dist/src/define_config.js +8 -0
- package/dist/src/define_config.js.map +1 -0
- package/dist/src/diagnostics-bridge.d.ts +22 -0
- package/dist/src/diagnostics-bridge.d.ts.map +1 -0
- package/dist/src/diagnostics-bridge.js +25 -0
- package/dist/src/diagnostics-bridge.js.map +1 -0
- package/dist/src/duration.d.ts +6 -0
- package/dist/src/duration.d.ts.map +1 -0
- package/dist/src/duration.js +39 -0
- package/dist/src/duration.js.map +1 -0
- package/dist/src/engine.d.ts +583 -0
- package/dist/src/engine.d.ts.map +1 -0
- package/dist/src/engine.js +1894 -0
- package/dist/src/engine.js.map +1 -0
- package/dist/src/entities.d.ts +44 -0
- package/dist/src/entities.d.ts.map +1 -0
- package/dist/src/entities.js +64 -0
- package/dist/src/entities.js.map +1 -0
- package/dist/src/errors.d.ts +68 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +102 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/event-accumulators.d.ts +39 -0
- package/dist/src/event-accumulators.d.ts.map +1 -0
- package/dist/src/event-accumulators.js +70 -0
- package/dist/src/event-accumulators.js.map +1 -0
- package/dist/src/events.d.ts +9 -0
- package/dist/src/events.d.ts.map +1 -0
- package/dist/src/events.js +35 -0
- package/dist/src/events.js.map +1 -0
- package/dist/src/index.d.ts +36 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +37 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/interfaces.d.ts +909 -0
- package/dist/src/interfaces.d.ts.map +1 -0
- package/dist/src/interfaces.js +2 -0
- package/dist/src/interfaces.js.map +1 -0
- package/dist/src/metrics.d.ts +44 -0
- package/dist/src/metrics.d.ts.map +1 -0
- package/dist/src/metrics.js +78 -0
- package/dist/src/metrics.js.map +1 -0
- package/dist/src/otel/durable-metrics.d.ts +42 -0
- package/dist/src/otel/durable-metrics.d.ts.map +1 -0
- package/dist/src/otel/durable-metrics.js +75 -0
- package/dist/src/otel/durable-metrics.js.map +1 -0
- package/dist/src/otel/durable-otel.d.ts +20 -0
- package/dist/src/otel/durable-otel.d.ts.map +1 -0
- package/dist/src/otel/durable-otel.js +74 -0
- package/dist/src/otel/durable-otel.js.map +1 -0
- package/dist/src/otel/index.d.ts +4 -0
- package/dist/src/otel/index.d.ts.map +1 -0
- package/dist/src/otel/index.js +4 -0
- package/dist/src/otel/index.js.map +1 -0
- package/dist/src/otel/traceparent.d.ts +17 -0
- package/dist/src/otel/traceparent.d.ts.map +1 -0
- package/dist/src/otel/traceparent.js +21 -0
- package/dist/src/otel/traceparent.js.map +1 -0
- package/dist/src/pollers.d.ts +33 -0
- package/dist/src/pollers.d.ts.map +1 -0
- package/dist/src/pollers.js +76 -0
- package/dist/src/pollers.js.map +1 -0
- package/dist/src/protocol.d.ts +17 -0
- package/dist/src/protocol.d.ts.map +1 -0
- package/dist/src/protocol.js +47 -0
- package/dist/src/protocol.js.map +1 -0
- package/dist/src/queue.d.ts +113 -0
- package/dist/src/queue.d.ts.map +1 -0
- package/dist/src/queue.js +128 -0
- package/dist/src/queue.js.map +1 -0
- package/dist/src/remote-step-factory.d.ts +15 -0
- package/dist/src/remote-step-factory.d.ts.map +1 -0
- package/dist/src/remote-step-factory.js +12 -0
- package/dist/src/remote-step-factory.js.map +1 -0
- package/dist/src/remote-workflow-executor.d.ts +24 -0
- package/dist/src/remote-workflow-executor.d.ts.map +1 -0
- package/dist/src/remote-workflow-executor.js +70 -0
- package/dist/src/remote-workflow-executor.js.map +1 -0
- package/dist/src/scheduler.d.ts +67 -0
- package/dist/src/scheduler.d.ts.map +1 -0
- package/dist/src/scheduler.js +111 -0
- package/dist/src/scheduler.js.map +1 -0
- package/dist/src/search-attributes.d.ts +48 -0
- package/dist/src/search-attributes.d.ts.map +1 -0
- package/dist/src/search-attributes.js +98 -0
- package/dist/src/search-attributes.js.map +1 -0
- package/dist/src/singleton-gate.d.ts +44 -0
- package/dist/src/singleton-gate.d.ts.map +1 -0
- package/dist/src/singleton-gate.js +90 -0
- package/dist/src/singleton-gate.js.map +1 -0
- package/dist/src/step-logger.d.ts +9 -0
- package/dist/src/step-logger.d.ts.map +1 -0
- package/dist/src/step-logger.js +89 -0
- package/dist/src/step-logger.js.map +1 -0
- package/dist/src/stores/factory.d.ts +42 -0
- package/dist/src/stores/factory.d.ts.map +1 -0
- package/dist/src/stores/factory.js +29 -0
- package/dist/src/stores/factory.js.map +1 -0
- package/dist/src/stores/lucid-helpers.d.ts +11 -0
- package/dist/src/stores/lucid-helpers.d.ts.map +1 -0
- package/dist/src/stores/lucid-helpers.js +38 -0
- package/dist/src/stores/lucid-helpers.js.map +1 -0
- package/dist/src/stores/lucid-mappers.d.ts +58 -0
- package/dist/src/stores/lucid-mappers.d.ts.map +1 -0
- package/dist/src/stores/lucid-mappers.js +174 -0
- package/dist/src/stores/lucid-mappers.js.map +1 -0
- package/dist/src/stores/lucid-schema.d.ts +28 -0
- package/dist/src/stores/lucid-schema.d.ts.map +1 -0
- package/dist/src/stores/lucid-schema.js +115 -0
- package/dist/src/stores/lucid-schema.js.map +1 -0
- package/dist/src/stores/lucid.d.ts +69 -0
- package/dist/src/stores/lucid.d.ts.map +1 -0
- package/dist/src/stores/lucid.js +342 -0
- package/dist/src/stores/lucid.js.map +1 -0
- package/dist/src/telescope/dashboard.d.ts +15 -0
- package/dist/src/telescope/dashboard.d.ts.map +1 -0
- package/dist/src/telescope/dashboard.js +113 -0
- package/dist/src/telescope/dashboard.js.map +1 -0
- package/dist/src/telescope/data-providers.d.ts +20 -0
- package/dist/src/telescope/data-providers.d.ts.map +1 -0
- package/dist/src/telescope/data-providers.js +322 -0
- package/dist/src/telescope/data-providers.js.map +1 -0
- package/dist/src/telescope/extension.d.ts +22 -0
- package/dist/src/telescope/extension.d.ts.map +1 -0
- package/dist/src/telescope/extension.js +38 -0
- package/dist/src/telescope/extension.js.map +1 -0
- package/dist/src/telescope/index.d.ts +5 -0
- package/dist/src/telescope/index.d.ts.map +1 -0
- package/dist/src/telescope/index.js +4 -0
- package/dist/src/telescope/index.js.map +1 -0
- package/dist/src/telescope/telescope-sdk.d.ts +123 -0
- package/dist/src/telescope/telescope-sdk.d.ts.map +1 -0
- package/dist/src/telescope/telescope-sdk.js +12 -0
- package/dist/src/telescope/telescope-sdk.js.map +1 -0
- package/dist/src/test-helpers.d.ts +11 -0
- package/dist/src/test-helpers.d.ts.map +1 -0
- package/dist/src/test-helpers.js +12 -0
- package/dist/src/test-helpers.js.map +1 -0
- package/dist/src/testing/in-memory-state-store.d.ts +64 -0
- package/dist/src/testing/in-memory-state-store.d.ts.map +1 -0
- package/dist/src/testing/in-memory-state-store.js +259 -0
- package/dist/src/testing/in-memory-state-store.js.map +1 -0
- package/dist/src/testing/in-memory-transport.d.ts +25 -0
- package/dist/src/testing/in-memory-transport.d.ts.map +1 -0
- package/dist/src/testing/in-memory-transport.js +49 -0
- package/dist/src/testing/in-memory-transport.js.map +1 -0
- package/dist/src/testing-kit/admission-backend-conformance.d.ts +18 -0
- package/dist/src/testing-kit/admission-backend-conformance.d.ts.map +1 -0
- package/dist/src/testing-kit/admission-backend-conformance.js +81 -0
- package/dist/src/testing-kit/admission-backend-conformance.js.map +1 -0
- package/dist/src/testing-kit/assertions.d.ts +10 -0
- package/dist/src/testing-kit/assertions.d.ts.map +1 -0
- package/dist/src/testing-kit/assertions.js +41 -0
- package/dist/src/testing-kit/assertions.js.map +1 -0
- package/dist/src/testing-kit/harness.d.ts +28 -0
- package/dist/src/testing-kit/harness.d.ts.map +1 -0
- package/dist/src/testing-kit/harness.js +42 -0
- package/dist/src/testing-kit/harness.js.map +1 -0
- package/dist/src/testing-kit/index.d.ts +8 -0
- package/dist/src/testing-kit/index.d.ts.map +1 -0
- package/dist/src/testing-kit/index.js +8 -0
- package/dist/src/testing-kit/index.js.map +1 -0
- package/dist/src/testing-kit/replay.d.ts +22 -0
- package/dist/src/testing-kit/replay.d.ts.map +1 -0
- package/dist/src/testing-kit/replay.js +38 -0
- package/dist/src/testing-kit/replay.js.map +1 -0
- package/dist/src/testing-kit/state-store-conformance.d.ts +51 -0
- package/dist/src/testing-kit/state-store-conformance.d.ts.map +1 -0
- package/dist/src/testing-kit/state-store-conformance.js +430 -0
- package/dist/src/testing-kit/state-store-conformance.js.map +1 -0
- package/dist/src/testing-kit/steps.d.ts +5 -0
- package/dist/src/testing-kit/steps.d.ts.map +1 -0
- package/dist/src/testing-kit/steps.js +15 -0
- package/dist/src/testing-kit/steps.js.map +1 -0
- package/dist/src/testing-kit/transport-conformance.d.ts +16 -0
- package/dist/src/testing-kit/transport-conformance.d.ts.map +1 -0
- package/dist/src/testing-kit/transport-conformance.js +64 -0
- package/dist/src/testing-kit/transport-conformance.js.map +1 -0
- package/dist/src/tokens.d.ts +18 -0
- package/dist/src/tokens.d.ts.map +1 -0
- package/dist/src/tokens.js +18 -0
- package/dist/src/tokens.js.map +1 -0
- package/dist/src/transport-pool.d.ts +30 -0
- package/dist/src/transport-pool.d.ts.map +1 -0
- package/dist/src/transport-pool.js +82 -0
- package/dist/src/transport-pool.js.map +1 -0
- package/dist/src/transports/db-helpers.d.ts +10 -0
- package/dist/src/transports/db-helpers.d.ts.map +1 -0
- package/dist/src/transports/db-helpers.js +33 -0
- package/dist/src/transports/db-helpers.js.map +1 -0
- package/dist/src/transports/db-schema.d.ts +28 -0
- package/dist/src/transports/db-schema.d.ts.map +1 -0
- package/dist/src/transports/db-schema.js +98 -0
- package/dist/src/transports/db-schema.js.map +1 -0
- package/dist/src/transports/db.d.ts +81 -0
- package/dist/src/transports/db.d.ts.map +1 -0
- package/dist/src/transports/db.js +340 -0
- package/dist/src/transports/db.js.map +1 -0
- package/dist/src/transports/factory.d.ts +79 -0
- package/dist/src/transports/factory.d.ts.map +1 -0
- package/dist/src/transports/factory.js +57 -0
- package/dist/src/transports/factory.js.map +1 -0
- package/dist/src/transports/queue-mock-adapter.d.ts +39 -0
- package/dist/src/transports/queue-mock-adapter.d.ts.map +1 -0
- package/dist/src/transports/queue-mock-adapter.js +86 -0
- package/dist/src/transports/queue-mock-adapter.js.map +1 -0
- package/dist/src/transports/queue.d.ts +84 -0
- package/dist/src/transports/queue.d.ts.map +1 -0
- package/dist/src/transports/queue.js +210 -0
- package/dist/src/transports/queue.js.map +1 -0
- package/dist/src/workflow-ctx.d.ts +64 -0
- package/dist/src/workflow-ctx.d.ts.map +1 -0
- package/dist/src/workflow-ctx.js +457 -0
- package/dist/src/workflow-ctx.js.map +1 -0
- package/dist/src/workflow-ref.d.ts +34 -0
- package/dist/src/workflow-ref.d.ts.map +1 -0
- package/dist/src/workflow-ref.js +28 -0
- package/dist/src/workflow-ref.js.map +1 -0
- package/dist/stubs/config/durable.stub +49 -0
- package/dist/stubs/config/durable_dashboard.stub +17 -0
- package/dist/stubs/database/migrations/create_durable_tables.stub +87 -0
- package/dist/stubs/database/migrations/create_durable_transport_tables.stub +75 -0
- package/dist/stubs/main.d.ts +3 -0
- package/dist/stubs/main.d.ts.map +1 -0
- package/dist/stubs/main.js +4 -0
- package/dist/stubs/main.js.map +1 -0
- package/package.json +154 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { BaseCommand } from '@adonisjs/core/ace';
|
|
2
|
+
import type { CommandOptions } from '@adonisjs/core/types/ace';
|
|
3
|
+
/**
|
|
4
|
+
* `node ace durable:work` — the long-running worker loop. Resolves the {@link WorkflowEngine} bound by
|
|
5
|
+
* `@adonis-agora/durable`'s provider, then on an interval picks up pending runs, recovers crashed runs,
|
|
6
|
+
* resumes due timers, sweeps execution timeouts, and fires any `schedules` configured in
|
|
7
|
+
* `config/durable.ts`. Stays alive until SIGINT/SIGTERM, then drains in-flight executions so a deploy
|
|
8
|
+
* hands off cleanly.
|
|
9
|
+
*/
|
|
10
|
+
export default class DurableWork extends BaseCommand {
|
|
11
|
+
static commandName: string;
|
|
12
|
+
static description: string;
|
|
13
|
+
static options: CommandOptions;
|
|
14
|
+
interval: number;
|
|
15
|
+
drainTimeout: number;
|
|
16
|
+
run(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=work.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"work.d.ts","sourceRoot":"","sources":["../../commands/work.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAS,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAK/D;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,WAAW;IAClD,OAAgB,WAAW,SAAkB;IAC7C,OAAgB,WAAW,SAC+D;IAC1F,OAAgB,OAAO,EAAE,cAAc,CAAwC;IAGvE,QAAQ,EAAE,MAAM,CAAC;IAGjB,YAAY,EAAE,MAAM,CAAC;IAEd,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAiCpC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { BaseCommand, flags } from '@adonisjs/core/ace';
|
|
8
|
+
import { runWorkerLoop } from '../src/commands/worker.js';
|
|
9
|
+
import { WorkflowEngine } from '../src/index.js';
|
|
10
|
+
/**
|
|
11
|
+
* `node ace durable:work` — the long-running worker loop. Resolves the {@link WorkflowEngine} bound by
|
|
12
|
+
* `@adonis-agora/durable`'s provider, then on an interval picks up pending runs, recovers crashed runs,
|
|
13
|
+
* resumes due timers, sweeps execution timeouts, and fires any `schedules` configured in
|
|
14
|
+
* `config/durable.ts`. Stays alive until SIGINT/SIGTERM, then drains in-flight executions so a deploy
|
|
15
|
+
* hands off cleanly.
|
|
16
|
+
*/
|
|
17
|
+
export default class DurableWork extends BaseCommand {
|
|
18
|
+
static commandName = 'durable:work';
|
|
19
|
+
static description = 'Run the durable workflow worker loop (pending, recovery, timers, timeouts, schedules)';
|
|
20
|
+
static options = { startApp: true, staysAlive: true };
|
|
21
|
+
async run() {
|
|
22
|
+
const engine = await this.app.container.make(WorkflowEngine);
|
|
23
|
+
// Recurring schedules registered in `config/durable.ts` — fired as the worker tick's 5th phase.
|
|
24
|
+
const config = this.app.config.get('durable', {});
|
|
25
|
+
const schedules = config.schedules ?? [];
|
|
26
|
+
// Resolve `stopSignal` once a termination signal arrives, so the loop finishes its current tick,
|
|
27
|
+
// drains, and exits cleanly instead of being hard-killed mid-run.
|
|
28
|
+
let stop;
|
|
29
|
+
const stopSignal = new Promise((resolve) => {
|
|
30
|
+
stop = resolve;
|
|
31
|
+
});
|
|
32
|
+
const onSignal = () => {
|
|
33
|
+
this.logger.info('shutdown signal received — stopping worker…');
|
|
34
|
+
stop();
|
|
35
|
+
};
|
|
36
|
+
process.once('SIGINT', onSignal);
|
|
37
|
+
process.once('SIGTERM', onSignal);
|
|
38
|
+
this.logger.info(`durable:work started (interval ${this.interval}ms)`);
|
|
39
|
+
await runWorkerLoop(engine, {
|
|
40
|
+
intervalMs: this.interval,
|
|
41
|
+
drainTimeoutMs: this.drainTimeout,
|
|
42
|
+
stopSignal,
|
|
43
|
+
schedules,
|
|
44
|
+
logger: { info: (m) => this.logger.info(m), error: (m) => this.logger.error(m) },
|
|
45
|
+
});
|
|
46
|
+
process.off('SIGINT', onSignal);
|
|
47
|
+
process.off('SIGTERM', onSignal);
|
|
48
|
+
// Let ace tear the staysAlive command down now that the loop has returned.
|
|
49
|
+
await this.terminate();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
__decorate([
|
|
53
|
+
flags.number({ description: 'Poll interval in milliseconds between ticks', default: 1000 })
|
|
54
|
+
], DurableWork.prototype, "interval", void 0);
|
|
55
|
+
__decorate([
|
|
56
|
+
flags.number({ description: 'Drain timeout in milliseconds on shutdown', default: 10_000 })
|
|
57
|
+
], DurableWork.prototype, "drainTimeout", void 0);
|
|
58
|
+
//# sourceMappingURL=work.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"work.js","sourceRoot":"","sources":["../../commands/work.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,WAAW;IAClD,MAAM,CAAU,WAAW,GAAG,cAAc,CAAC;IAC7C,MAAM,CAAU,WAAW,GACzB,uFAAuF,CAAC;IAC1F,MAAM,CAAU,OAAO,GAAmB,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IAQtE,KAAK,CAAC,GAAG;QAChB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC7D,gGAAgG;QAChG,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAgB,SAAS,EAAE,EAAE,CAAC,CAAC;QACjE,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC;QAEzC,iGAAiG;QACjG,kEAAkE;QAClE,IAAI,IAAiB,CAAC;QACtB,MAAM,UAAU,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAC/C,IAAI,GAAG,OAAO,CAAC;QACjB,CAAC,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,GAAS,EAAE;YAC1B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;YAChE,IAAI,EAAE,CAAC;QACT,CAAC,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAElC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,kCAAkC,IAAI,CAAC,QAAQ,KAAK,CAAC,CAAC;QACvE,MAAM,aAAa,CAAC,MAAM,EAAE;YAC1B,UAAU,EAAE,IAAI,CAAC,QAAQ;YACzB,cAAc,EAAE,IAAI,CAAC,YAAY;YACjC,UAAU;YACV,SAAS;YACT,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;SACjF,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACjC,2EAA2E;QAC3E,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;IACzB,CAAC;;AArCO;IADP,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,6CAA6C,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;6CACnE;AAGjB;IADP,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,2CAA2C,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;iDAC/D"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type Configure from '@adonisjs/core/commands/configure';
|
|
2
|
+
/**
|
|
3
|
+
* `node ace configure @adonis-agora/durable` — auto-wires the package:
|
|
4
|
+
*
|
|
5
|
+
* 1. registers the core service provider in `adonisrc.ts`;
|
|
6
|
+
* 2. registers the ace commands barrel (`durable:work`, `durable:runs`,
|
|
7
|
+
* `durable:retry`);
|
|
8
|
+
* 3. registers the optional dashboard provider;
|
|
9
|
+
* 4. publishes `config/durable.ts` + `config/durable_dashboard.ts`;
|
|
10
|
+
* 5. publishes the Lucid migrations for the optional `lucid` store and `db`
|
|
11
|
+
* transport drivers (run `node ace migration:run`, and delete the transport
|
|
12
|
+
* migration if you don't use the `db` transport).
|
|
13
|
+
*/
|
|
14
|
+
export declare function configure(command: Configure): Promise<void>;
|
|
15
|
+
//# sourceMappingURL=configure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../configure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,mCAAmC,CAAC;AAG/D;;;;;;;;;;;GAWG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,SAAS,iBAiBjD"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { stubsRoot } from './stubs/main.js';
|
|
2
|
+
/**
|
|
3
|
+
* `node ace configure @adonis-agora/durable` — auto-wires the package:
|
|
4
|
+
*
|
|
5
|
+
* 1. registers the core service provider in `adonisrc.ts`;
|
|
6
|
+
* 2. registers the ace commands barrel (`durable:work`, `durable:runs`,
|
|
7
|
+
* `durable:retry`);
|
|
8
|
+
* 3. registers the optional dashboard provider;
|
|
9
|
+
* 4. publishes `config/durable.ts` + `config/durable_dashboard.ts`;
|
|
10
|
+
* 5. publishes the Lucid migrations for the optional `lucid` store and `db`
|
|
11
|
+
* transport drivers (run `node ace migration:run`, and delete the transport
|
|
12
|
+
* migration if you don't use the `db` transport).
|
|
13
|
+
*/
|
|
14
|
+
export async function configure(command) {
|
|
15
|
+
const codemods = await command.createCodemods();
|
|
16
|
+
await codemods.updateRcFile((rcFile) => {
|
|
17
|
+
rcFile.addProvider('@adonis-agora/durable/durable_provider');
|
|
18
|
+
rcFile.addProvider('@adonis-agora/durable/dashboard_provider');
|
|
19
|
+
rcFile.addCommand('@adonis-agora/durable/commands');
|
|
20
|
+
});
|
|
21
|
+
await codemods.makeUsingStub(stubsRoot, 'config/durable.stub', {});
|
|
22
|
+
await codemods.makeUsingStub(stubsRoot, 'config/durable_dashboard.stub', {});
|
|
23
|
+
await codemods.makeUsingStub(stubsRoot, 'database/migrations/create_durable_tables.stub', {});
|
|
24
|
+
await codemods.makeUsingStub(stubsRoot, 'database/migrations/create_durable_transport_tables.stub', {});
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=configure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configure.js","sourceRoot":"","sources":["../configure.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAkB;IAChD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,cAAc,EAAE,CAAC;IAEhD,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAC,MAAM,EAAE,EAAE;QACrC,MAAM,CAAC,WAAW,CAAC,wCAAwC,CAAC,CAAC;QAC7D,MAAM,CAAC,WAAW,CAAC,0CAA0C,CAAC,CAAC;QAC/D,MAAM,CAAC,UAAU,CAAC,gCAAgC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,MAAM,QAAQ,CAAC,aAAa,CAAC,SAAS,EAAE,qBAAqB,EAAE,EAAE,CAAC,CAAC;IACnE,MAAM,QAAQ,CAAC,aAAa,CAAC,SAAS,EAAE,+BAA+B,EAAE,EAAE,CAAC,CAAC;IAC7E,MAAM,QAAQ,CAAC,aAAa,CAAC,SAAS,EAAE,gDAAgD,EAAE,EAAE,CAAC,CAAC;IAC9F,MAAM,QAAQ,CAAC,aAAa,CAC1B,SAAS,EACT,0DAA0D,EAC1D,EAAE,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ApplicationService } from '@adonisjs/core/types';
|
|
2
|
+
/**
|
|
3
|
+
* Mounts the durable dashboard into an AdonisJS app: a JSON API over the
|
|
4
|
+
* {@link WorkflowEngine}'s read surface, and a single self-contained HTML page
|
|
5
|
+
* that consumes it. All routes sit behind the configurable `authorize` guard from
|
|
6
|
+
* `config/durable_dashboard.ts`.
|
|
7
|
+
*
|
|
8
|
+
* Routes (relative to the configured `path`, default `/durable`):
|
|
9
|
+
* - `GET /` → the dashboard HTML
|
|
10
|
+
* - `GET /api/runs` → list runs (status/workflow/tag filters, paged)
|
|
11
|
+
* - `GET /api/runs/:id` → run detail (run + step timeline + children)
|
|
12
|
+
* - `POST /api/runs/:id/retry` → re-enqueue the run
|
|
13
|
+
* - `POST /api/runs/:id/cancel` → cancel the run
|
|
14
|
+
* - `GET /api/health` → worker-group health
|
|
15
|
+
*/
|
|
16
|
+
export default class DashboardProvider {
|
|
17
|
+
protected app: ApplicationService;
|
|
18
|
+
constructor(app: ApplicationService);
|
|
19
|
+
boot(): Promise<void>;
|
|
20
|
+
private registerRoutes;
|
|
21
|
+
/**
|
|
22
|
+
* Run the configured guard. On denial, replies `403` and returns `false` so
|
|
23
|
+
* the route handler short-circuits.
|
|
24
|
+
*/
|
|
25
|
+
private guard;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=dashboard_provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard_provider.d.ts","sourceRoot":"","sources":["../../providers/dashboard_provider.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAmB/D;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,OAAO,OAAO,iBAAiB;IACxB,SAAS,CAAC,GAAG,EAAE,kBAAkB;gBAAvB,GAAG,EAAE,kBAAkB;IAEvC,IAAI;IASV,OAAO,CAAC,cAAc;IA+CtB;;;OAGG;YACW,KAAK;CAQpB"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import router from '@adonisjs/core/services/router';
|
|
2
|
+
import { resolveConfig, } from '../src/dashboard/define_config.js';
|
|
3
|
+
import { cancelRun, getRun, health, listRuns, retryRun, } from '../src/dashboard/handlers.js';
|
|
4
|
+
import { renderDashboard } from '../src/dashboard/html.js';
|
|
5
|
+
import { WorkflowEngine } from '../src/index.js';
|
|
6
|
+
/**
|
|
7
|
+
* Mounts the durable dashboard into an AdonisJS app: a JSON API over the
|
|
8
|
+
* {@link WorkflowEngine}'s read surface, and a single self-contained HTML page
|
|
9
|
+
* that consumes it. All routes sit behind the configurable `authorize` guard from
|
|
10
|
+
* `config/durable_dashboard.ts`.
|
|
11
|
+
*
|
|
12
|
+
* Routes (relative to the configured `path`, default `/durable`):
|
|
13
|
+
* - `GET /` → the dashboard HTML
|
|
14
|
+
* - `GET /api/runs` → list runs (status/workflow/tag filters, paged)
|
|
15
|
+
* - `GET /api/runs/:id` → run detail (run + step timeline + children)
|
|
16
|
+
* - `POST /api/runs/:id/retry` → re-enqueue the run
|
|
17
|
+
* - `POST /api/runs/:id/cancel` → cancel the run
|
|
18
|
+
* - `GET /api/health` → worker-group health
|
|
19
|
+
*/
|
|
20
|
+
export default class DashboardProvider {
|
|
21
|
+
app;
|
|
22
|
+
constructor(app) {
|
|
23
|
+
this.app = app;
|
|
24
|
+
}
|
|
25
|
+
async boot() {
|
|
26
|
+
const config = resolveConfig(this.app.config.get('durable_dashboard', {}));
|
|
27
|
+
if (!config.enabled)
|
|
28
|
+
return;
|
|
29
|
+
this.registerRoutes(config);
|
|
30
|
+
}
|
|
31
|
+
registerRoutes(config) {
|
|
32
|
+
const apiBase = `${config.path}/api`;
|
|
33
|
+
// Resolve the engine lazily per request: the singleton is built by
|
|
34
|
+
// @adonis-agora/durable's provider, and runs/checkpoints are read through its own
|
|
35
|
+
// read API (listRuns / listCheckpoints), so the dashboard needs nothing else.
|
|
36
|
+
const deps = async () => {
|
|
37
|
+
const engine = await this.app.container.make(WorkflowEngine);
|
|
38
|
+
return { engine };
|
|
39
|
+
};
|
|
40
|
+
// The HTML page.
|
|
41
|
+
router
|
|
42
|
+
.get(config.path === '' ? '/' : config.path, async (ctx) => {
|
|
43
|
+
if (!(await this.guard(config, ctx)))
|
|
44
|
+
return;
|
|
45
|
+
ctx.response.header('content-type', 'text/html; charset=utf-8');
|
|
46
|
+
return ctx.response.send(renderDashboard(apiBase));
|
|
47
|
+
})
|
|
48
|
+
.as('durable_dashboard.index');
|
|
49
|
+
// JSON API.
|
|
50
|
+
const json = (handler) => {
|
|
51
|
+
return async (ctx) => {
|
|
52
|
+
if (!(await this.guard(config, ctx)))
|
|
53
|
+
return;
|
|
54
|
+
try {
|
|
55
|
+
const result = await handler(await deps(), toApiRequest(ctx));
|
|
56
|
+
return ctx.response.status(result.status).json(result.body);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
return ctx.response
|
|
60
|
+
.status(500)
|
|
61
|
+
.json({ error: error instanceof Error ? error.message : 'internal error' });
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
router.get(`${apiBase}/runs`, json(listRuns)).as('durable_dashboard.runs.index');
|
|
66
|
+
router.get(`${apiBase}/runs/:id`, json(getRun)).as('durable_dashboard.runs.show');
|
|
67
|
+
router.post(`${apiBase}/runs/:id/retry`, json(retryRun)).as('durable_dashboard.runs.retry');
|
|
68
|
+
router.post(`${apiBase}/runs/:id/cancel`, json(cancelRun)).as('durable_dashboard.runs.cancel');
|
|
69
|
+
router
|
|
70
|
+
.get(`${apiBase}/health`, json((d) => health(d)))
|
|
71
|
+
.as('durable_dashboard.health');
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Run the configured guard. On denial, replies `403` and returns `false` so
|
|
75
|
+
* the route handler short-circuits.
|
|
76
|
+
*/
|
|
77
|
+
async guard(config, ctx) {
|
|
78
|
+
const allowed = await config.authorize(ctx);
|
|
79
|
+
if (!allowed) {
|
|
80
|
+
ctx.response.status(403).json({ error: 'forbidden' });
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/** Adapt an AdonisJS `HttpContext` to the framework-light {@link ApiRequest}. */
|
|
87
|
+
function toApiRequest(ctx) {
|
|
88
|
+
return {
|
|
89
|
+
params: ctx.params,
|
|
90
|
+
query: ctx.request.qs(),
|
|
91
|
+
body: ctx.request.body(),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=dashboard_provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard_provider.js","sourceRoot":"","sources":["../../providers/dashboard_provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ApplicationService } from '@adonisjs/core/types';
|
|
2
|
+
/**
|
|
3
|
+
* Wires `@adonis-agora/durable` into the AdonisJS application: binds a singleton
|
|
4
|
+
* {@link WorkflowEngine} built from `config/durable.ts`.
|
|
5
|
+
*
|
|
6
|
+
* Defaults to an in-process store + transport (single-process, zero infra). Pick a `transport` /
|
|
7
|
+
* `store` by name from the config's `transports` / `stores` maps to run cross-process or persist
|
|
8
|
+
* durably; each selected driver's peer dependency is imported lazily inside its factory thunk, only
|
|
9
|
+
* when that driver is chosen. When `@adonis-agora/context` is installed, the originating
|
|
10
|
+
* tenant/user/correlation carrier is attached to each dispatched task (best-effort, read structurally
|
|
11
|
+
* from the global accessor slot — no hard dependency). When `@adonis-agora/diagnostics-otel` (and an OTel SDK
|
|
12
|
+
* such as `@adonisjs/otel`) is installed, each dispatched task is stamped with the active OTel
|
|
13
|
+
* `traceparent` so a worker continues the trace.
|
|
14
|
+
*
|
|
15
|
+
* ```ts
|
|
16
|
+
* const engine = await app.container.make(WorkflowEngine)
|
|
17
|
+
* engine.register('order', '1', async (ctx) => { ... })
|
|
18
|
+
* await engine.start('order', input, runId)
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export default class DurableProvider {
|
|
22
|
+
#private;
|
|
23
|
+
protected app: ApplicationService;
|
|
24
|
+
constructor(app: ApplicationService);
|
|
25
|
+
register(): void;
|
|
26
|
+
/**
|
|
27
|
+
* Once everything is booted, bridge engine lifecycle events onto the `@adonis-agora/diagnostics` bus —
|
|
28
|
+
* but only when diagnostics is actually installed (its emit slot is populated at module load).
|
|
29
|
+
* Gating on the slot avoids eagerly constructing the engine when diagnostics is absent; when it is
|
|
30
|
+
* present, this makes durable runs visible to `onDiagnostic`, Telescope, the relays and OTel with
|
|
31
|
+
* zero config. No hard dependency on `@adonis-agora/diagnostics`.
|
|
32
|
+
*/
|
|
33
|
+
ready(): Promise<void>;
|
|
34
|
+
shutdown(): Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=durable_provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"durable_provider.d.ts","sourceRoot":"","sources":["../../providers/durable_provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAgC/D;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,OAAO,OAAO,eAAe;;IAItB,SAAS,CAAC,GAAG,EAAE,kBAAkB;gBAAvB,GAAG,EAAE,kBAAkB;IAE7C,QAAQ;IAiER;;;;;;OAMG;IACG,KAAK;IAOL,QAAQ;CAOf"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { InMemoryStateStore, InMemoryTransport, WorkflowEngine, attachDurableDiagnostics, } from '../src/index.js';
|
|
2
|
+
const CONTEXT_ACCESSOR = Symbol.for('@agora/context:accessor');
|
|
3
|
+
/**
|
|
4
|
+
* Global slot `@adonis-agora/diagnostics-otel` publishes its `otelTraceparent` under: a
|
|
5
|
+
* `() => string | undefined` returning the active OTel span's W3C `traceparent`.
|
|
6
|
+
* Read structurally so durable continues the OpenTelemetry trace on remote steps
|
|
7
|
+
* with zero config when OTel is installed — and no hard dependency when it is not.
|
|
8
|
+
*/
|
|
9
|
+
const OTEL_TRACEPARENT = Symbol.for('@agora/otel:traceparent');
|
|
10
|
+
/** `@adonis-agora/diagnostics`'s emit capability slot (set at that package's module load when installed). */
|
|
11
|
+
const DIAGNOSTICS_EMIT = Symbol.for('@agora/diagnostics:emit');
|
|
12
|
+
/**
|
|
13
|
+
* Wires `@adonis-agora/durable` into the AdonisJS application: binds a singleton
|
|
14
|
+
* {@link WorkflowEngine} built from `config/durable.ts`.
|
|
15
|
+
*
|
|
16
|
+
* Defaults to an in-process store + transport (single-process, zero infra). Pick a `transport` /
|
|
17
|
+
* `store` by name from the config's `transports` / `stores` maps to run cross-process or persist
|
|
18
|
+
* durably; each selected driver's peer dependency is imported lazily inside its factory thunk, only
|
|
19
|
+
* when that driver is chosen. When `@adonis-agora/context` is installed, the originating
|
|
20
|
+
* tenant/user/correlation carrier is attached to each dispatched task (best-effort, read structurally
|
|
21
|
+
* from the global accessor slot — no hard dependency). When `@adonis-agora/diagnostics-otel` (and an OTel SDK
|
|
22
|
+
* such as `@adonisjs/otel`) is installed, each dispatched task is stamped with the active OTel
|
|
23
|
+
* `traceparent` so a worker continues the trace.
|
|
24
|
+
*
|
|
25
|
+
* ```ts
|
|
26
|
+
* const engine = await app.container.make(WorkflowEngine)
|
|
27
|
+
* engine.register('order', '1', async (ctx) => { ... })
|
|
28
|
+
* await engine.start('order', input, runId)
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export default class DurableProvider {
|
|
32
|
+
app;
|
|
33
|
+
#detachDiagnostics = null;
|
|
34
|
+
#transport = null;
|
|
35
|
+
constructor(app) {
|
|
36
|
+
this.app = app;
|
|
37
|
+
}
|
|
38
|
+
register() {
|
|
39
|
+
this.app.container.singleton(WorkflowEngine, async () => {
|
|
40
|
+
const config = this.app.config.get('durable', {});
|
|
41
|
+
const accessor = globalThis[CONTEXT_ACCESSOR];
|
|
42
|
+
const otelTraceparent = globalThis[OTEL_TRACEPARENT];
|
|
43
|
+
const ctx = { app: this.app };
|
|
44
|
+
const store = await this.#resolveStore(config, ctx);
|
|
45
|
+
const transport = await this.#resolveTransport(config, ctx);
|
|
46
|
+
// Hold the transport so `shutdown()` can release broker workers/connections cleanly.
|
|
47
|
+
this.#transport = transport;
|
|
48
|
+
const deps = {
|
|
49
|
+
store,
|
|
50
|
+
transport,
|
|
51
|
+
...(config.controlPlane ? { controlPlane: config.controlPlane } : {}),
|
|
52
|
+
...(config.leaseMs !== undefined ? { leaseMs: config.leaseMs } : {}),
|
|
53
|
+
...(config.instanceId ? { instanceId: config.instanceId } : {}),
|
|
54
|
+
...(config.maxRecoveryAttempts !== undefined
|
|
55
|
+
? { maxRecoveryAttempts: config.maxRecoveryAttempts }
|
|
56
|
+
: {}),
|
|
57
|
+
...(config.compensationRetries !== undefined
|
|
58
|
+
? { compensationRetries: config.compensationRetries }
|
|
59
|
+
: {}),
|
|
60
|
+
...(config.runDispatcher ? { runDispatcher: config.runDispatcher } : {}),
|
|
61
|
+
// Best-effort context propagation from @adonis-agora/context (no hard dep).
|
|
62
|
+
...(accessor ? { context: () => accessor.get() } : {}),
|
|
63
|
+
// Best-effort OTel trace continuation from @adonis-agora/diagnostics-otel (no hard dep).
|
|
64
|
+
...(otelTraceparent ? { traceparent: otelTraceparent } : {}),
|
|
65
|
+
};
|
|
66
|
+
return new WorkflowEngine(deps);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/** Resolve the configured state store (a key of `config.stores`), or the in-memory default. */
|
|
70
|
+
async #resolveStore(config, ctx) {
|
|
71
|
+
const name = config.store;
|
|
72
|
+
if (!name)
|
|
73
|
+
return new InMemoryStateStore();
|
|
74
|
+
const factory = config.stores?.[name];
|
|
75
|
+
if (!factory) {
|
|
76
|
+
throw new Error(`@agora/durable: config.store is "${name}", but config.stores.${name} is not defined`);
|
|
77
|
+
}
|
|
78
|
+
return factory(ctx);
|
|
79
|
+
}
|
|
80
|
+
/** Resolve the configured transport (a key of `config.transports`), or the in-memory default. */
|
|
81
|
+
async #resolveTransport(config, ctx) {
|
|
82
|
+
const name = config.transport;
|
|
83
|
+
if (!name)
|
|
84
|
+
return new InMemoryTransport();
|
|
85
|
+
const factory = config.transports?.[name];
|
|
86
|
+
if (!factory) {
|
|
87
|
+
throw new Error(`@agora/durable: config.transport is "${name}", but config.transports.${name} is not defined`);
|
|
88
|
+
}
|
|
89
|
+
return factory(ctx);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Once everything is booted, bridge engine lifecycle events onto the `@adonis-agora/diagnostics` bus —
|
|
93
|
+
* but only when diagnostics is actually installed (its emit slot is populated at module load).
|
|
94
|
+
* Gating on the slot avoids eagerly constructing the engine when diagnostics is absent; when it is
|
|
95
|
+
* present, this makes durable runs visible to `onDiagnostic`, Telescope, the relays and OTel with
|
|
96
|
+
* zero config. No hard dependency on `@adonis-agora/diagnostics`.
|
|
97
|
+
*/
|
|
98
|
+
async ready() {
|
|
99
|
+
const emit = globalThis[DIAGNOSTICS_EMIT];
|
|
100
|
+
if (typeof emit !== 'function')
|
|
101
|
+
return;
|
|
102
|
+
const engine = await this.app.container.make(WorkflowEngine);
|
|
103
|
+
this.#detachDiagnostics = attachDurableDiagnostics(engine);
|
|
104
|
+
}
|
|
105
|
+
async shutdown() {
|
|
106
|
+
this.#detachDiagnostics?.();
|
|
107
|
+
this.#detachDiagnostics = null;
|
|
108
|
+
// Release the transport's broker workers / queues / connections so a deploy hands off cleanly.
|
|
109
|
+
await this.#transport?.close?.();
|
|
110
|
+
this.#transport = null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=durable_provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"durable_provider.js","sourceRoot":"","sources":["../../providers/durable_provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/admission-redis/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,SAAS,GACf,MAAM,8BAA8B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/admission-redis/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,GAGtB,MAAM,8BAA8B,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { Admission, AdmissionBackend, AdmissionItem, QueueConfig } from '../index.js';
|
|
2
|
+
/**
|
|
3
|
+
* The minimal ioredis surface this backend needs. Both a raw `ioredis` instance and an
|
|
4
|
+
* `@adonisjs/redis` connection satisfy it, so we depend on the surface rather than a concrete type —
|
|
5
|
+
* keeping the peer coupling minimal and the backend testable. `duplicate()` must return a connection
|
|
6
|
+
* usable for pub/sub (only needed when {@link RedisAdmissionBackend.onFreed} is wired).
|
|
7
|
+
*/
|
|
8
|
+
export interface RedisLike {
|
|
9
|
+
defineCommand(name: string, definition: {
|
|
10
|
+
numberOfKeys: number;
|
|
11
|
+
lua: string;
|
|
12
|
+
}): void;
|
|
13
|
+
set(key: string, value: string, mode: 'PX', ttlMs: number): Promise<unknown>;
|
|
14
|
+
hdel(key: string, ...fields: string[]): Promise<unknown>;
|
|
15
|
+
publish(channel: string, message: string): Promise<unknown>;
|
|
16
|
+
subscribe(channel: string): Promise<unknown>;
|
|
17
|
+
on(event: 'message', listener: (channel: string, message: string) => void): unknown;
|
|
18
|
+
duplicate(): RedisLike;
|
|
19
|
+
disconnect(): void;
|
|
20
|
+
}
|
|
21
|
+
export interface RedisAdmissionOptions {
|
|
22
|
+
/** An ioredis instance or `@adonisjs/redis` connection. One connection is reused for every queue. */
|
|
23
|
+
connection: RedisLike;
|
|
24
|
+
/** Key prefix namespacing the admission keys. Defaults to `durable`. */
|
|
25
|
+
prefix?: string;
|
|
26
|
+
/** Stable id for this engine instance ("pod"). Defaults to a random uuid. */
|
|
27
|
+
instanceId?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Liveness TTL (ms) for THIS instance's heartbeat key. A held slot is reclaimed only once its
|
|
30
|
+
* owner's heartbeat lapses — so a live pod keeps its slot no matter how long the step runs, and a
|
|
31
|
+
* crashed pod's slots free within this window. Refreshed on a timer at a third of the TTL. Default 30s.
|
|
32
|
+
*/
|
|
33
|
+
instanceTtlMs?: number;
|
|
34
|
+
/**
|
|
35
|
+
* How long a blocked waiter's place is kept after its last `tryAdmit` (ms). A waiter re-registers on
|
|
36
|
+
* every retry, so a still-trying one never expires; one that gave up (run cancelled) is pruned after
|
|
37
|
+
* this, so it can't sit as a phantom best-waiter and deadlock the rest. Defaults to `retryMs * 3`.
|
|
38
|
+
*/
|
|
39
|
+
waiterTtlMs?: number;
|
|
40
|
+
/** Delay (ms) a blocked call is told to wait before re-trying admission. Default 1000. */
|
|
41
|
+
retryMs?: number;
|
|
42
|
+
/** Epoch-ms clock; injectable for tests. Defaults to `Date.now`. */
|
|
43
|
+
clock?: () => number;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* An {@link AdmissionBackend} whose state lives in Redis, so `concurrency` / `rateLimit` / priority +
|
|
47
|
+
* fairness ordering are enforced ACROSS every engine replica instead of per-process.
|
|
48
|
+
*
|
|
49
|
+
* - **Concurrency** is a hash of slot→owning-instance; a slot is reclaimed only when its owner's
|
|
50
|
+
* liveness heartbeat lapses, so a live pod holds its slot for the full step duration (no time-lease
|
|
51
|
+
* false purge) while a crashed pod's slots free within `instanceTtlMs`.
|
|
52
|
+
* - **Rate limit** is a fixed-window counter.
|
|
53
|
+
* - **Ordering** registers blocked callers and, when a slot frees, admits the rightful next under
|
|
54
|
+
* (priority desc → fairness round-robin by `key` → arrival FIFO/LIFO). Abandoned waiters are pruned
|
|
55
|
+
* so a cancelled run can't sit as a phantom best-waiter.
|
|
56
|
+
*
|
|
57
|
+
* Targets a single (non-cluster) Redis — the atomic Lua spans multiple keys.
|
|
58
|
+
*/
|
|
59
|
+
export declare class RedisAdmissionBackend implements AdmissionBackend {
|
|
60
|
+
private readonly redis;
|
|
61
|
+
private readonly prefix;
|
|
62
|
+
private readonly instanceId;
|
|
63
|
+
private readonly instanceTtlMs;
|
|
64
|
+
private readonly waiterTtlMs;
|
|
65
|
+
private readonly retryMs;
|
|
66
|
+
private readonly clock;
|
|
67
|
+
private readonly configs;
|
|
68
|
+
private readonly heartbeat;
|
|
69
|
+
private subscriber?;
|
|
70
|
+
constructor(options: RedisAdmissionOptions);
|
|
71
|
+
register(config: QueueConfig): void;
|
|
72
|
+
handles(queue: string): boolean;
|
|
73
|
+
tryAdmit(queue: string, item: AdmissionItem): Promise<Admission>;
|
|
74
|
+
release(queue: string, slotId: string): Promise<void>;
|
|
75
|
+
onFreed(handler: (queue: string) => void): void;
|
|
76
|
+
/** Stop the liveness heartbeat + subscriber (held slots lapse within `instanceTtlMs`). */
|
|
77
|
+
close(): Promise<void>;
|
|
78
|
+
private freedChannel;
|
|
79
|
+
private refreshLiveness;
|
|
80
|
+
private instPrefix;
|
|
81
|
+
private key;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=redis-admission-backend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis-admission-backend.d.ts","sourceRoot":"","sources":["../../../src/admission-redis/redis-admission-backend.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE3F;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACrF,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7E,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACzD,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5D,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC;IACpF,SAAS,IAAI,SAAS,CAAC;IACvB,UAAU,IAAI,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,qGAAqG;IACrG,UAAU,EAAE,SAAS,CAAC;IACtB,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0FAA0F;IAC1F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC;CACtB;AA4HD;;;;;;;;;;;;;GAaG;AACH,qBAAa,qBAAsB,YAAW,gBAAgB;IAC5D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAC1D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiC;IAC3D,OAAO,CAAC,UAAU,CAAC,CAAY;gBAEnB,OAAO,EAAE,qBAAqB;IAkB1C,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAInC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIzB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,SAAS,CAAC;IA8ChE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO3D,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAQ/C,0FAA0F;IACpF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5B,OAAO,CAAC,YAAY;YAIN,eAAe;IAI7B,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,GAAG;CAIZ"}
|