@usine/engine 0.3.0 → 0.5.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 +661 -21
- package/README.md +112 -38
- package/dist/board-moves/board-moves.d.ts +20 -0
- package/dist/board-moves/board-moves.d.ts.map +1 -0
- package/dist/board-moves/board-moves.js +74 -0
- package/dist/board-moves/board-moves.js.map +1 -0
- package/dist/board-moves/model.d.ts +21 -0
- package/dist/board-moves/model.d.ts.map +1 -0
- package/dist/board-moves/model.js +22 -0
- package/dist/board-moves/model.js.map +1 -0
- package/dist/cursor/cursor.d.ts +2 -6
- package/dist/cursor/cursor.d.ts.map +1 -1
- package/dist/cursor/cursor.js +2 -6
- package/dist/cursor/cursor.js.map +1 -1
- package/dist/cycle-budget/cycle-budget.d.ts +14 -8
- package/dist/cycle-budget/cycle-budget.d.ts.map +1 -1
- package/dist/cycle-budget/cycle-budget.js +51 -10
- package/dist/cycle-budget/cycle-budget.js.map +1 -1
- package/dist/cycle-budget/model.d.ts +6 -2
- package/dist/cycle-budget/model.d.ts.map +1 -1
- package/dist/cycle-budget/model.js +5 -2
- package/dist/cycle-budget/model.js.map +1 -1
- package/dist/cycle-budget/queries.d.ts +1 -1
- package/dist/cycle-budget/queries.d.ts.map +1 -1
- package/dist/cycle-budget/queries.js +3 -3
- package/dist/cycle-budget/queries.js.map +1 -1
- package/dist/database/database.d.ts +1 -1
- package/dist/database/database.d.ts.map +1 -1
- package/dist/database/local-sqlite.d.ts +13 -10
- package/dist/database/local-sqlite.d.ts.map +1 -1
- package/dist/database/local-sqlite.js +22 -17
- package/dist/database/local-sqlite.js.map +1 -1
- package/dist/database/schema.d.ts +668 -36
- package/dist/database/schema.d.ts.map +1 -1
- package/dist/database/schema.js +123 -23
- package/dist/database/schema.js.map +1 -1
- package/dist/{workflow → engine}/admission.d.ts +2 -2
- package/dist/engine/admission.d.ts.map +1 -0
- package/dist/{workflow → engine}/admission.js +4 -4
- package/dist/engine/admission.js.map +1 -0
- package/dist/engine/checkout-recovery.d.ts +79 -0
- package/dist/engine/checkout-recovery.d.ts.map +1 -0
- package/dist/engine/checkout-recovery.js +238 -0
- package/dist/engine/checkout-recovery.js.map +1 -0
- package/dist/engine/engine.d.ts +67 -26
- package/dist/engine/engine.d.ts.map +1 -1
- package/dist/engine/engine.js +136 -129
- package/dist/engine/engine.js.map +1 -1
- package/dist/engine/error.d.ts +29 -10
- package/dist/engine/error.d.ts.map +1 -1
- package/dist/engine/error.js +28 -8
- package/dist/engine/error.js.map +1 -1
- package/dist/engine/lifecycle.d.ts +83 -28
- package/dist/engine/lifecycle.d.ts.map +1 -1
- package/dist/engine/lifecycle.js +94 -45
- package/dist/engine/lifecycle.js.map +1 -1
- package/dist/engine/retry.d.ts +16 -0
- package/dist/engine/retry.d.ts.map +1 -0
- package/dist/engine/retry.js +18 -0
- package/dist/engine/retry.js.map +1 -0
- package/dist/engine/run-again.d.ts +45 -0
- package/dist/engine/run-again.d.ts.map +1 -0
- package/dist/engine/run-again.js +56 -0
- package/dist/engine/run-again.js.map +1 -0
- package/dist/engine/run-driver.d.ts +68 -0
- package/dist/engine/run-driver.d.ts.map +1 -0
- package/dist/engine/run-driver.js +448 -0
- package/dist/engine/run-driver.js.map +1 -0
- package/dist/engine/shutdown.d.ts +3 -4
- package/dist/engine/shutdown.d.ts.map +1 -1
- package/dist/engine/shutdown.js +3 -4
- package/dist/engine/shutdown.js.map +1 -1
- package/dist/engine/submission.d.ts +31 -11
- package/dist/engine/submission.d.ts.map +1 -1
- package/dist/engine/submission.js +43 -12
- package/dist/engine/submission.js.map +1 -1
- package/dist/engine/unconfirmed-stops.d.ts +27 -0
- package/dist/engine/unconfirmed-stops.d.ts.map +1 -0
- package/dist/engine/unconfirmed-stops.js +26 -0
- package/dist/engine/unconfirmed-stops.js.map +1 -0
- package/dist/item-projection/item-projection.d.ts +14 -4
- package/dist/item-projection/item-projection.d.ts.map +1 -1
- package/dist/item-projection/item-projection.js +60 -14
- package/dist/item-projection/item-projection.js.map +1 -1
- package/dist/item-projection/model.d.ts +5 -1
- package/dist/item-projection/model.d.ts.map +1 -1
- package/dist/item-projection/model.js +6 -2
- package/dist/item-projection/model.js.map +1 -1
- package/dist/loop-control/loop-control.d.ts +5 -5
- package/dist/loop-control/loop-control.d.ts.map +1 -1
- package/dist/loop-control/loop-control.js +4 -4
- package/dist/loop-control/loop-control.js.map +1 -1
- package/dist/loop-control/model.d.ts +1 -1
- package/dist/loop-control/model.d.ts.map +1 -1
- package/dist/loop-control/model.js +1 -1
- package/dist/loop-control/model.js.map +1 -1
- package/dist/repository-label-projection/model.d.ts +2 -2
- package/dist/repository-label-projection/model.d.ts.map +1 -1
- package/dist/repository-label-projection/model.js +2 -2
- package/dist/repository-label-projection/model.js.map +1 -1
- package/dist/repository-label-projection/repository-label-projection.d.ts +1 -1
- package/dist/repository-label-projection/repository-label-projection.d.ts.map +1 -1
- package/dist/repository-label-projection/repository-label-projection.js +1 -1
- package/dist/repository-label-projection/repository-label-projection.js.map +1 -1
- package/dist/run-reader/model.d.ts +62 -4
- package/dist/run-reader/model.d.ts.map +1 -1
- package/dist/run-reader/model.js +66 -7
- package/dist/run-reader/model.js.map +1 -1
- package/dist/run-reader/run-reader.d.ts +25 -10
- package/dist/run-reader/run-reader.d.ts.map +1 -1
- package/dist/run-reader/run-reader.js +25 -7
- package/dist/run-reader/run-reader.js.map +1 -1
- package/dist/step-executor.d.ts +86 -13
- package/dist/step-executor.d.ts.map +1 -1
- package/dist/step-executor.js +10 -2
- package/dist/step-executor.js.map +1 -1
- package/dist/store/attempt-windows.d.ts +8 -0
- package/dist/store/attempt-windows.d.ts.map +1 -0
- package/dist/store/attempt-windows.js +53 -0
- package/dist/store/attempt-windows.js.map +1 -0
- package/dist/store/codec.d.ts +242 -43
- package/dist/store/codec.d.ts.map +1 -1
- package/dist/store/codec.js +61 -16
- package/dist/store/codec.js.map +1 -1
- package/dist/store/leftovers.d.ts +10 -0
- package/dist/store/leftovers.d.ts.map +1 -0
- package/dist/store/leftovers.js +43 -0
- package/dist/store/leftovers.js.map +1 -0
- package/dist/store/loop-items.d.ts +16 -0
- package/dist/store/loop-items.d.ts.map +1 -0
- package/dist/store/loop-items.js +185 -0
- package/dist/store/loop-items.js.map +1 -0
- package/dist/store/queries.d.ts +385 -36
- package/dist/store/queries.d.ts.map +1 -1
- package/dist/store/queries.js +355 -107
- package/dist/store/queries.js.map +1 -1
- package/dist/store/store.d.ts +106 -54
- package/dist/store/store.d.ts.map +1 -1
- package/dist/store/store.js +497 -190
- package/dist/store/store.js.map +1 -1
- package/dist/store/transcript.d.ts +3 -3
- package/dist/store/transcript.d.ts.map +1 -1
- package/dist/store/transcript.js +25 -6
- package/dist/store/transcript.js.map +1 -1
- package/dist/transcript.d.ts +19 -20
- package/dist/transcript.d.ts.map +1 -1
- package/dist/transcript.js +23 -21
- package/dist/transcript.js.map +1 -1
- package/dist/trigger-condition.d.ts +23 -0
- package/dist/trigger-condition.d.ts.map +1 -0
- package/dist/trigger-condition.js +8 -0
- package/dist/trigger-condition.js.map +1 -0
- package/drizzle/20260917071139_resolve_run_failure/migration.sql +1 -0
- package/drizzle/20260917071139_resolve_run_failure/snapshot.json +1471 -0
- package/drizzle/20260918032643_attempt_salvage/migration.sql +1 -0
- package/drizzle/20260918032643_attempt_salvage/snapshot.json +1481 -0
- package/drizzle/20261011153856_drop_workflow_tables/migration.sql +4 -0
- package/drizzle/20261011153856_drop_workflow_tables/snapshot.json +1433 -0
- package/drizzle/20261017155043_attempt_salvage_check/migration.sql +41 -0
- package/drizzle/20261017155043_attempt_salvage_check/snapshot.json +1421 -0
- package/drizzle/20261018162700_discard_attempt_leftovers/migration.sql +1 -0
- package/drizzle/20261018162700_discard_attempt_leftovers/snapshot.json +1431 -0
- package/drizzle/20261018172605_loop_items_and_reopenings/migration.sql +15 -0
- package/drizzle/20261018172605_loop_items_and_reopenings/snapshot.json +1574 -0
- package/drizzle/20261018180339_attempt_ended_at/migration.sql +1 -0
- package/drizzle/20261018180339_attempt_ended_at/snapshot.json +1584 -0
- package/drizzle/20261019104043_run_approval_source/migration.sql +15 -0
- package/drizzle/20261019104043_run_approval_source/snapshot.json +1610 -0
- package/drizzle/20261019133538_board_moves/migration.sql +14 -0
- package/drizzle/20261019133538_board_moves/snapshot.json +1731 -0
- package/drizzle/20261019170538_item_projection_gone/migration.sql +1 -0
- package/drizzle/20261019170538_item_projection_gone/snapshot.json +1741 -0
- package/drizzle/20261019180649_run_again_events/migration.sql +7 -0
- package/drizzle/20261019180649_run_again_events/snapshot.json +1804 -0
- package/drizzle/20261019185008_trigger_event_permissions/migration.sql +1 -0
- package/drizzle/20261019185008_trigger_event_permissions/snapshot.json +1814 -0
- package/drizzle/20261020103746_attempt_start/migration.sql +5 -0
- package/drizzle/20261020103746_attempt_start/snapshot.json +1844 -0
- package/drizzle/20261020125211_attempt_comments/migration.sql +1 -0
- package/drizzle/20261020125211_attempt_comments/snapshot.json +1854 -0
- package/drizzle/20261020191320_run_closed_at/migration.sql +6 -0
- package/drizzle/20261020191320_run_closed_at/snapshot.json +1864 -0
- package/drizzle/20261023091428_rename_loop_item_hold_to_suppression/migration.sql +2 -0
- package/drizzle/20261023091428_rename_loop_item_hold_to_suppression/snapshot.json +1867 -0
- package/drizzle/20261024162954_cycle_ask_closures/migration.sql +10 -0
- package/drizzle/20261024162954_cycle_ask_closures/snapshot.json +1948 -0
- package/drizzle/20261027104206_attempt_out_of_memory/migration.sql +1 -0
- package/drizzle/20261027104206_attempt_out_of_memory/snapshot.json +1958 -0
- package/drizzle/20261027191944_failure_resolution/migration.sql +1 -0
- package/drizzle/20261027191944_failure_resolution/snapshot.json +1968 -0
- package/package.json +22 -12
- package/dist/workflow/admission.d.ts.map +0 -1
- package/dist/workflow/admission.js.map +0 -1
- package/dist/workflow/command.d.ts +0 -13
- package/dist/workflow/command.d.ts.map +0 -1
- package/dist/workflow/command.js +0 -17
- package/dist/workflow/command.js.map +0 -1
- package/dist/workflow/workflow.d.ts +0 -18
- package/dist/workflow/workflow.d.ts.map +0 -1
- package/dist/workflow/workflow.js +0 -108
- package/dist/workflow/workflow.js.map +0 -1
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { AttemptId } from "@usine/core/attempt";
|
|
2
|
+
import type { RunId } from "@usine/core/run";
|
|
3
|
+
import { Context, Crypto, Effect, Layer } from "effect";
|
|
4
|
+
import { ItemProjectionWriter } from "../item-projection/item-projection.ts";
|
|
5
|
+
import { StepExecutor } from "../step-executor.ts";
|
|
6
|
+
import { RunStore } from "../store/store.ts";
|
|
7
|
+
import { TriggerCondition } from "../trigger-condition.ts";
|
|
8
|
+
import { AttemptAdmission } from "./admission.ts";
|
|
9
|
+
import type { RunStoreError } from "./error.ts";
|
|
10
|
+
import { UnconfirmedStop } from "./unconfirmed-stops.ts";
|
|
11
|
+
/** An Attempt whose parent task the engine stops, with its Run's Loop and Item and the reason. */
|
|
12
|
+
export type StopTarget = Pick<UnconfirmedStop, "attemptId" | "runId" | "loop" | "itemKey" | "reason">;
|
|
13
|
+
declare const RunDriver_base: Context.ServiceClass<RunDriver, "@usine/engine/internal/RunDriver", {
|
|
14
|
+
/** Starts the fiber of an open Run, unless one already runs here. */
|
|
15
|
+
readonly launch: (runId: RunId) => Effect.Effect<void>;
|
|
16
|
+
/** Starts the fiber of a Run that an approval or operator retry reopened, after its previous fiber ends. */
|
|
17
|
+
readonly resume: (runId: RunId) => Effect.Effect<void>;
|
|
18
|
+
/** Interrupts the fiber of a closed Run and waits for it to end. */
|
|
19
|
+
readonly stop: (runId: RunId) => Effect.Effect<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Gives the newest queued Event of the closed Run's Item its turn, after re-evaluating the
|
|
22
|
+
* trigger against the Item's current state. If the Item is gone, marks its projection gone.
|
|
23
|
+
*/
|
|
24
|
+
readonly continueWithNewest: (closedRunId: RunId) => Effect.Effect<void, RunStoreError>;
|
|
25
|
+
/**
|
|
26
|
+
* Opens the queued Events whose continuation didn't run and starts a fiber for every open Run
|
|
27
|
+
* without one, except Runs waiting for approval. Also retries the parent task stops that
|
|
28
|
+
* `releaseKept`, `recoverWorkspaces`, or the end of an Attempt couldn't confirm, then runs
|
|
29
|
+
* `StepExecutor.sweep`.
|
|
30
|
+
*/
|
|
31
|
+
readonly reconcile: () => Effect.Effect<void, RunStoreError>;
|
|
32
|
+
/** Returns the closed Attempts whose parent task stop `reconcile` retries. */
|
|
33
|
+
readonly unconfirmedStops: Effect.Effect<ReadonlyArray<UnconfirmedStop>>;
|
|
34
|
+
/**
|
|
35
|
+
* Reconciles at startup the checkout of every persisted Attempt on a configured Worker, before
|
|
36
|
+
* any Run admits its next Attempt. Keeps the checkout and occupies a Worker slot (#177) for
|
|
37
|
+
* an open Attempt whose parent task is live or unreadable, and for a closed Attempt whose
|
|
38
|
+
* parent task isn't confirmed stopped. See `checkoutRecoveryFor`.
|
|
39
|
+
*/
|
|
40
|
+
readonly recoverWorkspaces: () => Effect.Effect<void, RunStoreError>;
|
|
41
|
+
/**
|
|
42
|
+
* Moves the slot that the fiber of Run `runId` holds to its Attempt `attemptId`, whose parent
|
|
43
|
+
* task may still run, so the slot stays taken after the fiber frees it, until `releaseKept`
|
|
44
|
+
* confirms that the parent task stopped (#475). Does nothing if the fiber holds no slot.
|
|
45
|
+
*/
|
|
46
|
+
readonly holdSlot: (runId: RunId, attemptId: AttemptId) => Effect.Effect<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Releases the slot kept for the Attempt of `stop`: the slot that `holdSlot` moved, or what
|
|
49
|
+
* `recoverWorkspaces` kept for reattaching it. Once the parent task is confirmed stopped for
|
|
50
|
+
* `stop.reason`, reconciles a kept checkout and releases the slot. Until then, both stay kept
|
|
51
|
+
* (#177, #475), no Run of the Loop on the Item starts an Attempt (#523), and each `reconcile`
|
|
52
|
+
* retries.
|
|
53
|
+
*/
|
|
54
|
+
readonly releaseKept: (stop: StopTarget) => Effect.Effect<void>;
|
|
55
|
+
}>;
|
|
56
|
+
/**
|
|
57
|
+
* The service that drives open Runs in this process, one fiber per Run. A fiber parks a gated
|
|
58
|
+
* Run for approval, then reserves a Worker, starts or reattaches the Attempt, records its
|
|
59
|
+
* outcome, and repeats until the Run closes. The fiber that closes a Run gives the Item's newest
|
|
60
|
+
* queued Event its turn; cancel, supersede, and revoke do that themselves. A fiber that ends
|
|
61
|
+
* without closing its Run leaves it for `resume` or `reconcile`, as one does instead of starting
|
|
62
|
+
* an Attempt while a parent task on its Loop's Item isn't confirmed stopped (#523).
|
|
63
|
+
*/
|
|
64
|
+
export declare class RunDriver extends RunDriver_base {
|
|
65
|
+
static readonly layer: Layer.Layer<RunDriver, never, AttemptAdmission | Crypto.Crypto | ItemProjectionWriter | RunStore | StepExecutor | TriggerCondition>;
|
|
66
|
+
}
|
|
67
|
+
export {};
|
|
68
|
+
//# sourceMappingURL=run-driver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-driver.d.ts","sourceRoot":"","sources":["../../src/engine/run-driver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAG9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAG7C,OAAO,EAEL,OAAO,EACP,MAAM,EAEN,MAAM,EAGN,KAAK,EAKN,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAoB,MAAM,qBAAqB,CAAC;AACrE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,KAAK,EAKV,aAAa,EACd,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AA6DzD,kGAAkG;AAClG,MAAM,MAAM,UAAU,GAAG,IAAI,CAC3B,eAAe,EACf,WAAW,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CACtD,CAAC;;IAmBE,qEAAqE;qBACpD,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;IACtD,4GAA4G;qBAC3F,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;IACtD,oEAAoE;mBACrD,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;IACpD;;;OAGG;iCAC0B,CAAC,WAAW,EAAE,KAAK,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC;IACvF;;;;;OAKG;wBACiB,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC;IAC5D,8EAA8E;+BACnD,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC;IACxE;;;;;OAKG;gCACyB,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC;IACpE;;;;OAIG;uBACgB,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;IAC9E;;;;;;OAMG;0BACmB,CAAC,IAAI,EAAE,UAAU,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;;AAnDnE;;;;;;;GAOG;AACH,qBAAa,SAAU,SAAQ,cA6CQ;IACrC,MAAM,CAAC,QAAQ,CAAC,KAAK,sIAilBnB;CACH"}
|
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
import * as AttemptChannel from "@usine/core/attempt/channel";
|
|
2
|
+
import { DefectFailure, InfraFailure } from "@usine/core/attempt/failure";
|
|
3
|
+
import { Cause, Context, Crypto, DateTime, Effect, Fiber, FiberMap, Layer, Option, Ref, Result, Schedule, } from "effect";
|
|
4
|
+
import { ItemProjectionWriter } from "../item-projection/item-projection.js";
|
|
5
|
+
import { StepExecutor } from "../step-executor.js";
|
|
6
|
+
import { RunStore } from "../store/store.js";
|
|
7
|
+
import { TranscriptAllQuery } from "../transcript.js";
|
|
8
|
+
import { TriggerCondition } from "../trigger-condition.js";
|
|
9
|
+
import { AttemptAdmission } from "./admission.js";
|
|
10
|
+
import { checkoutRecoveryFor, without } from "./checkout-recovery.js";
|
|
11
|
+
import { runIdFor } from "./submission.js";
|
|
12
|
+
import { UnconfirmedStop } from "./unconfirmed-stops.js";
|
|
13
|
+
// Executor sinks fail with `AttemptFailure`: a persistence error becomes an `InfraFailure`, and
|
|
14
|
+
// other store errors are defects.
|
|
15
|
+
const asAttemptFailure = (effect) => Effect.catchTags(effect, {
|
|
16
|
+
EnginePersistenceError: (error) => new InfraFailure({
|
|
17
|
+
message: `Runtime store error: could not ${error.operation}`,
|
|
18
|
+
cause: error,
|
|
19
|
+
}),
|
|
20
|
+
RunNotFoundError: (error) => Effect.die(error),
|
|
21
|
+
RunOperationRejectedError: (error) => Effect.die(error),
|
|
22
|
+
RunRetryBlockedError: (error) => Effect.die(error),
|
|
23
|
+
});
|
|
24
|
+
/** The number of retries for a store operation that failed to persist. */
|
|
25
|
+
const STORE_RETRIES = 4;
|
|
26
|
+
/** The delay before the first retry; each later delay doubles. */
|
|
27
|
+
const STORE_RETRY_DELAY = "100 millis";
|
|
28
|
+
/**
|
|
29
|
+
* Retries a store operation that fails with `EnginePersistenceError`, with exponential backoff.
|
|
30
|
+
* Returns other errors and the last persistence error.
|
|
31
|
+
*/
|
|
32
|
+
const retryingStore = (runId, operation) => (effect) => effect.pipe(Effect.tapError((error) => error._tag === "EnginePersistenceError"
|
|
33
|
+
? Effect.logWarning("A Run store operation failed to persist", {
|
|
34
|
+
runId,
|
|
35
|
+
operation,
|
|
36
|
+
cause: error.cause,
|
|
37
|
+
})
|
|
38
|
+
: Effect.void), Effect.retry({
|
|
39
|
+
schedule: Schedule.exponential(STORE_RETRY_DELAY),
|
|
40
|
+
times: STORE_RETRIES,
|
|
41
|
+
while: (error) => error._tag === "EnginePersistenceError",
|
|
42
|
+
}));
|
|
43
|
+
/** Returns the open Attempt if its parent task is live. */
|
|
44
|
+
const reattaching = (open) => Option.flatMap(open, (found) => found._tag === "Live" ? Option.some(found.attempt) : Option.none());
|
|
45
|
+
/**
|
|
46
|
+
* The service that drives open Runs in this process, one fiber per Run. A fiber parks a gated
|
|
47
|
+
* Run for approval, then reserves a Worker, starts or reattaches the Attempt, records its
|
|
48
|
+
* outcome, and repeats until the Run closes. The fiber that closes a Run gives the Item's newest
|
|
49
|
+
* queued Event its turn; cancel, supersede, and revoke do that themselves. A fiber that ends
|
|
50
|
+
* without closing its Run leaves it for `resume` or `reconcile`, as one does instead of starting
|
|
51
|
+
* an Attempt while a parent task on its Loop's Item isn't confirmed stopped (#523).
|
|
52
|
+
*/
|
|
53
|
+
export class RunDriver extends Context.Service()("@usine/engine/internal/RunDriver") {
|
|
54
|
+
static layer = Layer.effect(RunDriver, Effect.gen(function* () {
|
|
55
|
+
const store = yield* RunStore;
|
|
56
|
+
const executor = yield* StepExecutor;
|
|
57
|
+
const admission = yield* AttemptAdmission;
|
|
58
|
+
const condition = yield* TriggerCondition;
|
|
59
|
+
const items = yield* ItemProjectionWriter;
|
|
60
|
+
const crypto = yield* Crypto.Crypto;
|
|
61
|
+
const fibers = yield* FiberMap.make();
|
|
62
|
+
const checkouts = yield* checkoutRecoveryFor(store, executor);
|
|
63
|
+
// Closed Attempts whose parent task isn't confirmed stopped; each reconcile retries the stop.
|
|
64
|
+
const unconfirmed = yield* Ref.make(new Map());
|
|
65
|
+
// The slot that each Run's fiber holds, unless `holdSlot` moved it to the Run's Attempt.
|
|
66
|
+
const slots = yield* Ref.make(new Map());
|
|
67
|
+
/** Releases `lease`, the slot of the Run's fiber, unless `holdSlot` moved it. */
|
|
68
|
+
const releaseSlot = (runId, lease) => Ref.modify(slots, (held) => held.get(runId) === lease ? [true, without(held, runId)] : [false, held]).pipe(Effect.flatMap((owned) => owned
|
|
69
|
+
? lease.release
|
|
70
|
+
: Effect.logDebug("The Run's slot stays with its Attempt until the parent task is confirmed stopped", { runId, worker: lease.worker })));
|
|
71
|
+
// Annotated because a fiber's continuation calls launch again, which TypeScript cannot infer.
|
|
72
|
+
const launch = Effect.fn("RunDriver.launch")(function* (runId) {
|
|
73
|
+
yield* Effect.annotateCurrentSpan({ runId });
|
|
74
|
+
if (yield* FiberMap.has(fibers, runId)) {
|
|
75
|
+
yield* Effect.logDebug("The Run's fiber already runs in this process", { runId });
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
yield* Effect.logDebug("Starting the Run's fiber", { runId });
|
|
79
|
+
const launchedBy = yield* Effect.option(Effect.currentSpan);
|
|
80
|
+
yield* FiberMap.run(fibers, runId, drive(runId).pipe(
|
|
81
|
+
// Logged inside the Run's span: the launch span has ended by the time drive fails.
|
|
82
|
+
Effect.tapCause((cause) => Cause.hasInterruptsOnly(cause)
|
|
83
|
+
? Effect.void
|
|
84
|
+
: Effect.logError("The Run's fiber stopped on an engine failure; the next reconcile or a restart resumes it", { runId, cause })), Effect.withSpan("RunDriver.drive", {
|
|
85
|
+
root: true,
|
|
86
|
+
links: Option.toArray(Option.map(launchedBy, (span) => ({ span, attributes: {} }))),
|
|
87
|
+
}), Effect.catchCause((cause) => Cause.hasInterruptsOnly(cause) ? Effect.failCause(cause) : Effect.void)), { onlyIfMissing: true });
|
|
88
|
+
});
|
|
89
|
+
const resume = Effect.fn("RunDriver.resume")(function* (runId) {
|
|
90
|
+
yield* Effect.annotateCurrentSpan({ runId });
|
|
91
|
+
const previous = yield* FiberMap.get(fibers, runId);
|
|
92
|
+
if (Option.isSome(previous)) {
|
|
93
|
+
// The previous fiber ends right after its last write; wait until it leaves the map.
|
|
94
|
+
yield* Effect.logDebug("Waiting for the Run's previous fiber to end", { runId });
|
|
95
|
+
yield* Fiber.await(previous.value);
|
|
96
|
+
}
|
|
97
|
+
yield* launch(runId);
|
|
98
|
+
});
|
|
99
|
+
const stop = Effect.fn("RunDriver.stop")(function* (runId) {
|
|
100
|
+
yield* Effect.annotateCurrentSpan({ runId });
|
|
101
|
+
if (!(yield* FiberMap.has(fibers, runId))) {
|
|
102
|
+
yield* Effect.logDebug("The closed Run has no fiber in this process", { runId });
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
yield* FiberMap.remove(fibers, runId);
|
|
106
|
+
yield* Effect.logInfo("The closed Run's fiber stopped", { runId });
|
|
107
|
+
});
|
|
108
|
+
const markItemGone = Effect.fn("RunDriver.markItemGone")(function* (closedRunId, submission) {
|
|
109
|
+
yield* Effect.annotateCurrentSpan({ runId: closedRunId, itemKey: submission.itemKey });
|
|
110
|
+
return yield* items.markGone(submission.itemKey, yield* DateTime.now).pipe(retryingStore(closedRunId, "mark the item's projection gone"), Effect.catch((error) => Effect.logWarning("Could not mark the gone Item's projection; its Board card stays in place", {
|
|
111
|
+
completedRunId: closedRunId,
|
|
112
|
+
itemKey: submission.itemKey,
|
|
113
|
+
errorTag: error._tag,
|
|
114
|
+
}).pipe(Effect.as(false))));
|
|
115
|
+
});
|
|
116
|
+
const continueWithNewest = Effect.fn("RunDriver.continueWithNewest")(function* (closedRunId) {
|
|
117
|
+
yield* Effect.annotateCurrentSpan({ runId: closedRunId });
|
|
118
|
+
const queued = yield* store
|
|
119
|
+
.nextQueued(closedRunId)
|
|
120
|
+
.pipe(retryingStore(closedRunId, "read the queued events"));
|
|
121
|
+
if (Option.isNone(queued))
|
|
122
|
+
return;
|
|
123
|
+
const submission = queued.value.submission;
|
|
124
|
+
const fields = {
|
|
125
|
+
completedRunId: closedRunId,
|
|
126
|
+
eventId: submission.event.id,
|
|
127
|
+
loop: submission.loop,
|
|
128
|
+
itemKey: submission.itemKey,
|
|
129
|
+
};
|
|
130
|
+
const recheck = yield* condition.recheck(submission);
|
|
131
|
+
if (recheck !== "matches") {
|
|
132
|
+
// Revoke only the queue read before the remote check.
|
|
133
|
+
const revoked = yield* store
|
|
134
|
+
.revokeQueued(queued.value)
|
|
135
|
+
.pipe(retryingStore(closedRunId, "revoke the queued events"));
|
|
136
|
+
if (recheck === "no-longer-matches") {
|
|
137
|
+
yield* Effect.logInfo("Queued Event no longer matches its trigger; revoked", {
|
|
138
|
+
...fields,
|
|
139
|
+
revokedEvents: revoked,
|
|
140
|
+
});
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const projectionMarkedGone = yield* markItemGone(closedRunId, submission);
|
|
144
|
+
yield* Effect.logInfo("Queued Event's Item is gone from its source; revoked its queued Events", { ...fields, revokedEvents: revoked, projectionMarkedGone });
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const runId = yield* runIdFor(submission).pipe(Effect.provideService(Crypto.Crypto, crypto));
|
|
148
|
+
const claimed = yield* store
|
|
149
|
+
.claimQueued(submission, runId)
|
|
150
|
+
.pipe(retryingStore(closedRunId, "claim the queued event"));
|
|
151
|
+
if (Option.isNone(claimed)) {
|
|
152
|
+
// During the check, the Event was ignored, another Run opened for the Item, or a cycle
|
|
153
|
+
// reset superseded the Event.
|
|
154
|
+
yield* Effect.logInfo("Queued Event still matches its trigger but could no longer be claimed; no Run opened", fields);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
yield* Effect.logInfo("Queued Event still matches its trigger; opening its Run", {
|
|
158
|
+
...fields,
|
|
159
|
+
runId: claimed.value,
|
|
160
|
+
});
|
|
161
|
+
yield* launch(claimed.value);
|
|
162
|
+
});
|
|
163
|
+
/**
|
|
164
|
+
* Reads the state of the Run's open Attempt, or `None` if there is none. If a read fails,
|
|
165
|
+
* logs a warning and returns `Interrupted`.
|
|
166
|
+
*/
|
|
167
|
+
const openAttempt = Effect.fn("RunDriver.openAttempt")(function* (runId) {
|
|
168
|
+
yield* Effect.annotateCurrentSpan({ runId });
|
|
169
|
+
const current = yield* store.snapshot(runId).pipe(retryingStore(runId, "read the run"));
|
|
170
|
+
const open = current.attempts.at(-1);
|
|
171
|
+
if (current.run.state._tag !== "Running" ||
|
|
172
|
+
open === undefined ||
|
|
173
|
+
Option.isSome(open.outcome))
|
|
174
|
+
return Option.none();
|
|
175
|
+
const fields = { runId, attemptId: open.id, worker: open.worker };
|
|
176
|
+
yield* Effect.annotateCurrentSpan({ attemptId: open.id, worker: open.worker });
|
|
177
|
+
const live = yield* executor.isLive(open.id).pipe(Effect.result);
|
|
178
|
+
if (Result.isFailure(live)) {
|
|
179
|
+
yield* Effect.logWarning("Could not read whether the open Attempt is live; the Run does not reattach it", { ...fields, errorTag: live.failure._tag, message: live.failure.message });
|
|
180
|
+
return Option.some({ _tag: "Interrupted", attempt: open });
|
|
181
|
+
}
|
|
182
|
+
if (live.success) {
|
|
183
|
+
yield* Effect.logInfo("The open Attempt's parent task is live; reattaching it", fields);
|
|
184
|
+
return Option.some({ _tag: "Live", attempt: open });
|
|
185
|
+
}
|
|
186
|
+
const stored = yield* executor.outcome(open.id).pipe(Effect.result);
|
|
187
|
+
if (Result.isFailure(stored)) {
|
|
188
|
+
yield* Effect.logWarning("Could not read the open Attempt's stored outcome; the Run does not reattach it", { ...fields, errorTag: stored.failure._tag, message: stored.failure.message });
|
|
189
|
+
return Option.some({ _tag: "Interrupted", attempt: open });
|
|
190
|
+
}
|
|
191
|
+
if (Option.isNone(stored.success)) {
|
|
192
|
+
yield* Effect.logInfo("The open Attempt's parent task is gone; the Run does not reattach it", fields);
|
|
193
|
+
return Option.some({ _tag: "Interrupted", attempt: open });
|
|
194
|
+
}
|
|
195
|
+
const result = stored.success.value;
|
|
196
|
+
yield* Effect.logInfo("The open Attempt's parent task finished before this process recorded it; finishing the Attempt with its stored result", {
|
|
197
|
+
...fields,
|
|
198
|
+
outcome: Result.match(result, {
|
|
199
|
+
onSuccess: () => "Succeeded",
|
|
200
|
+
onFailure: ({ _tag }) => _tag,
|
|
201
|
+
}),
|
|
202
|
+
});
|
|
203
|
+
return Option.some({ _tag: "Finished", attempt: open, result });
|
|
204
|
+
});
|
|
205
|
+
/**
|
|
206
|
+
* Returns the slot for the Run's next Attempt and the effect that reads the open Attempt once
|
|
207
|
+
* the slot is held. A reattaching Run uses the slot startup occupied or waits for one on the
|
|
208
|
+
* Attempt's Worker. Only the wait, through `restore`, is interruptible.
|
|
209
|
+
*/
|
|
210
|
+
const slotFor = Effect.fn("RunDriver.slot")(function* (runId, submission, open, restore) {
|
|
211
|
+
yield* Effect.annotateCurrentSpan({ runId });
|
|
212
|
+
const found = Effect.succeed(open);
|
|
213
|
+
const reattached = reattaching(open);
|
|
214
|
+
if (Option.isSome(reattached)) {
|
|
215
|
+
const occupied = yield* checkouts.reattachSlot(reattached.value.id);
|
|
216
|
+
if (Option.isSome(occupied)) {
|
|
217
|
+
yield* Effect.logInfo("The Run reattaches its open Attempt in the slot startup occupied on its Worker", { runId, attemptId: reattached.value.id, worker: occupied.value.worker });
|
|
218
|
+
return { lease: occupied.value, open: found };
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
const lease = yield* restore(executor.reserve(runId, submission, Option.map(reattached, ({ worker }) => worker)));
|
|
222
|
+
// The parent task can stop during the wait, so read it again before reattaching.
|
|
223
|
+
return { lease, open: Option.isSome(reattached) ? openAttempt(runId) : found };
|
|
224
|
+
});
|
|
225
|
+
/**
|
|
226
|
+
* Runs one Attempt of the Run of `submission` on the reserved Worker and returns the
|
|
227
|
+
* resulting decision tag. `current` reads the open Attempt once the slot is held.
|
|
228
|
+
*/
|
|
229
|
+
const executeAttempt = Effect.fn("RunDriver.attempt")(function* (runId, submission, worker, current) {
|
|
230
|
+
yield* Effect.annotateCurrentSpan({ runId, worker });
|
|
231
|
+
const open = yield* current;
|
|
232
|
+
if (Option.isSome(open) && open.value._tag === "Finished") {
|
|
233
|
+
const finished = yield* store
|
|
234
|
+
.finishAttempt(open.value.attempt, open.value.result)
|
|
235
|
+
.pipe(retryingStore(runId, "finish the attempt"));
|
|
236
|
+
if (finished._tag !== "RetryAttempt")
|
|
237
|
+
return finished._tag;
|
|
238
|
+
}
|
|
239
|
+
const started = yield* store
|
|
240
|
+
.beginAttempt(runId, worker, Option.map(reattaching(open), ({ id }) => id))
|
|
241
|
+
.pipe(retryingStore(runId, "begin the attempt"));
|
|
242
|
+
if (started._tag === "AttemptRecoveryFailed")
|
|
243
|
+
return "RunFailed";
|
|
244
|
+
if (started._tag === "RunClosed")
|
|
245
|
+
return "Unchanged";
|
|
246
|
+
// An executor defect becomes a `DefectFailure`, which isn't retried automatically (ADR 0003).
|
|
247
|
+
const result = yield* executor
|
|
248
|
+
.execute(started.execution, {
|
|
249
|
+
append: (direction, envelope) => store.appendTranscript(direction, envelope).pipe(asAttemptFailure),
|
|
250
|
+
salvage: (salvage) => store.recordSalvage(started.execution.attempt.id, salvage).pipe(asAttemptFailure),
|
|
251
|
+
comments: (comments) => store.recordComments(started.execution.attempt.id, comments).pipe(asAttemptFailure),
|
|
252
|
+
outOfMemory: (kills) => store.recordOutOfMemory(started.execution.attempt.id, kills).pipe(asAttemptFailure),
|
|
253
|
+
windows: store
|
|
254
|
+
.attemptWindows(started.execution.attempt.id)
|
|
255
|
+
.pipe(retryingStore(runId, "read the attempt windows"), asAttemptFailure),
|
|
256
|
+
transcript: store
|
|
257
|
+
.transcript(new TranscriptAllQuery({ attemptId: started.execution.attempt.id }))
|
|
258
|
+
.pipe(retryingStore(runId, "read the attempt transcript"), asAttemptFailure,
|
|
259
|
+
// Reattached Attempts recorded the current protocol version. A version bump must
|
|
260
|
+
// convert retired envelopes here for Attempts open across the upgrade.
|
|
261
|
+
Effect.map((entries) => entries.flatMap(({ envelope }) => envelope.version === AttemptChannel.PROTOCOL_VERSION ? [envelope] : []))),
|
|
262
|
+
// Until this point, the driver reconciles a checkout that startup kept, for example on
|
|
263
|
+
// a cancel (#180).
|
|
264
|
+
checkoutAcquired: checkouts.acquired(started.execution.attempt.id),
|
|
265
|
+
})
|
|
266
|
+
.pipe(Effect.catchDefect((defect) => Effect.logError("Step executor defect; operator intervention required", {
|
|
267
|
+
runId,
|
|
268
|
+
attemptId: started.execution.attempt.id,
|
|
269
|
+
defect: defect instanceof Error ? defect.message : String(defect),
|
|
270
|
+
}).pipe(Effect.andThen(new DefectFailure({
|
|
271
|
+
message: "The step executor crashed with an unexpected error",
|
|
272
|
+
cause: defect,
|
|
273
|
+
})))), Effect.result);
|
|
274
|
+
if (started.execution.reattach && Result.isFailure(result)) {
|
|
275
|
+
// Reconcile a reattach that failed before acquiring the kept checkout, such as on a
|
|
276
|
+
// credential error, so the next Attempt resumes from its salvage. `reconcile` does nothing
|
|
277
|
+
// once the checkout was acquired, and fails this fiber while the stop is unconfirmed.
|
|
278
|
+
yield* checkouts.reconcile(started.execution.attempt.id, "failed");
|
|
279
|
+
}
|
|
280
|
+
// Before the Attempt closes, so a cancel meanwhile still finds it open and keeps its slot.
|
|
281
|
+
if (Result.isFailure(result))
|
|
282
|
+
yield* confirmStopAfterFailure({
|
|
283
|
+
attemptId: started.execution.attempt.id,
|
|
284
|
+
runId,
|
|
285
|
+
loop: submission.loop,
|
|
286
|
+
itemKey: submission.itemKey,
|
|
287
|
+
reason: "failed",
|
|
288
|
+
}, worker);
|
|
289
|
+
const finished = yield* store
|
|
290
|
+
.finishAttempt(started.execution.attempt, result)
|
|
291
|
+
.pipe(retryingStore(runId, "finish the attempt"));
|
|
292
|
+
return finished._tag;
|
|
293
|
+
});
|
|
294
|
+
// `launch` traces it as the root span of the Run's own trace.
|
|
295
|
+
const drive = Effect.fnUntraced(function* (runId) {
|
|
296
|
+
const submission = yield* store
|
|
297
|
+
.submission(runId)
|
|
298
|
+
.pipe(retryingStore(runId, "read the run's submission"));
|
|
299
|
+
yield* Effect.annotateCurrentSpan({
|
|
300
|
+
runId,
|
|
301
|
+
loop: submission.loop,
|
|
302
|
+
itemKey: submission.itemKey,
|
|
303
|
+
});
|
|
304
|
+
if (submission.approval === "required" &&
|
|
305
|
+
(yield* store
|
|
306
|
+
.parkForApproval(runId)
|
|
307
|
+
.pipe(retryingStore(runId, "park the run for approval")))._tag === "Waiting") {
|
|
308
|
+
yield* Effect.logInfo("Run waits for its approval", { runId });
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
let outcome;
|
|
312
|
+
do {
|
|
313
|
+
// A reattached Attempt uses a slot on the Worker it started on (#177).
|
|
314
|
+
const open = yield* openAttempt(runId);
|
|
315
|
+
if (Option.isSome(open) && open.value._tag !== "Live") {
|
|
316
|
+
// Reconcile before waiting for a slot, so the next Attempt resumes from the salvage and
|
|
317
|
+
// the slot startup occupied is freed. If the stop can't be confirmed, this fiber fails
|
|
318
|
+
// and keeps the slot; the next reconcile drives the Run again.
|
|
319
|
+
yield* checkouts.reconcile(open.value.attempt.id, "startup");
|
|
320
|
+
}
|
|
321
|
+
// A reattachment starts no parent task, so only a new Attempt waits for the stop.
|
|
322
|
+
if (Option.isNone(reattaching(open))) {
|
|
323
|
+
const blocking = yield* stopBlocking(submission);
|
|
324
|
+
if (Option.isSome(blocking)) {
|
|
325
|
+
// `reconcile` retries the stop, then starts a fiber for this Run again.
|
|
326
|
+
yield* Effect.logInfo("The Run starts no Attempt while the parent task of an earlier Attempt on its Loop's Item is not confirmed stopped; each reconcile tries that stop again, then drives the Run", {
|
|
327
|
+
runId,
|
|
328
|
+
loop: submission.loop,
|
|
329
|
+
itemKey: submission.itemKey,
|
|
330
|
+
unstoppedAttemptId: blocking.value.attemptId,
|
|
331
|
+
unstoppedRunId: blocking.value.runId,
|
|
332
|
+
worker: blocking.value.worker,
|
|
333
|
+
reason: blocking.value.reason,
|
|
334
|
+
});
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
// Only the slot wait is interruptible, so a cancel can stop a Run in `reserve`; the
|
|
339
|
+
// scheduler releases or reoffers the slot on interrupt. `releaseSlot` runs once the
|
|
340
|
+
// lease exists.
|
|
341
|
+
outcome = yield* Effect.uninterruptibleMask((restore) => slotFor(runId, submission, open, restore).pipe(Effect.tap(({ lease }) => Ref.update(slots, (held) => new Map(held).set(runId, lease))), Effect.flatMap(({ lease, open: current }) => restore(admission.withAttempt(runId, executeAttempt(runId, submission, lease.worker, current))).pipe(Effect.ensuring(releaseSlot(runId, lease))))));
|
|
342
|
+
} while (outcome === "RetryAttempt");
|
|
343
|
+
// Cancel, supersede, and revoke handle the Item's queued Events themselves and can
|
|
344
|
+
// interrupt this fiber at any point.
|
|
345
|
+
if (outcome === "Unchanged") {
|
|
346
|
+
yield* Effect.logInfo("Run closed by another operation; its fiber ends", { runId });
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
yield* continueWithNewest(runId);
|
|
350
|
+
});
|
|
351
|
+
const holdSlot = Effect.fn("RunDriver.holdSlot")(function* (runId, attemptId) {
|
|
352
|
+
yield* Effect.annotateCurrentSpan({ runId, attemptId });
|
|
353
|
+
const lease = yield* Ref.modify(slots, (held) => [
|
|
354
|
+
Option.fromUndefinedOr(held.get(runId)),
|
|
355
|
+
without(held, runId),
|
|
356
|
+
]);
|
|
357
|
+
if (Option.isNone(lease)) {
|
|
358
|
+
yield* Effect.logDebug("The Run's fiber holds no slot in this process; no slot moves to its Attempt", { runId, attemptId });
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
yield* checkouts.hold(attemptId, lease.value);
|
|
362
|
+
}, Effect.uninterruptible);
|
|
363
|
+
/** Records `stop` for `reconcile` to retry, keeping the first record of its Attempt. */
|
|
364
|
+
const recordUnconfirmed = (stop) => Ref.update(unconfirmed, (stops) => stops.has(stop.attemptId) ? stops : new Map(stops).set(stop.attemptId, stop));
|
|
365
|
+
/**
|
|
366
|
+
* Confirms through `StepExecutor.interrupt` that the parent task of the Attempt of `stop`,
|
|
367
|
+
* which failed on `worker`, stopped. The executor stops the task when an Attempt fails but
|
|
368
|
+
* doesn't report whether the stop succeeded. If the stop isn't confirmed, the Attempt keeps
|
|
369
|
+
* the Run's slot, as on a cancel, no Run of the Loop on the Item starts an Attempt, and each
|
|
370
|
+
* `reconcile` retries the stop (#512, #523).
|
|
371
|
+
*/
|
|
372
|
+
const confirmStopAfterFailure = Effect.fn("RunDriver.confirmStopAfterFailure")(function* (stop, worker) {
|
|
373
|
+
const { attemptId, runId } = stop;
|
|
374
|
+
const fields = { runId, attemptId, worker, reason: stop.reason };
|
|
375
|
+
yield* Effect.annotateCurrentSpan(fields);
|
|
376
|
+
const stopped = yield* executor.interrupt(attemptId, stop.reason).pipe(Effect.result);
|
|
377
|
+
if (Result.isSuccess(stopped)) {
|
|
378
|
+
yield* Effect.logDebug("The parent task of the failed Attempt is confirmed stopped; the Run's slot is freed", fields);
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
yield* Effect.logWarning("Could not confirm that the parent task of the failed Attempt stopped; the Attempt keeps its Run's slot, no Attempt starts on its Loop's Item, and each reconcile tries the stop again", { ...fields, errorTag: stopped.failure._tag, message: stopped.failure.message });
|
|
382
|
+
yield* holdSlot(runId, attemptId).pipe(Effect.andThen(recordUnconfirmed(new UnconfirmedStop({ ...stop, worker }))), Effect.uninterruptible);
|
|
383
|
+
});
|
|
384
|
+
/** Returns the unconfirmed stop that keeps the Run of `submission` from starting an Attempt. */
|
|
385
|
+
const stopBlocking = (submission) => Ref.get(unconfirmed).pipe(Effect.map((stops) => Option.fromUndefinedOr([...stops.values()].find(({ loop, itemKey }) => loop === submission.loop && itemKey === submission.itemKey))));
|
|
386
|
+
const releaseKept = Effect.fn("RunDriver.releaseKept")(function* (stop) {
|
|
387
|
+
const { attemptId, runId, reason } = stop;
|
|
388
|
+
yield* Effect.annotateCurrentSpan({ runId, attemptId, reason });
|
|
389
|
+
const stopped = yield* checkouts.reconcile(attemptId, reason).pipe(Effect.result);
|
|
390
|
+
if (Result.isSuccess(stopped)) {
|
|
391
|
+
const recorded = yield* Ref.modify(unconfirmed, (stops) => [
|
|
392
|
+
stops.has(attemptId),
|
|
393
|
+
without(stops, attemptId),
|
|
394
|
+
]);
|
|
395
|
+
if (recorded)
|
|
396
|
+
yield* Effect.logInfo("The parent task of a closed Attempt is confirmed stopped; Runs on its Loop's Item start Attempts again", { runId, attemptId, loop: stop.loop, itemKey: stop.itemKey, reason });
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
const { worker } = stopped.failure;
|
|
400
|
+
yield* Effect.annotateCurrentSpan({ worker });
|
|
401
|
+
yield* recordUnconfirmed(new UnconfirmedStop({ ...stop, worker }));
|
|
402
|
+
yield* Effect.logWarning("The parent task of a closed Attempt is not confirmed stopped; its Worker's slot, and any checkout startup kept, stay kept, no Attempt starts on its Loop's Item, and the next reconcile tries the stop again", { runId, attemptId, worker, loop: stop.loop, itemKey: stop.itemKey, reason });
|
|
403
|
+
});
|
|
404
|
+
const recoverWorkspaces = Effect.fn("RunDriver.recoverWorkspaces")(function* () {
|
|
405
|
+
// Closed Attempts whose parent task stop wasn't confirmed before the restart.
|
|
406
|
+
const unstopped = yield* checkouts.atStartup();
|
|
407
|
+
yield* Effect.forEach(unstopped, ({ attemptId, runId, loop, itemKey, worker }) => recordUnconfirmed(new UnconfirmedStop({ attemptId, runId, loop, itemKey, worker, reason: "startup" })), { discard: true });
|
|
408
|
+
});
|
|
409
|
+
const reconcile = Effect.fn("RunDriver.reconcile")(function* () {
|
|
410
|
+
// No Run fiber retries these stops, so reconcile does, before it starts the fibers they
|
|
411
|
+
// keep from starting an Attempt.
|
|
412
|
+
const unstopped = [...(yield* Ref.get(unconfirmed)).values()];
|
|
413
|
+
yield* Effect.forEach(unstopped, releaseKept, { discard: true });
|
|
414
|
+
const continuations = yield* store.pendingContinuations;
|
|
415
|
+
yield* Effect.forEach(continuations, (runId) => continueWithNewest(runId).pipe(Effect.tapError((error) => Effect.logError("Could not continue the queued Events behind a closed Run", {
|
|
416
|
+
runId,
|
|
417
|
+
errorTag: error._tag,
|
|
418
|
+
})), Effect.ignore), { discard: true });
|
|
419
|
+
const driven = yield* store.runIdsToDrive;
|
|
420
|
+
const withoutFiber = yield* Effect.filter(driven, (runId) => Effect.map(FiberMap.has(fibers, runId), (running) => !running));
|
|
421
|
+
yield* Effect.forEach(withoutFiber, launch, { discard: true });
|
|
422
|
+
// After the stops above, so a machine whose stop they confirmed is released before it.
|
|
423
|
+
yield* executor.sweep;
|
|
424
|
+
const fields = {
|
|
425
|
+
continuedAfterRunIds: continuations,
|
|
426
|
+
startedRunIds: withoutFiber,
|
|
427
|
+
drivenRunIds: driven.length,
|
|
428
|
+
retriedStopAttemptIds: unstopped.map(({ attemptId }) => attemptId),
|
|
429
|
+
};
|
|
430
|
+
if (continuations.length === 0 && withoutFiber.length === 0 && unstopped.length === 0)
|
|
431
|
+
yield* Effect.logDebug("Every Run to drive already has its fiber", fields);
|
|
432
|
+
else
|
|
433
|
+
yield* Effect.logInfo("Runs recovered from the run tables", fields);
|
|
434
|
+
});
|
|
435
|
+
return {
|
|
436
|
+
launch,
|
|
437
|
+
resume,
|
|
438
|
+
stop,
|
|
439
|
+
continueWithNewest,
|
|
440
|
+
reconcile,
|
|
441
|
+
recoverWorkspaces,
|
|
442
|
+
holdSlot,
|
|
443
|
+
releaseKept,
|
|
444
|
+
unconfirmedStops: Ref.get(unconfirmed).pipe(Effect.map((stops) => [...stops.values()])),
|
|
445
|
+
};
|
|
446
|
+
}));
|
|
447
|
+
}
|
|
448
|
+
//# sourceMappingURL=run-driver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-driver.js","sourceRoot":"","sources":["../../src/engine/run-driver.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { Context, Deferred } from "effect";
|
|
2
2
|
declare const RunEngineShutdown_base: Context.ServiceClass<RunEngineShutdown, "@usine/engine/RunEngineShutdown", Deferred.Deferred<void, never>>;
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* Completing it closes Attempt admission even
|
|
6
|
-
*
|
|
7
|
-
* Allocate a fresh latch for each runtime; it cannot be reopened (ADR 0023).
|
|
4
|
+
* An optional shutdown latch owned by the host, provided before building an engine runtime.
|
|
5
|
+
* Completing it closes Attempt admission, even during startup recovery. It can't be reopened,
|
|
6
|
+
* so each runtime needs a new one (ADR 0023).
|
|
8
7
|
*/
|
|
9
8
|
export declare class RunEngineShutdown extends RunEngineShutdown_base {
|
|
10
9
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shutdown.d.ts","sourceRoot":"","sources":["../../src/engine/shutdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;;AAE3C
|
|
1
|
+
{"version":3,"file":"shutdown.d.ts","sourceRoot":"","sources":["../../src/engine/shutdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;;AAE3C;;;;GAIG;AACH,qBAAa,iBAAkB,SAAQ,sBAGD;CAAG"}
|
package/dist/engine/shutdown.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { Context, Deferred } from "effect";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
* Completing it closes Attempt admission even
|
|
5
|
-
*
|
|
6
|
-
* Allocate a fresh latch for each runtime; it cannot be reopened (ADR 0023).
|
|
3
|
+
* An optional shutdown latch owned by the host, provided before building an engine runtime.
|
|
4
|
+
* Completing it closes Attempt admission, even during startup recovery. It can't be reopened,
|
|
5
|
+
* so each runtime needs a new one (ADR 0023).
|
|
7
6
|
*/
|
|
8
7
|
export class RunEngineShutdown extends Context.Service()("@usine/engine/RunEngineShutdown") {
|
|
9
8
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../../src/engine/shutdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAE3C
|
|
1
|
+
{"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../../src/engine/shutdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAE3C;;;;GAIG;AACH,MAAM,OAAO,iBAAkB,SAAQ,OAAO,CAAC,OAAO,EAGnD,CAAC,iCAAiC,CAAC;CAAG"}
|