adispatchd 0.0.0-stage → 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 +195 -2
- package/dist/api/errors.d.ts +27 -0
- package/dist/api/errors.js +80 -0
- package/dist/api/errors.js.map +1 -0
- package/dist/api/index.d.ts +10 -0
- package/dist/api/index.js +11 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/logs.d.ts +30 -0
- package/dist/api/logs.js +88 -0
- package/dist/api/logs.js.map +1 -0
- package/dist/api/serialize.d.ts +65 -0
- package/dist/api/serialize.js +135 -0
- package/dist/api/serialize.js.map +1 -0
- package/dist/api/server.d.ts +89 -0
- package/dist/api/server.js +751 -0
- package/dist/api/server.js.map +1 -0
- package/dist/api/sse.d.ts +90 -0
- package/dist/api/sse.js +225 -0
- package/dist/api/sse.js.map +1 -0
- package/dist/app.d.ts +173 -0
- package/dist/app.js +488 -0
- package/dist/app.js.map +1 -0
- package/dist/cli/config-validate.d.ts +6 -0
- package/dist/cli/config-validate.js +39 -0
- package/dist/cli/config-validate.js.map +1 -0
- package/dist/cli/control.d.ts +31 -0
- package/dist/cli/control.js +186 -0
- package/dist/cli/control.js.map +1 -0
- package/dist/cli/http-client.d.ts +57 -0
- package/dist/cli/http-client.js +174 -0
- package/dist/cli/http-client.js.map +1 -0
- package/dist/cli/index.d.ts +14 -0
- package/dist/cli/index.js +14 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init-templates.d.ts +20 -0
- package/dist/cli/init-templates.js +275 -0
- package/dist/cli/init-templates.js.map +1 -0
- package/dist/cli/init.d.ts +16 -0
- package/dist/cli/init.js +107 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/main.d.ts +2 -0
- package/dist/cli/main.js +25 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/program.d.ts +102 -0
- package/dist/cli/program.js +133 -0
- package/dist/cli/program.js.map +1 -0
- package/dist/cli/service.d.ts +27 -0
- package/dist/cli/service.js +252 -0
- package/dist/cli/service.js.map +1 -0
- package/dist/cli/start.d.ts +22 -0
- package/dist/cli/start.js +133 -0
- package/dist/cli/start.js.map +1 -0
- package/dist/cli/workflow-dry-run.d.ts +13 -0
- package/dist/cli/workflow-dry-run.js +144 -0
- package/dist/cli/workflow-dry-run.js.map +1 -0
- package/dist/config/field-catalog.d.ts +33 -0
- package/dist/config/field-catalog.js +172 -0
- package/dist/config/field-catalog.js.map +1 -0
- package/dist/config/filter-schema.d.ts +15 -0
- package/dist/config/filter-schema.js +110 -0
- package/dist/config/filter-schema.js.map +1 -0
- package/dist/config/index.d.ts +15 -0
- package/dist/config/index.js +16 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/issues.d.ts +27 -0
- package/dist/config/issues.js +37 -0
- package/dist/config/issues.js.map +1 -0
- package/dist/config/loader.d.ts +32 -0
- package/dist/config/loader.js +250 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/manager.d.ts +153 -0
- package/dist/config/manager.js +276 -0
- package/dist/config/manager.js.map +1 -0
- package/dist/config/model.d.ts +334 -0
- package/dist/config/model.js +2 -0
- package/dist/config/model.js.map +1 -0
- package/dist/config/normalize.d.ts +20 -0
- package/dist/config/normalize.js +200 -0
- package/dist/config/normalize.js.map +1 -0
- package/dist/config/parameters.d.ts +37 -0
- package/dist/config/parameters.js +71 -0
- package/dist/config/parameters.js.map +1 -0
- package/dist/config/public.d.ts +6 -0
- package/dist/config/public.js +18 -0
- package/dist/config/public.js.map +1 -0
- package/dist/config/schemas.d.ts +538 -0
- package/dist/config/schemas.js +321 -0
- package/dist/config/schemas.js.map +1 -0
- package/dist/config/snapshot.d.ts +38 -0
- package/dist/config/snapshot.js +57 -0
- package/dist/config/snapshot.js.map +1 -0
- package/dist/config/validate.d.ts +33 -0
- package/dist/config/validate.js +346 -0
- package/dist/config/validate.js.map +1 -0
- package/dist/core/clock.d.ts +59 -0
- package/dist/core/clock.js +133 -0
- package/dist/core/clock.js.map +1 -0
- package/dist/core/duration.d.ts +19 -0
- package/dist/core/duration.js +93 -0
- package/dist/core/duration.js.map +1 -0
- package/dist/core/errors.d.ts +62 -0
- package/dist/core/errors.js +72 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/ids.d.ts +57 -0
- package/dist/core/ids.js +88 -0
- package/dist/core/ids.js.map +1 -0
- package/dist/core/index.d.ts +13 -0
- package/dist/core/index.js +14 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/logger.d.ts +100 -0
- package/dist/core/logger.js +207 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/paths.d.ts +84 -0
- package/dist/core/paths.js +138 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/template.d.ts +136 -0
- package/dist/core/template.js +261 -0
- package/dist/core/template.js.map +1 -0
- package/dist/core/types.d.ts +544 -0
- package/dist/core/types.js +172 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/worker-protocol.d.ts +102 -0
- package/dist/core/worker-protocol.js +75 -0
- package/dist/core/worker-protocol.js.map +1 -0
- package/dist/executors/classify.d.ts +25 -0
- package/dist/executors/classify.js +54 -0
- package/dist/executors/classify.js.map +1 -0
- package/dist/executors/dispatcher.d.ts +35 -0
- package/dist/executors/dispatcher.js +68 -0
- package/dist/executors/dispatcher.js.map +1 -0
- package/dist/executors/env.d.ts +43 -0
- package/dist/executors/env.js +66 -0
- package/dist/executors/env.js.map +1 -0
- package/dist/executors/event-parser.d.ts +41 -0
- package/dist/executors/event-parser.js +106 -0
- package/dist/executors/event-parser.js.map +1 -0
- package/dist/executors/index.d.ts +12 -0
- package/dist/executors/index.js +13 -0
- package/dist/executors/index.js.map +1 -0
- package/dist/executors/log-capture.d.ts +57 -0
- package/dist/executors/log-capture.js +155 -0
- package/dist/executors/log-capture.js.map +1 -0
- package/dist/executors/process-identity.d.ts +124 -0
- package/dist/executors/process-identity.js +283 -0
- package/dist/executors/process-identity.js.map +1 -0
- package/dist/executors/shell-executor.d.ts +35 -0
- package/dist/executors/shell-executor.js +478 -0
- package/dist/executors/shell-executor.js.map +1 -0
- package/dist/executors/stream-redactor.d.ts +40 -0
- package/dist/executors/stream-redactor.js +89 -0
- package/dist/executors/stream-redactor.js.map +1 -0
- package/dist/executors/workspace.d.ts +10 -0
- package/dist/executors/workspace.js +47 -0
- package/dist/executors/workspace.js.map +1 -0
- package/dist/filters/evaluate.d.ts +77 -0
- package/dist/filters/evaluate.js +187 -0
- package/dist/filters/evaluate.js.map +1 -0
- package/dist/filters/fields.d.ts +35 -0
- package/dist/filters/fields.js +75 -0
- package/dist/filters/fields.js.map +1 -0
- package/dist/filters/index.d.ts +11 -0
- package/dist/filters/index.js +12 -0
- package/dist/filters/index.js.map +1 -0
- package/dist/filters/iso-date.d.ts +10 -0
- package/dist/filters/iso-date.js +42 -0
- package/dist/filters/iso-date.js.map +1 -0
- package/dist/filters/predicate.d.ts +24 -0
- package/dist/filters/predicate.js +178 -0
- package/dist/filters/predicate.js.map +1 -0
- package/dist/filters/priority.d.ts +51 -0
- package/dist/filters/priority.js +91 -0
- package/dist/filters/priority.js.map +1 -0
- package/dist/filters/pushdown.d.ts +12 -0
- package/dist/filters/pushdown.js +52 -0
- package/dist/filters/pushdown.js.map +1 -0
- package/dist/filters/shell-check.d.ts +110 -0
- package/dist/filters/shell-check.js +304 -0
- package/dist/filters/shell-check.js.map +1 -0
- package/dist/identities/github-app.d.ts +55 -0
- package/dist/identities/github-app.js +160 -0
- package/dist/identities/github-app.js.map +1 -0
- package/dist/identities/index.d.ts +6 -0
- package/dist/identities/index.js +7 -0
- package/dist/identities/index.js.map +1 -0
- package/dist/identities/jwt.d.ts +24 -0
- package/dist/identities/jwt.js +56 -0
- package/dist/identities/jwt.js.map +1 -0
- package/dist/lifecycle/context.d.ts +106 -0
- package/dist/lifecycle/context.js +170 -0
- package/dist/lifecycle/context.js.map +1 -0
- package/dist/lifecycle/engine.d.ts +185 -0
- package/dist/lifecycle/engine.js +551 -0
- package/dist/lifecycle/engine.js.map +1 -0
- package/dist/lifecycle/errors.d.ts +48 -0
- package/dist/lifecycle/errors.js +71 -0
- package/dist/lifecycle/errors.js.map +1 -0
- package/dist/lifecycle/index.d.ts +9 -0
- package/dist/lifecycle/index.js +9 -0
- package/dist/lifecycle/index.js.map +1 -0
- package/dist/lifecycle/performers.d.ts +66 -0
- package/dist/lifecycle/performers.js +179 -0
- package/dist/lifecycle/performers.js.map +1 -0
- package/dist/notifications/index.d.ts +6 -0
- package/dist/notifications/index.js +7 -0
- package/dist/notifications/index.js.map +1 -0
- package/dist/notifications/service.d.ts +115 -0
- package/dist/notifications/service.js +364 -0
- package/dist/notifications/service.js.map +1 -0
- package/dist/persistence/actions.d.ts +101 -0
- package/dist/persistence/actions.js +196 -0
- package/dist/persistence/actions.js.map +1 -0
- package/dist/persistence/blocks.d.ts +85 -0
- package/dist/persistence/blocks.js +140 -0
- package/dist/persistence/blocks.js.map +1 -0
- package/dist/persistence/cron-firings.d.ts +55 -0
- package/dist/persistence/cron-firings.js +70 -0
- package/dist/persistence/cron-firings.js.map +1 -0
- package/dist/persistence/database.d.ts +60 -0
- package/dist/persistence/database.js +124 -0
- package/dist/persistence/database.js.map +1 -0
- package/dist/persistence/errors.d.ts +39 -0
- package/dist/persistence/errors.js +67 -0
- package/dist/persistence/errors.js.map +1 -0
- package/dist/persistence/events.d.ts +72 -0
- package/dist/persistence/events.js +83 -0
- package/dist/persistence/events.js.map +1 -0
- package/dist/persistence/index.d.ts +18 -0
- package/dist/persistence/index.js +19 -0
- package/dist/persistence/index.js.map +1 -0
- package/dist/persistence/instance-lock.d.ts +26 -0
- package/dist/persistence/instance-lock.js +117 -0
- package/dist/persistence/instance-lock.js.map +1 -0
- package/dist/persistence/lock-keys.d.ts +16 -0
- package/dist/persistence/lock-keys.js +41 -0
- package/dist/persistence/lock-keys.js.map +1 -0
- package/dist/persistence/notifications.d.ts +113 -0
- package/dist/persistence/notifications.js +213 -0
- package/dist/persistence/notifications.js.map +1 -0
- package/dist/persistence/persistence.d.ts +46 -0
- package/dist/persistence/persistence.js +42 -0
- package/dist/persistence/persistence.js.map +1 -0
- package/dist/persistence/retention.d.ts +46 -0
- package/dist/persistence/retention.js +68 -0
- package/dist/persistence/retention.js.map +1 -0
- package/dist/persistence/runs.d.ts +215 -0
- package/dist/persistence/runs.js +417 -0
- package/dist/persistence/runs.js.map +1 -0
- package/dist/persistence/schema.d.ts +16 -0
- package/dist/persistence/schema.js +183 -0
- package/dist/persistence/schema.js.map +1 -0
- package/dist/persistence/sqlite.d.ts +49 -0
- package/dist/persistence/sqlite.js +131 -0
- package/dist/persistence/sqlite.js.map +1 -0
- package/dist/runs/controller.d.ts +307 -0
- package/dist/runs/controller.js +1078 -0
- package/dist/runs/controller.js.map +1 -0
- package/dist/runs/errors.d.ts +20 -0
- package/dist/runs/errors.js +26 -0
- package/dist/runs/errors.js.map +1 -0
- package/dist/runs/event-bus.d.ts +106 -0
- package/dist/runs/event-bus.js +105 -0
- package/dist/runs/event-bus.js.map +1 -0
- package/dist/runs/execution.d.ts +39 -0
- package/dist/runs/execution.js +146 -0
- package/dist/runs/execution.js.map +1 -0
- package/dist/runs/index.d.ts +12 -0
- package/dist/runs/index.js +13 -0
- package/dist/runs/index.js.map +1 -0
- package/dist/runs/retention.d.ts +64 -0
- package/dist/runs/retention.js +232 -0
- package/dist/runs/retention.js.map +1 -0
- package/dist/runs/workspace.d.ts +20 -0
- package/dist/runs/workspace.js +51 -0
- package/dist/runs/workspace.js.map +1 -0
- package/dist/scheduler/checks.d.ts +41 -0
- package/dist/scheduler/checks.js +111 -0
- package/dist/scheduler/checks.js.map +1 -0
- package/dist/scheduler/cron.d.ts +32 -0
- package/dist/scheduler/cron.js +83 -0
- package/dist/scheduler/cron.js.map +1 -0
- package/dist/scheduler/dry-run.d.ts +42 -0
- package/dist/scheduler/dry-run.js +167 -0
- package/dist/scheduler/dry-run.js.map +1 -0
- package/dist/scheduler/errors.d.ts +22 -0
- package/dist/scheduler/errors.js +22 -0
- package/dist/scheduler/errors.js.map +1 -0
- package/dist/scheduler/format.d.ts +3 -0
- package/dist/scheduler/format.js +73 -0
- package/dist/scheduler/format.js.map +1 -0
- package/dist/scheduler/index.d.ts +13 -0
- package/dist/scheduler/index.js +14 -0
- package/dist/scheduler/index.js.map +1 -0
- package/dist/scheduler/planner.d.ts +88 -0
- package/dist/scheduler/planner.js +255 -0
- package/dist/scheduler/planner.js.map +1 -0
- package/dist/scheduler/scheduler.d.ts +160 -0
- package/dist/scheduler/scheduler.js +680 -0
- package/dist/scheduler/scheduler.js.map +1 -0
- package/dist/scheduler/state.d.ts +26 -0
- package/dist/scheduler/state.js +25 -0
- package/dist/scheduler/state.js.map +1 -0
- package/dist/scheduler/types.d.ts +197 -0
- package/dist/scheduler/types.js +3 -0
- package/dist/scheduler/types.js.map +1 -0
- package/dist/service/index.d.ts +6 -0
- package/dist/service/index.js +7 -0
- package/dist/service/index.js.map +1 -0
- package/dist/service/install.d.ts +93 -0
- package/dist/service/install.js +250 -0
- package/dist/service/install.js.map +1 -0
- package/dist/service/unit.d.ts +50 -0
- package/dist/service/unit.js +171 -0
- package/dist/service/unit.js.map +1 -0
- package/dist/sources/github/adapter.d.ts +99 -0
- package/dist/sources/github/adapter.js +336 -0
- package/dist/sources/github/adapter.js.map +1 -0
- package/dist/sources/github/fields.d.ts +8 -0
- package/dist/sources/github/fields.js +72 -0
- package/dist/sources/github/fields.js.map +1 -0
- package/dist/sources/github/http.d.ts +100 -0
- package/dist/sources/github/http.js +288 -0
- package/dist/sources/github/http.js.map +1 -0
- package/dist/sources/github/index.d.ts +6 -0
- package/dist/sources/github/index.js +7 -0
- package/dist/sources/github/index.js.map +1 -0
- package/dist/sources/github/pushdown.d.ts +14 -0
- package/dist/sources/github/pushdown.js +47 -0
- package/dist/sources/github/pushdown.js.map +1 -0
- package/dist/sources/github/refs.d.ts +17 -0
- package/dist/sources/github/refs.js +61 -0
- package/dist/sources/github/refs.js.map +1 -0
- package/dist/sources/index.d.ts +6 -0
- package/dist/sources/index.js +7 -0
- package/dist/sources/index.js.map +1 -0
- package/dist/ui/index.d.ts +12 -0
- package/dist/ui/index.js +28 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/public/app.css +239 -0
- package/dist/ui/public/favicon.svg +1 -0
- package/dist/ui/public/index.html +27 -0
- package/dist/ui/public/js/client/api.js +68 -0
- package/dist/ui/public/js/client/app.js +146 -0
- package/dist/ui/public/js/client/dom.js +34 -0
- package/dist/ui/public/js/client/page.js +9 -0
- package/dist/ui/public/js/client/pages/actions.js +35 -0
- package/dist/ui/public/js/client/pages/blocked.js +58 -0
- package/dist/ui/public/js/client/pages/config.js +126 -0
- package/dist/ui/public/js/client/pages/dashboard.js +175 -0
- package/dist/ui/public/js/client/pages/run.js +367 -0
- package/dist/ui/public/js/client/pages/runs.js +72 -0
- package/dist/ui/public/js/client/pages/views.js +80 -0
- package/dist/ui/public/js/client/pages/workflows.js +291 -0
- package/dist/ui/public/js/client/types.js +1 -0
- package/dist/ui/public/js/client/ui.js +152 -0
- package/dist/ui/public/js/shared/dom.js +77 -0
- package/dist/ui/public/js/shared/events.js +88 -0
- package/dist/ui/public/js/shared/format.js +213 -0
- package/dist/ui/public/js/shared/logs.js +136 -0
- package/dist/ui/public/js/shared/params.js +90 -0
- package/dist/ui/public/js/shared/route.js +36 -0
- package/dist/ui/public/js/shared/sort.js +70 -0
- package/dist/ui/public/js/shared/sse.js +193 -0
- package/dist/ui/public/js/shared/throttle.js +65 -0
- package/dist/views/index.d.ts +6 -0
- package/dist/views/index.js +7 -0
- package/dist/views/index.js.map +1 -0
- package/dist/views/service.d.ts +131 -0
- package/dist/views/service.js +264 -0
- package/dist/views/service.js.map +1 -0
- package/docs/api.md +239 -0
- package/docs/configuration-reference.md +1785 -0
- package/docs/cron-semantics.md +96 -0
- package/docs/manual-tests/github-fixture/config.yaml +30 -0
- package/docs/manual-tests/github-fixture/helpers.sh +93 -0
- package/docs/manual-tests/github-fixture/identities.yaml +18 -0
- package/docs/manual-tests/github-fixture/scripts/test-worker.sh +100 -0
- package/docs/manual-tests/github-fixture/sources.yaml +13 -0
- package/docs/manual-tests/github-fixture/views/dependencies.yaml +17 -0
- package/docs/manual-tests/github-fixture/views/needs-maintainer.yaml +17 -0
- package/docs/manual-tests/github-fixture/workflows/coder-test.yaml +76 -0
- package/docs/manual-tests/github-fixture/workflows/commenter-test.yaml +63 -0
- package/docs/manual-tests/github-fixture/workflows/reviewer-test.yaml +60 -0
- package/docs/manual-tests/github.md +1308 -0
- package/docs/manual-tests/process-supervision.md +64 -0
- package/docs/manual-tests/systemd.md +68 -0
- package/docs/operations.md +271 -0
- package/docs/worker-protocol.md +145 -0
- package/examples/config/config.yaml +35 -0
- package/examples/config/identities.yaml +18 -0
- package/examples/config/sources.yaml +13 -0
- package/examples/config/views/needs-maintainer.yaml +15 -0
- package/examples/config/workflows/coder-project-a.yaml +86 -0
- package/examples/config/workflows/deploy.yaml +15 -0
- package/examples/config/workflows/nightly-maintenance.yaml +13 -0
- package/package.json +75 -4
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run controller (Spec §8, §11, §13, §14): drives a reserved run through
|
|
3
|
+
* `starting → running → finalizing → <terminal>`, classifies the outcome,
|
|
4
|
+
* applies technical-failure counting and retry blocks, runs the completion
|
|
5
|
+
* hook, cleans up the workspace, supervises cancel, recovers after a
|
|
6
|
+
* controller crash and implements pause / drain / cancel-all shutdown.
|
|
7
|
+
*
|
|
8
|
+
* Invariants:
|
|
9
|
+
* - Every status transition is persisted before work continues; terminal
|
|
10
|
+
* statuses are reached only via `finalizing` with a persisted
|
|
11
|
+
* {@link FinalizationTarget} (WI-01/WI-03).
|
|
12
|
+
* - The retry block is created in the SAME transaction as `→ finalizing`,
|
|
13
|
+
* i.e. before the completion hook runs (Spec §11 "important order").
|
|
14
|
+
* - Hooks always use the run's configuration snapshot, never the live config.
|
|
15
|
+
* - Bus publication and notifications happen only after commit.
|
|
16
|
+
* - A process is only ever signalled after verifying its start identity
|
|
17
|
+
* (recovery); on doubt the run becomes `recovery_pending` and keeps its lock.
|
|
18
|
+
*/
|
|
19
|
+
import { type Clock, type CredentialProvider, type Executor, type Logger, type Notifier, type SourceItem, type TechnicalStatus, type Timers } from '../core/index.js';
|
|
20
|
+
import { type KillFn, type ProcessInspector } from '../executors/index.js';
|
|
21
|
+
import { type LifecycleEngine, type SourceResolver } from '../lifecycle/index.js';
|
|
22
|
+
import { type BlockRecord, type Repositories, type RunRecord } from '../persistence/index.js';
|
|
23
|
+
import { PersistedEventPublisher, RunEventBus, type ControllerStatus } from './event-bus.js';
|
|
24
|
+
/** Orchestrator-side event types persisted by the controller (besides `run.status`). */
|
|
25
|
+
export declare const RUN_EVENTS: {
|
|
26
|
+
/** Worker spawn is about to happen (`{command, args, workingDirectory}`); recovery uses it. */
|
|
27
|
+
readonly spawn: 'run.spawn';
|
|
28
|
+
/** Item re-read before `on_start` (Spec §7): `{found, matches?}`. */
|
|
29
|
+
readonly itemReread: 'run.item_reread';
|
|
30
|
+
readonly cancelRequested: 'run.cancel_requested';
|
|
31
|
+
/** Process group could not be terminated; run stays `cancelling` (Spec §13). */
|
|
32
|
+
readonly cancelFailed: 'run.cancel_failed';
|
|
33
|
+
/** A completion hook threw unexpectedly. */
|
|
34
|
+
readonly hookError: 'run.hook_error';
|
|
35
|
+
/** Unexpected internal error while supervising a run (run left as is for recovery). */
|
|
36
|
+
readonly controllerError: 'run.controller_error';
|
|
37
|
+
/** Recovery could not identify / stop the process → `recovery_pending`. */
|
|
38
|
+
readonly recoveryFailed: 'recovery.failed';
|
|
39
|
+
/** Recovery decided the run's fate (`{action, detail}`). */
|
|
40
|
+
readonly recovered: 'recovery.recovered';
|
|
41
|
+
/** Workspace cleanup result. */
|
|
42
|
+
readonly workspaceCleanup: 'workspace.cleanup';
|
|
43
|
+
};
|
|
44
|
+
/** Optional per-start settings. */
|
|
45
|
+
export interface StartRunOptions {
|
|
46
|
+
/**
|
|
47
|
+
* Re-check of the freshly re-read item (Spec §7 race), e.g. the scheduler's
|
|
48
|
+
* cheap filter. `false` → the run is not started and finalized as
|
|
49
|
+
* `cancelled` (not counted, no hooks). Manual starts omit it.
|
|
50
|
+
*/
|
|
51
|
+
verifyItem?: (item: SourceItem) => boolean | Promise<boolean>;
|
|
52
|
+
}
|
|
53
|
+
/** Handle returned by {@link RunController.startRun}. */
|
|
54
|
+
export interface RunHandle {
|
|
55
|
+
runId: string;
|
|
56
|
+
/**
|
|
57
|
+
* Resolves with the run record once supervision ended (terminal, or left
|
|
58
|
+
* in its state for recovery). Rejects only if the database itself fails.
|
|
59
|
+
*/
|
|
60
|
+
done: Promise<RunRecord>;
|
|
61
|
+
}
|
|
62
|
+
/** Shutdown mode. */
|
|
63
|
+
export type ShutdownMode = 'drain' | 'cancel';
|
|
64
|
+
/** Options of {@link RunController.shutdown}. */
|
|
65
|
+
export interface ShutdownOptions {
|
|
66
|
+
/** Default `drain`. */
|
|
67
|
+
mode?: ShutdownMode;
|
|
68
|
+
/** Max wait for active runs while draining; then cancel-all. `undefined` = wait forever. */
|
|
69
|
+
drainTimeoutMs?: number;
|
|
70
|
+
/**
|
|
71
|
+
* Max wait for cancelled runs (incl. `on_cancel`); then running hooks are
|
|
72
|
+
* interrupted (resumed by recovery at next start). `undefined` = wait forever.
|
|
73
|
+
*/
|
|
74
|
+
cancelTimeoutMs?: number;
|
|
75
|
+
/** Reason recorded on cancelled runs. */
|
|
76
|
+
reason?: string;
|
|
77
|
+
}
|
|
78
|
+
/** Result of a shutdown. */
|
|
79
|
+
export interface ShutdownResult {
|
|
80
|
+
/** `drained`: all runs finished normally; `cancelled`: cancel-all was needed. */
|
|
81
|
+
outcome: 'drained' | 'cancelled';
|
|
82
|
+
/** Runs still supervised when the stop callback ran (left for recovery). */
|
|
83
|
+
leftActive: string[];
|
|
84
|
+
}
|
|
85
|
+
/** Report of {@link RunController.recover}. */
|
|
86
|
+
export interface RecoveryReport {
|
|
87
|
+
/** Runs finalized by recovery, with their final status. */
|
|
88
|
+
finalized: Array<{
|
|
89
|
+
runId: string;
|
|
90
|
+
status: TechnicalStatus;
|
|
91
|
+
detail: string;
|
|
92
|
+
}>;
|
|
93
|
+
/** Runs that are `recovery_pending` after recovery (lock kept). */
|
|
94
|
+
pending: Array<{
|
|
95
|
+
runId: string;
|
|
96
|
+
reason: string;
|
|
97
|
+
}>;
|
|
98
|
+
/** Terminal runs whose incomplete action chains were resumed. */
|
|
99
|
+
resumedActions: string[];
|
|
100
|
+
/** Unexpected per-run errors (logged; the run is left as is). */
|
|
101
|
+
errors: Array<{
|
|
102
|
+
runId: string;
|
|
103
|
+
message: string;
|
|
104
|
+
}>;
|
|
105
|
+
}
|
|
106
|
+
/** Dependencies and tuning of the {@link RunController}. */
|
|
107
|
+
export interface RunControllerOptions {
|
|
108
|
+
repositories: Repositories;
|
|
109
|
+
/** Lifecycle engine (WI-07); pass `publisher.actionListener()` as its `onActionChange`. */
|
|
110
|
+
lifecycle: LifecycleEngine;
|
|
111
|
+
/** Source adapters by configured source ID. */
|
|
112
|
+
sources: SourceResolver;
|
|
113
|
+
dataDir: string;
|
|
114
|
+
/** Shared bus; default: a new one (see {@link RunController.bus}). */
|
|
115
|
+
bus?: RunEventBus;
|
|
116
|
+
/** Shared publisher of persisted events; default: a new one over `bus`. */
|
|
117
|
+
publisher?: PersistedEventPublisher;
|
|
118
|
+
/** Needed for `execute.secrets`. */
|
|
119
|
+
credentials?: CredentialProvider;
|
|
120
|
+
/** Receives `retry_block_created` and `recovery_failed` after commit. Must not block/throw. */
|
|
121
|
+
notifier?: Notifier;
|
|
122
|
+
/** Executor per run; default `new ShellExecutor({clock, logger, workspaceBaseDir})`. */
|
|
123
|
+
createExecutor?: (options: {
|
|
124
|
+
workspaceBaseDir: string | undefined;
|
|
125
|
+
}) => Executor;
|
|
126
|
+
/** `retention.max_log_size_per_run` in bytes (value or getter for the live config). */
|
|
127
|
+
maxLogBytesPerRun?: number | (() => number | undefined);
|
|
128
|
+
clock?: Clock;
|
|
129
|
+
/** Timers for shutdown timeouts and recovery polling. */
|
|
130
|
+
timers?: Timers;
|
|
131
|
+
logger?: Logger;
|
|
132
|
+
/** Recovery: process inspector / signal sender (tests). */
|
|
133
|
+
processInspector?: ProcessInspector;
|
|
134
|
+
kill?: KillFn;
|
|
135
|
+
/** Recovery: "does a process group with this ID exist?" (default `processGroupExists`; tests). */
|
|
136
|
+
groupExists?: (pgid: number) => boolean;
|
|
137
|
+
/** Recovery: wait after SIGKILL before giving up (default 5 s). */
|
|
138
|
+
recoveryKillConfirmMs?: number;
|
|
139
|
+
/** Recovery: SIGTERM→SIGKILL grace; default the run snapshot's `execute.cancel_grace`. */
|
|
140
|
+
recoveryGraceMs?: number;
|
|
141
|
+
/** Max wait for interrupted hooks after a forced stop (default 10 s). */
|
|
142
|
+
abortSettleMs?: number;
|
|
143
|
+
/** Called once when a shutdown completed (after drain or cancel-all). */
|
|
144
|
+
onStop?: (result: ShutdownResult) => void | Promise<void>;
|
|
145
|
+
}
|
|
146
|
+
/** See module docs. One instance per process. */
|
|
147
|
+
export declare class RunController {
|
|
148
|
+
private readonly options;
|
|
149
|
+
/** In-process event bus (SSE source for WI-10). */
|
|
150
|
+
readonly bus: RunEventBus;
|
|
151
|
+
/** Publisher of persisted events (share with the lifecycle engine). */
|
|
152
|
+
readonly publisher: PersistedEventPublisher;
|
|
153
|
+
private readonly repos;
|
|
154
|
+
private readonly lifecycle;
|
|
155
|
+
private readonly clock;
|
|
156
|
+
private readonly timers;
|
|
157
|
+
private readonly logger;
|
|
158
|
+
private readonly active;
|
|
159
|
+
private readonly idleWaiters;
|
|
160
|
+
/** Woken when a running shutdown is escalated (cancel mode / stricter timeouts). */
|
|
161
|
+
private readonly shutdownWakeups;
|
|
162
|
+
private shutdownState;
|
|
163
|
+
/** Aborted on a forced stop: interrupts completion hooks (resumed by recovery). */
|
|
164
|
+
private readonly hookAbort;
|
|
165
|
+
private ready;
|
|
166
|
+
private paused;
|
|
167
|
+
private draining;
|
|
168
|
+
private stopping;
|
|
169
|
+
private recovering;
|
|
170
|
+
private shuttingDown;
|
|
171
|
+
constructor(options: RunControllerOptions);
|
|
172
|
+
/** Current controller status. */
|
|
173
|
+
get status(): ControllerStatus;
|
|
174
|
+
/** Recovery finished (`/ready`). */
|
|
175
|
+
isReady(): boolean;
|
|
176
|
+
/** Scheduler gate for automatic starts: ready, not paused, not draining/stopping. */
|
|
177
|
+
canStartAutomatically(): boolean;
|
|
178
|
+
/** Gate for manual starts: pause does not apply (Spec §14), drain/stop does. */
|
|
179
|
+
canStartManually(): boolean;
|
|
180
|
+
/** Run IDs currently supervised by this process. */
|
|
181
|
+
activeRunIds(): string[];
|
|
182
|
+
/** Pause automatic starts (running runs are not touched). */
|
|
183
|
+
pause(): void;
|
|
184
|
+
/** Resume automatic starts. */
|
|
185
|
+
resume(): void;
|
|
186
|
+
/** True if an active retry block exists for the workflow/item (`itemKey = null` → workflow scope). */
|
|
187
|
+
isBlocked(workflowId: string, itemKey: string | null): boolean;
|
|
188
|
+
/** Remove a block: starts a new counting period; runs/history stay (idempotent). */
|
|
189
|
+
clearBlock(blockId: number, clearedBy?: string | null): BlockRecord;
|
|
190
|
+
/**
|
|
191
|
+
* Start supervising a reserved run (from the scheduler or a manual start).
|
|
192
|
+
* Returns immediately; the run proceeds asynchronously (`handle.done`).
|
|
193
|
+
*
|
|
194
|
+
* If the controller does not accept runs (not ready, draining, stopping),
|
|
195
|
+
* the reserved run is finalized as `cancelled` (never started, not counted,
|
|
196
|
+
* no hooks) so its lock is released, and a {@link RunControllerError} is thrown.
|
|
197
|
+
*/
|
|
198
|
+
startRun(run: RunRecord | string, options?: StartRunOptions): RunHandle;
|
|
199
|
+
/**
|
|
200
|
+
* Cancel a run: persist `cancelling`, stop the process group (SIGTERM →
|
|
201
|
+
* grace → SIGKILL → confirmed), run `on_cancel`, end as `cancelled`.
|
|
202
|
+
* Resolves with the final run. If the group cannot be terminated the run
|
|
203
|
+
* stays `cancelling`, the failure is persisted and `kill_failed` is thrown
|
|
204
|
+
* (calling again retries).
|
|
205
|
+
*/
|
|
206
|
+
cancelRun(runId: string, options?: {
|
|
207
|
+
reason?: string;
|
|
208
|
+
}): Promise<RunRecord>;
|
|
209
|
+
/**
|
|
210
|
+
* Synchronous variant for the API (HTTP 202/409): validates and persists the
|
|
211
|
+
* cancel request (`cancelling`) and stops the process in the background.
|
|
212
|
+
* Throws the same errors as {@link cancelRun}; a later kill failure is only
|
|
213
|
+
* visible on the run (`run.cancel_failed`, `error.code = kill_failed`).
|
|
214
|
+
*/
|
|
215
|
+
requestCancel(runId: string, options?: {
|
|
216
|
+
reason?: string;
|
|
217
|
+
}): {
|
|
218
|
+
runId: string;
|
|
219
|
+
status: TechnicalStatus;
|
|
220
|
+
};
|
|
221
|
+
/** Validate + persist a cancel request; `null` if the run was finalized directly (never started). */
|
|
222
|
+
private beginCancel;
|
|
223
|
+
/** Drain: no new runs, wait for all active runs, then stop. */
|
|
224
|
+
drain(): Promise<ShutdownResult>;
|
|
225
|
+
/** Cancel all runs (with `on_cancel`), then stop. */
|
|
226
|
+
cancelAllAndShutdown(reason?: string): Promise<ShutdownResult>;
|
|
227
|
+
/**
|
|
228
|
+
* Shutdown. The first call starts it; later calls return the same promise
|
|
229
|
+
* but ESCALATE a running shutdown: `mode: 'cancel'` turns a drain into
|
|
230
|
+
* cancel-all, and stricter `drainTimeoutMs` / `cancelTimeoutMs` (counted
|
|
231
|
+
* from the later call) replace looser ones – e.g. API drain followed by
|
|
232
|
+
* SIGTERM with timeouts, or a second SIGTERM → `mode: 'cancel'`.
|
|
233
|
+
*
|
|
234
|
+
* SIGTERM recommendation (WI-10): `shutdown({mode: 'drain', drainTimeoutMs, cancelTimeoutMs})`
|
|
235
|
+
* – drain with timeout, then cancel-all, then interrupt remaining hooks.
|
|
236
|
+
* A running recovery is awaited before anything stops.
|
|
237
|
+
*/
|
|
238
|
+
shutdown(options?: ShutdownOptions): Promise<ShutdownResult>;
|
|
239
|
+
private doShutdown;
|
|
240
|
+
private remaining;
|
|
241
|
+
/**
|
|
242
|
+
* Recover after a (crashed) previous controller. MUST run before the
|
|
243
|
+
* scheduler starts; sets `ready` only at the end. Idempotent.
|
|
244
|
+
*/
|
|
245
|
+
recover(): Promise<RecoveryReport>;
|
|
246
|
+
/**
|
|
247
|
+
* Re-attempt the recovery of a `recovery_pending` run (e.g. after the
|
|
248
|
+
* operator stopped the process). With `assumeGone: true` the operator
|
|
249
|
+
* confirms the process is gone; nothing is signalled and the run is
|
|
250
|
+
* finalized (`crashed`, or `cancelled` if it was being cancelled).
|
|
251
|
+
* An unsupervised `finalizing` run (e.g. after an internal error) resumes
|
|
252
|
+
* its completion hook and finishes.
|
|
253
|
+
*
|
|
254
|
+
* @throws RunControllerError `run_controller_not_ready` during recovery,
|
|
255
|
+
* `run_controller_not_accepting` while draining/stopping,
|
|
256
|
+
* `run_already_started` if the run is supervised, `run_not_recovery_pending`
|
|
257
|
+
*/
|
|
258
|
+
retryRecovery(runId: string, options?: {
|
|
259
|
+
assumeGone?: boolean;
|
|
260
|
+
}): Promise<RunRecord>;
|
|
261
|
+
/** Register a recovery job in `active`: drain waits for it, cancel refuses it, no double processing. */
|
|
262
|
+
private trackRecovery;
|
|
263
|
+
private doRecover;
|
|
264
|
+
private recoverRun;
|
|
265
|
+
/** Runs that may have a worker process: verify/terminate it, then finalize or mark `recovery_pending`. */
|
|
266
|
+
private recoverProcessRun;
|
|
267
|
+
private checkProcess;
|
|
268
|
+
private markRecoveryPending;
|
|
269
|
+
private resumeFinalizing;
|
|
270
|
+
private resumeTerminalRunActions;
|
|
271
|
+
/** Actions left `running` → safe state (WI-07); optionally drop the rest of an interrupted `on_start`. */
|
|
272
|
+
private makeActionsSafe;
|
|
273
|
+
private execute;
|
|
274
|
+
private cancelProcess;
|
|
275
|
+
/**
|
|
276
|
+
* `→ finalizing` (target, counter and block in ONE transaction), then the
|
|
277
|
+
* completion hook, workspace cleanup and `→ <terminal>` (lock released).
|
|
278
|
+
*/
|
|
279
|
+
private finalize;
|
|
280
|
+
private beginFinalization;
|
|
281
|
+
private completeFinalization;
|
|
282
|
+
/** Finalize a run that never reached `starting`: `cancelled`, not counted, no hooks (synchronous). */
|
|
283
|
+
private finalizeUnstarted;
|
|
284
|
+
private cleanupWorkspace;
|
|
285
|
+
private track;
|
|
286
|
+
/**
|
|
287
|
+
* `idle` once no run is supervised, `timeout` after `timeoutMs`, `woken`
|
|
288
|
+
* (only with `wakeable`) when a running shutdown was escalated.
|
|
289
|
+
*/
|
|
290
|
+
private waitIdle;
|
|
291
|
+
/**
|
|
292
|
+
* Unexpected internal error while supervising a run: never finalize blindly
|
|
293
|
+
* (the worker may still run). Where the state machine allows it the run
|
|
294
|
+
* becomes `recovery_pending` (lock kept, error, `recovery_failed`
|
|
295
|
+
* notification); a `finalizing` run stays as is. The entry stays supervised
|
|
296
|
+
* until a started worker process ended; then `retryRecovery` resolves the run.
|
|
297
|
+
*/
|
|
298
|
+
private onUnexpected;
|
|
299
|
+
private appendEvent;
|
|
300
|
+
private recordRecovered;
|
|
301
|
+
private reachedStarting;
|
|
302
|
+
private spawnAttempted;
|
|
303
|
+
private groupExists;
|
|
304
|
+
private maxLogBytes;
|
|
305
|
+
private notify;
|
|
306
|
+
private publishStatus;
|
|
307
|
+
}
|