@blokjs/runner 0.2.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Configuration.d.ts +18 -0
- package/dist/Configuration.js +151 -4
- package/dist/Configuration.js.map +1 -1
- package/dist/PayloadTooLargeError.d.ts +19 -0
- package/dist/PayloadTooLargeError.js +29 -0
- package/dist/PayloadTooLargeError.js.map +1 -0
- package/dist/RunCancelledError.d.ts +17 -0
- package/dist/RunCancelledError.js +25 -0
- package/dist/RunCancelledError.js.map +1 -0
- package/dist/RunnerSteps.js +330 -33
- package/dist/RunnerSteps.js.map +1 -1
- package/dist/SubworkflowNode.d.ts +75 -0
- package/dist/SubworkflowNode.js +221 -0
- package/dist/SubworkflowNode.js.map +1 -0
- package/dist/TriggerBase.d.ts +128 -0
- package/dist/TriggerBase.js +773 -4
- package/dist/TriggerBase.js.map +1 -1
- package/dist/WaitDispatchRequest.d.ts +38 -0
- package/dist/WaitDispatchRequest.js +13 -0
- package/dist/WaitDispatchRequest.js.map +1 -0
- package/dist/WaitNode.d.ts +23 -0
- package/dist/WaitNode.js +26 -0
- package/dist/WaitNode.js.map +1 -0
- package/dist/concurrency/ConcurrencyBackend.d.ts +61 -0
- package/dist/concurrency/ConcurrencyBackend.js +20 -0
- package/dist/concurrency/ConcurrencyBackend.js.map +1 -0
- package/dist/concurrency/ConcurrencyLimitError.d.ts +37 -0
- package/dist/concurrency/ConcurrencyLimitError.js +16 -0
- package/dist/concurrency/ConcurrencyLimitError.js.map +1 -0
- package/dist/concurrency/NatsKvConcurrencyBackend.d.ts +64 -0
- package/dist/concurrency/NatsKvConcurrencyBackend.js +297 -0
- package/dist/concurrency/NatsKvConcurrencyBackend.js.map +1 -0
- package/dist/concurrency/QueueExpiredError.d.ts +40 -0
- package/dist/concurrency/QueueExpiredError.js +15 -0
- package/dist/concurrency/QueueExpiredError.js.map +1 -0
- package/dist/concurrency/createConcurrencyBackend.d.ts +23 -0
- package/dist/concurrency/createConcurrencyBackend.js +34 -0
- package/dist/concurrency/createConcurrencyBackend.js.map +1 -0
- package/dist/concurrency/readConcurrencyConfig.d.ts +60 -0
- package/dist/concurrency/readConcurrencyConfig.js +60 -0
- package/dist/concurrency/readConcurrencyConfig.js.map +1 -0
- package/dist/idempotency/resolveIdempotencyKey.d.ts +20 -0
- package/dist/idempotency/resolveIdempotencyKey.js +37 -0
- package/dist/idempotency/resolveIdempotencyKey.js.map +1 -0
- package/dist/index.d.ts +23 -3
- package/dist/index.js +47 -2
- package/dist/index.js.map +1 -1
- package/dist/monitoring/ConcurrencyMetrics.d.ts +56 -0
- package/dist/monitoring/ConcurrencyMetrics.js +107 -0
- package/dist/monitoring/ConcurrencyMetrics.js.map +1 -0
- package/dist/monitoring/JanitorMetrics.d.ts +27 -0
- package/dist/monitoring/JanitorMetrics.js +48 -0
- package/dist/monitoring/JanitorMetrics.js.map +1 -0
- package/dist/scheduling/DebounceCoordinator.d.ts +88 -0
- package/dist/scheduling/DebounceCoordinator.js +141 -0
- package/dist/scheduling/DebounceCoordinator.js.map +1 -0
- package/dist/scheduling/DeferredDispatchSignal.d.ts +50 -0
- package/dist/scheduling/DeferredDispatchSignal.js +14 -0
- package/dist/scheduling/DeferredDispatchSignal.js.map +1 -0
- package/dist/scheduling/DeferredRunScheduler.d.ts +68 -0
- package/dist/scheduling/DeferredRunScheduler.js +154 -0
- package/dist/scheduling/DeferredRunScheduler.js.map +1 -0
- package/dist/scheduling/readSchedulingConfig.d.ts +24 -0
- package/dist/scheduling/readSchedulingConfig.js +52 -0
- package/dist/scheduling/readSchedulingConfig.js.map +1 -0
- package/dist/timeouts/StepTimeoutError.d.ts +22 -0
- package/dist/timeouts/StepTimeoutError.js +31 -0
- package/dist/timeouts/StepTimeoutError.js.map +1 -0
- package/dist/tracing/InMemoryRunStore.d.ts +28 -1
- package/dist/tracing/InMemoryRunStore.js +150 -0
- package/dist/tracing/InMemoryRunStore.js.map +1 -1
- package/dist/tracing/Janitor.d.ts +70 -0
- package/dist/tracing/Janitor.js +150 -0
- package/dist/tracing/Janitor.js.map +1 -0
- package/dist/tracing/PostgresRunStore.d.ts +30 -0
- package/dist/tracing/PostgresRunStore.js +435 -3
- package/dist/tracing/PostgresRunStore.js.map +1 -1
- package/dist/tracing/RunStore.d.ts +100 -1
- package/dist/tracing/RunTracker.d.ts +238 -9
- package/dist/tracing/RunTracker.js +571 -1
- package/dist/tracing/RunTracker.js.map +1 -1
- package/dist/tracing/SqliteRunStore.d.ts +23 -1
- package/dist/tracing/SqliteRunStore.js +405 -6
- package/dist/tracing/SqliteRunStore.js.map +1 -1
- package/dist/tracing/TraceRouter.d.ts +20 -2
- package/dist/tracing/TraceRouter.js +249 -5
- package/dist/tracing/TraceRouter.js.map +1 -1
- package/dist/tracing/sanitize.d.ts +11 -0
- package/dist/tracing/sanitize.js +29 -0
- package/dist/tracing/sanitize.js.map +1 -1
- package/dist/tracing/types.d.ts +348 -2
- package/dist/utils/createChildContext.d.ts +32 -0
- package/dist/utils/createChildContext.js +113 -0
- package/dist/utils/createChildContext.js.map +1 -0
- package/dist/workflow/WorkflowNormalizer.d.ts +29 -41
- package/dist/workflow/WorkflowNormalizer.js +182 -0
- package/dist/workflow/WorkflowNormalizer.js.map +1 -1
- package/dist/workflow/WorkflowRegistry.d.ts +64 -0
- package/dist/workflow/WorkflowRegistry.js +81 -0
- package/dist/workflow/WorkflowRegistry.js.map +1 -0
- package/package.json +3 -3
package/dist/RunnerSteps.js
CHANGED
|
@@ -1,6 +1,58 @@
|
|
|
1
1
|
import { GlobalError } from "@blokjs/shared";
|
|
2
|
+
import { RunCancelledError } from "./RunCancelledError";
|
|
3
|
+
import { WaitDispatchRequest } from "./WaitDispatchRequest";
|
|
4
|
+
import { resolveIdempotencyKey } from "./idempotency/resolveIdempotencyKey";
|
|
5
|
+
import { StepTimeoutError } from "./timeouts/StepTimeoutError";
|
|
2
6
|
import { RunTracker } from "./tracing/RunTracker";
|
|
3
7
|
import { sanitize } from "./tracing/sanitize";
|
|
8
|
+
import { applyStepOutput } from "./workflow/PersistenceHelper";
|
|
9
|
+
/**
|
|
10
|
+
* Default TTL for idempotency cache entries when the step author does not
|
|
11
|
+
* pass `idempotencyKeyTTL` explicitly. 24 hours, matching Trigger.dev's
|
|
12
|
+
* default and the decision recorded in the Tier 1 ROADMAP session.
|
|
13
|
+
*/
|
|
14
|
+
const DEFAULT_IDEMPOTENCY_TTL_MS = 24 * 60 * 60 * 1000;
|
|
15
|
+
/**
|
|
16
|
+
* Compute the delay before retry attempt N+1 using capped exponential
|
|
17
|
+
* backoff. Mirrors Trigger.dev's `retry` semantics — no jitter by default.
|
|
18
|
+
*
|
|
19
|
+
* `delay = min(maxTimeoutInMs, minTimeoutInMs * factor^(attempt - 1))`
|
|
20
|
+
*
|
|
21
|
+
* Defaults: min=1000, max=30000, factor=2 — same as Trigger.dev.
|
|
22
|
+
*/
|
|
23
|
+
function computeBackoff(config, attempt) {
|
|
24
|
+
const min = config.minTimeoutInMs ?? 1000;
|
|
25
|
+
const max = config.maxTimeoutInMs ?? 30000;
|
|
26
|
+
const factor = config.factor ?? 2;
|
|
27
|
+
const raw = min * factor ** Math.max(0, attempt - 1);
|
|
28
|
+
return Math.min(max, Math.floor(raw));
|
|
29
|
+
}
|
|
30
|
+
function sleep(ms) {
|
|
31
|
+
return new Promise((resolve) => {
|
|
32
|
+
setTimeout(resolve, ms);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Tier 2 quick-wins — wrap a Promise in a setTimeout-based timeout
|
|
37
|
+
* race. On timeout, rejects with `StepTimeoutError`. The underlying
|
|
38
|
+
* `fn()` continues to run (no AbortSignal cancellation in v1) but
|
|
39
|
+
* the runner has already moved on — orphaned resolution settles
|
|
40
|
+
* harmlessly into the void.
|
|
41
|
+
*/
|
|
42
|
+
function wrapWithTimeout(fn, ms, stepName) {
|
|
43
|
+
return new Promise((resolve, reject) => {
|
|
44
|
+
const timer = setTimeout(() => {
|
|
45
|
+
reject(new StepTimeoutError(stepName, ms));
|
|
46
|
+
}, ms);
|
|
47
|
+
fn().then((value) => {
|
|
48
|
+
clearTimeout(timer);
|
|
49
|
+
resolve(value);
|
|
50
|
+
}, (err) => {
|
|
51
|
+
clearTimeout(timer);
|
|
52
|
+
reject(err);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
}
|
|
4
56
|
export default class RunnerSteps {
|
|
5
57
|
/**
|
|
6
58
|
* Executes a series of steps in the given context.
|
|
@@ -23,8 +75,34 @@ export default class RunnerSteps {
|
|
|
23
75
|
let flow_steps = [];
|
|
24
76
|
let flow_step = 0;
|
|
25
77
|
let stepName = "";
|
|
78
|
+
// PR 4 — wait.for / wait.until resume cursor.
|
|
79
|
+
//
|
|
80
|
+
// On `dispatchDeferred` re-entry from a wait step, the runner
|
|
81
|
+
// must skip past pre-wait steps that already completed in the
|
|
82
|
+
// previous pass. `lastCompletedStepIndex` is set on the run
|
|
83
|
+
// record before each WaitDispatchRequest throw and read here
|
|
84
|
+
// at runSteps entry. Default `-1` = no resume; runner starts
|
|
85
|
+
// at i = 0.
|
|
86
|
+
const persistedRun = !deep && tracker && traceRunId ? tracker.getStore().getRun(traceRunId) : undefined;
|
|
87
|
+
const resumeFromIndex = persistedRun?.lastCompletedStepIndex !== undefined ? persistedRun.lastCompletedStepIndex + 1 : 0;
|
|
26
88
|
for (let i = 0; i < steps.length; i++) {
|
|
27
89
|
const step = steps[i];
|
|
90
|
+
// PR 4 — skip pre-wait steps on resume. State + NodeRuns
|
|
91
|
+
// from the first pass are still on `ctx.state` / in the
|
|
92
|
+
// store; the runner just advances past them.
|
|
93
|
+
if (i < resumeFromIndex) {
|
|
94
|
+
ctx.logger.log(`[step ${i + 1}/${steps.length}] ${step.name} → skipped (resumed past wait at lastCompletedStepIndex=${persistedRun?.lastCompletedStepIndex})`);
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
// Tier 2 follow-up · cooperative cancellation. Operators can
|
|
98
|
+
// abort `running` runs via `POST /__blok/runs/:runId/cancel`,
|
|
99
|
+
// which fires the ctx's AbortController. The check is between
|
|
100
|
+
// steps so a long-running step's `step.process()` doesn't have
|
|
101
|
+
// to consult the signal itself (though nodes that want finer
|
|
102
|
+
// granularity can read `ctx.signal.aborted` themselves).
|
|
103
|
+
if (ctx.signal?.aborted) {
|
|
104
|
+
throw new RunCancelledError(traceRunId);
|
|
105
|
+
}
|
|
28
106
|
if (!step.active) {
|
|
29
107
|
// Track skipped nodes
|
|
30
108
|
if (tracker && traceRunId) {
|
|
@@ -61,6 +139,19 @@ export default class RunnerSteps {
|
|
|
61
139
|
};
|
|
62
140
|
if (tracker && traceRunId) {
|
|
63
141
|
const configAny = ctx.config;
|
|
142
|
+
// Tier 2 #4 sub-workflow: capture the `wait` mode so
|
|
143
|
+
// Studio can render `↳ async` (wait:false) vs `↳ sub`
|
|
144
|
+
// (wait:true / default) in StepRail. Only meaningful
|
|
145
|
+
// for subworkflow steps; undefined elsewhere.
|
|
146
|
+
const subworkflowWait = stepType === "subworkflow" ? stepAny.wait : undefined;
|
|
147
|
+
// PR 5 E3 — surface sub-workflow nesting depth.
|
|
148
|
+
// `_subworkflowDepth` on ctx is set by SubworkflowNode +
|
|
149
|
+
// createChildContext; the parent's invocation of a
|
|
150
|
+
// child step has depth = parent.depth + 1. Top-level =
|
|
151
|
+
// 1; nested = 2+. Only meaningful for subworkflow steps.
|
|
152
|
+
const subworkflowDepth = stepType === "subworkflow"
|
|
153
|
+
? (ctx._subworkflowDepth ?? 0) + 1
|
|
154
|
+
: undefined;
|
|
64
155
|
const nodeRun = tracker.startNode(traceRunId, {
|
|
65
156
|
nodeName: step.name,
|
|
66
157
|
nodeType: stepType,
|
|
@@ -68,29 +159,176 @@ export default class RunnerSteps {
|
|
|
68
159
|
inputs: sanitize(configAny?.[step.name]?.inputs ?? stepAny.config),
|
|
69
160
|
depth: depthLevel,
|
|
70
161
|
stepIndex: i,
|
|
162
|
+
wait: subworkflowWait,
|
|
163
|
+
subworkflowDepth,
|
|
71
164
|
});
|
|
72
165
|
nodeRunId = nodeRun.id;
|
|
73
166
|
ctx._traceNodeId = nodeRunId;
|
|
74
167
|
}
|
|
168
|
+
// === PR 4: wait.for(duration) / wait.until(date) step ===
|
|
169
|
+
// Two paths:
|
|
170
|
+
// 1. First pass: compute deadline, mark NodeRun complete
|
|
171
|
+
// (the wait step has no `process()` body), set the
|
|
172
|
+
// run's resume cursor (lastCompletedStepIndex = i - 1),
|
|
173
|
+
// throw WaitDispatchRequest. TriggerBase translates to
|
|
174
|
+
// DeferredDispatchSignal → 202 Accepted.
|
|
175
|
+
// 2. Re-entry (dispatchDeferred): the resume cursor logic
|
|
176
|
+
// at the top of runSteps already skipped indices < i.
|
|
177
|
+
// For the wait step itself at i = lastCompletedStepIndex
|
|
178
|
+
// + 1, treat it as satisfied and advance.
|
|
179
|
+
// Detection: existence of run.scheduledAt + wait step =
|
|
180
|
+
// we're on the second pass.
|
|
181
|
+
if (stepType === "wait") {
|
|
182
|
+
const waitForMs = stepAny.waitForMs;
|
|
183
|
+
const waitUntil = stepAny.waitUntil;
|
|
184
|
+
// Compute the deadline (resolves $-proxy and ISO strings).
|
|
185
|
+
// Review fix-up · BUG-2. A malformed `until` string used to
|
|
186
|
+
// silently fall through to `Date.now()` (immediate no-op).
|
|
187
|
+
// Authors expecting "wait until tomorrow" with a typo got a
|
|
188
|
+
// no-op with no warning — the worst kind of footgun. Throw
|
|
189
|
+
// instead so the failure surfaces immediately, both in the
|
|
190
|
+
// run trace + Studio's error surface.
|
|
191
|
+
const computeDeadline = () => {
|
|
192
|
+
if (typeof waitForMs === "number")
|
|
193
|
+
return Date.now() + waitForMs;
|
|
194
|
+
if (typeof waitUntil === "number")
|
|
195
|
+
return waitUntil;
|
|
196
|
+
if (typeof waitUntil === "string") {
|
|
197
|
+
// Try parsing as a number first (ms-since-epoch as a string).
|
|
198
|
+
const asNum = Number(waitUntil);
|
|
199
|
+
if (!Number.isNaN(asNum))
|
|
200
|
+
return asNum;
|
|
201
|
+
// ISO-date string.
|
|
202
|
+
const t = Date.parse(waitUntil);
|
|
203
|
+
if (!Number.isNaN(t))
|
|
204
|
+
return t;
|
|
205
|
+
// Fail-fast on unparseable strings (the helpful path).
|
|
206
|
+
throw new Error(`wait.until: cannot parse '${waitUntil}' as a number or date. Use ms-since-epoch (number or numeric string) or a valid ISO date string.`);
|
|
207
|
+
}
|
|
208
|
+
// Schema rejects this combination, but defensive: treat
|
|
209
|
+
// unsupported input as immediate so the runner doesn't
|
|
210
|
+
// hang on a never-firing timer.
|
|
211
|
+
return Date.now();
|
|
212
|
+
};
|
|
213
|
+
// Detect re-entry: on first pass the run has no
|
|
214
|
+
// scheduledAt (or it's from trigger-level delay); on
|
|
215
|
+
// re-entry from a wait dispatch, the run was marked
|
|
216
|
+
// `delayed` with scheduledAt set to the wait deadline.
|
|
217
|
+
const isReentry = ctx._blokDispatchReentry === true &&
|
|
218
|
+
resumeFromIndex > 0 &&
|
|
219
|
+
i === resumeFromIndex;
|
|
220
|
+
const deadline = computeDeadline();
|
|
221
|
+
const now = Date.now();
|
|
222
|
+
if (isReentry || deadline <= now) {
|
|
223
|
+
// Wait already satisfied (timer fired AND we're on
|
|
224
|
+
// re-entry past the deadline) OR the deadline is
|
|
225
|
+
// in the past (e.g., wait.for(0) or wait.until(<past>)).
|
|
226
|
+
// Mark NodeRun complete and advance.
|
|
227
|
+
if (tracker && nodeRunId) {
|
|
228
|
+
tracker.completeNode(nodeRunId, { __waited__: true, deadline });
|
|
229
|
+
}
|
|
230
|
+
ctx.logger.log(`[step ${i + 1}/${steps.length}] ${step.name} (wait) → satisfied`);
|
|
231
|
+
// Advance the resume cursor so a subsequent wait at a
|
|
232
|
+
// later index can rely on it.
|
|
233
|
+
if (tracker && traceRunId) {
|
|
234
|
+
tracker.getStore().updateRun(traceRunId, { lastCompletedStepIndex: i });
|
|
235
|
+
}
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
// First pass: schedule + throw WaitDispatchRequest.
|
|
239
|
+
// Set resume cursor BEFORE throwing so re-entry knows
|
|
240
|
+
// where to pick up. Cursor = i - 1 (the last non-wait
|
|
241
|
+
// step that completed).
|
|
242
|
+
if (tracker && traceRunId) {
|
|
243
|
+
tracker.getStore().updateRun(traceRunId, {
|
|
244
|
+
lastCompletedStepIndex: i - 1,
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
ctx.logger.log(`[step ${i + 1}/${steps.length}] ${step.name} (wait) → scheduled (deadline=${new Date(deadline).toISOString()})`);
|
|
248
|
+
throw new WaitDispatchRequest({
|
|
249
|
+
scheduledAt: deadline,
|
|
250
|
+
stepIndex: i,
|
|
251
|
+
stepId: step.name,
|
|
252
|
+
lastCompletedStepIndex: i - 1,
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
// === Tier 1: idempotency cache lookup ===
|
|
256
|
+
// Resolve the step's idempotency key against the live ctx,
|
|
257
|
+
// then consult the cache. On hit, short-circuit step.process
|
|
258
|
+
// entirely: replay the cached result through the same v2
|
|
259
|
+
// persistence rules (ephemeral / spread / as), mark the
|
|
260
|
+
// node cached for tracing, log "cached", and skip to the
|
|
261
|
+
// next step. Caching layers ABOVE PersistenceHelper —
|
|
262
|
+
// applyStepOutput's rules apply identically to cached and
|
|
263
|
+
// freshly-computed results.
|
|
264
|
+
const workflowName = ctx.workflow_name ?? "";
|
|
265
|
+
const cacheStore = tracker && traceRunId ? tracker.getStore() : null;
|
|
266
|
+
const resolvedIdemKey = cacheStore && workflowName ? resolveIdempotencyKey(step.idempotencyKey, ctx) : null;
|
|
267
|
+
if (cacheStore && resolvedIdemKey && nodeRunId) {
|
|
268
|
+
const hit = cacheStore.getIdempotencyCache(workflowName, step.name, resolvedIdemKey);
|
|
269
|
+
if (hit) {
|
|
270
|
+
applyStepOutput(ctx, step, { data: hit.data });
|
|
271
|
+
ctx.response = hit.data;
|
|
272
|
+
tracker?.markNodeCached(nodeRunId, {
|
|
273
|
+
sourceRunId: hit.sourceRunId,
|
|
274
|
+
sourceNodeRunId: hit.sourceNodeRunId,
|
|
275
|
+
cachedAt: hit.cachedAt,
|
|
276
|
+
}, hit.data);
|
|
277
|
+
ctx.logger.log(`${stepPrefix} → cached (from run ${hit.sourceRunId})`);
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
75
281
|
ctx.logger.log(`${stepPrefix} → started`);
|
|
76
282
|
const stepStart = performance.now();
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
283
|
+
// === Tier 1: retry loop ===
|
|
284
|
+
// Wraps step.process() with capped exponential backoff per
|
|
285
|
+
// `step.retry`. Default `maxAttempts: 1` preserves
|
|
286
|
+
// pre-Phase-4 behaviour exactly (single attempt, no retry).
|
|
287
|
+
// Soft errors (model.data.error returned from the SDK)
|
|
288
|
+
// participate in retry alongside thrown errors — both flow
|
|
289
|
+
// through the catch block below.
|
|
290
|
+
const retryConfig = step.retry;
|
|
291
|
+
const maxAttempts = retryConfig ? Math.max(1, retryConfig.maxAttempts) : 1;
|
|
292
|
+
// Tier 2 quick-wins — per-attempt timeout. When unset, the
|
|
293
|
+
// step runs without a cap. Numeric `maxDurationMs` arrives
|
|
294
|
+
// pre-parsed from `Configuration` (string `"30s"` →
|
|
295
|
+
// `30000` via `parseDuration`).
|
|
296
|
+
const maxDurationMs = step.maxDurationMs;
|
|
297
|
+
let attempt = 0;
|
|
298
|
+
while (true) {
|
|
299
|
+
attempt += 1;
|
|
300
|
+
try {
|
|
301
|
+
const processInvocation = () => step.process(ctx, step);
|
|
302
|
+
const model = typeof maxDurationMs === "number" && maxDurationMs > 0
|
|
303
|
+
? await wrapWithTimeout(processInvocation, maxDurationMs, step.name)
|
|
304
|
+
: await processInvocation();
|
|
305
|
+
ctx.response = model.data;
|
|
306
|
+
// Treat soft errors (data carries `.error`) the same as
|
|
307
|
+
// thrown errors so retry semantics are uniform.
|
|
308
|
+
if (ctx.response?.error) {
|
|
309
|
+
throw ctx.response.error;
|
|
310
|
+
}
|
|
311
|
+
// === Tier 1: idempotency cache write ===
|
|
312
|
+
// Cache on the success path only — failed steps are
|
|
313
|
+
// re-runnable. Honour `idempotencyKeyTTL` per step;
|
|
314
|
+
// default 24h. A TTL of 0 stores an immediately-
|
|
315
|
+
// expired entry (useful as a kill-switch).
|
|
316
|
+
if (cacheStore && resolvedIdemKey && nodeRunId && traceRunId) {
|
|
317
|
+
const ttlField = step.idempotencyKeyTTL;
|
|
318
|
+
const ttlMs = typeof ttlField === "number" ? ttlField : DEFAULT_IDEMPOTENCY_TTL_MS;
|
|
319
|
+
const now = Date.now();
|
|
320
|
+
const expiresAt = ttlMs > 0 ? now + ttlMs : now - 1;
|
|
321
|
+
cacheStore.setIdempotencyCache(workflowName, step.name, resolvedIdemKey, {
|
|
322
|
+
data: model.data,
|
|
323
|
+
cachedAt: now,
|
|
324
|
+
expiresAt,
|
|
325
|
+
sourceRunId: traceRunId,
|
|
326
|
+
sourceNodeRunId: nodeRunId,
|
|
327
|
+
});
|
|
92
328
|
}
|
|
93
|
-
|
|
329
|
+
const stepDuration = (performance.now() - stepStart).toFixed(1);
|
|
330
|
+
// --- Trace: complete node ---
|
|
331
|
+
if (tracker && nodeRunId) {
|
|
94
332
|
// `_stepMetrics` is stashed on ctx by RuntimeAdapterNode
|
|
95
333
|
// when an adapter returns metrics (gRPC wire bytes,
|
|
96
334
|
// duration, cpu, memory). Threading it through
|
|
@@ -101,27 +339,69 @@ export default class RunnerSteps {
|
|
|
101
339
|
const stepMetrics = ctxAny._stepMetrics;
|
|
102
340
|
ctxAny._stepMetrics = undefined;
|
|
103
341
|
tracker.completeNode(nodeRunId, sanitize(ctx.response.data), stepMetrics);
|
|
342
|
+
// PR 4 — advance the resume cursor after each
|
|
343
|
+
// successful non-wait step. A subsequent wait step
|
|
344
|
+
// reads this value to set its own cursor before
|
|
345
|
+
// throwing WaitDispatchRequest. Only at top-level
|
|
346
|
+
// (deep=false); nested branch flow doesn't update.
|
|
347
|
+
if (!deep && traceRunId) {
|
|
348
|
+
tracker.getStore().updateRun(traceRunId, { lastCompletedStepIndex: i });
|
|
349
|
+
}
|
|
104
350
|
}
|
|
351
|
+
const attemptSuffix = attempt > 1 ? ` after ${attempt} attempts` : "";
|
|
352
|
+
ctx.logger.log(`${stepPrefix} → completed (${stepDuration}ms${attemptSuffix})`);
|
|
353
|
+
break;
|
|
105
354
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
355
|
+
catch (nodeErr) {
|
|
356
|
+
if (attempt < maxAttempts && retryConfig) {
|
|
357
|
+
// More attempts remain — record this as a soft
|
|
358
|
+
// failure and back off before retrying. The node
|
|
359
|
+
// stays in `running` status; failNode is the
|
|
360
|
+
// terminal call.
|
|
361
|
+
if (tracker && nodeRunId) {
|
|
362
|
+
tracker.recordNodeAttemptFailed(nodeRunId, { attempt, error: nodeErr });
|
|
363
|
+
}
|
|
364
|
+
const backoffMs = computeBackoff(retryConfig, attempt);
|
|
365
|
+
const errMsg = nodeErr instanceof Error ? nodeErr.message : String(nodeErr);
|
|
366
|
+
ctx.logger.log(`${stepPrefix} → attempt ${attempt}/${maxAttempts} failed (${errMsg}), retrying in ${backoffMs}ms`);
|
|
367
|
+
await sleep(backoffMs);
|
|
368
|
+
continue;
|
|
369
|
+
}
|
|
370
|
+
// Final attempt — fail the node and propagate the
|
|
371
|
+
// enriched error so RunnerSteps' outer catch can
|
|
372
|
+
// wrap it as a GlobalError.
|
|
373
|
+
if (tracker && nodeRunId) {
|
|
374
|
+
const existing = tracker.getNodeRun(nodeRunId);
|
|
375
|
+
if (existing && existing.status === "running") {
|
|
376
|
+
tracker.failNode(nodeRunId, nodeErr instanceof Error ? nodeErr : new Error(String(nodeErr)));
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
// Tier 2 quick-wins — final-attempt timeout flips
|
|
380
|
+
// the run to "timedOut" (distinct from "failed").
|
|
381
|
+
// Only when the FINAL error was a StepTimeoutError;
|
|
382
|
+
// mixed failures (some retries timed out, final
|
|
383
|
+
// retry threw a different error) keep the normal
|
|
384
|
+
// "failed" status.
|
|
385
|
+
if (tracker &&
|
|
386
|
+
traceRunId &&
|
|
387
|
+
typeof maxDurationMs === "number" &&
|
|
388
|
+
maxDurationMs > 0 &&
|
|
389
|
+
nodeErr instanceof StepTimeoutError) {
|
|
390
|
+
tracker.markRunTimedOut(traceRunId, {
|
|
391
|
+
stepId: step.name,
|
|
392
|
+
maxDurationMs,
|
|
393
|
+
attemptsExhausted: attempt,
|
|
394
|
+
});
|
|
118
395
|
}
|
|
396
|
+
const stepDuration = (performance.now() - stepStart).toFixed(1);
|
|
397
|
+
const attemptSuffix = attempt > 1 ? ` after ${attempt} attempts` : "";
|
|
398
|
+
ctx.logger.log(`${stepPrefix} → FAILED (${stepDuration}ms${attemptSuffix})`);
|
|
399
|
+
// Enrich error with step context so developers know which step failed
|
|
400
|
+
const originalMsg = nodeErr instanceof Error ? nodeErr.message : String(nodeErr);
|
|
401
|
+
const enrichedError = new Error(`${stepPrefix} failed: ${originalMsg}`);
|
|
402
|
+
enrichedError.cause = nodeErr;
|
|
403
|
+
throw enrichedError;
|
|
119
404
|
}
|
|
120
|
-
// Enrich error with step context so developers know which step failed
|
|
121
|
-
const originalMsg = nodeErr instanceof Error ? nodeErr.message : String(nodeErr);
|
|
122
|
-
const enrichedError = new Error(`${stepPrefix} failed: ${originalMsg}`);
|
|
123
|
-
enrichedError.cause = nodeErr;
|
|
124
|
-
throw enrichedError;
|
|
125
405
|
}
|
|
126
406
|
}
|
|
127
407
|
else {
|
|
@@ -138,6 +418,23 @@ export default class RunnerSteps {
|
|
|
138
418
|
}
|
|
139
419
|
}
|
|
140
420
|
catch (e) {
|
|
421
|
+
// PR 1 follow-up · A2 fix companion. RunCancelledError carries
|
|
422
|
+
// the cancellation contract end-to-end — wrapping it as
|
|
423
|
+
// GlobalError would defeat TriggerBase.run's `instanceof
|
|
424
|
+
// RunCancelledError` discrimination and the run would get
|
|
425
|
+
// failRun'd on top of an already-cancelled status. Pass through
|
|
426
|
+
// untouched so the catch in TriggerBase.run sees the right type.
|
|
427
|
+
if (e instanceof RunCancelledError) {
|
|
428
|
+
throw e;
|
|
429
|
+
}
|
|
430
|
+
// PR 4 — WaitDispatchRequest is the wait.for / wait.until
|
|
431
|
+
// step's signal to TriggerBase that it should schedule a
|
|
432
|
+
// deferred dispatch. Same pass-through rationale as
|
|
433
|
+
// RunCancelledError — the catch in TriggerBase.run translates
|
|
434
|
+
// it to DeferredDispatchSignal + 202.
|
|
435
|
+
if (e instanceof WaitDispatchRequest) {
|
|
436
|
+
throw e;
|
|
437
|
+
}
|
|
141
438
|
let error_context = {};
|
|
142
439
|
if (e instanceof GlobalError) {
|
|
143
440
|
error_context = e;
|
package/dist/RunnerSteps.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RunnerSteps.js","sourceRoot":"","sources":["../src/RunnerSteps.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RunnerSteps.js","sourceRoot":"","sources":["../src/RunnerSteps.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { Context, ResponseContext } from "@blokjs/shared";
|
|
2
|
+
import RunnerNode from "./RunnerNode";
|
|
3
|
+
import type GlobalOptions from "./types/GlobalOptions";
|
|
4
|
+
/**
|
|
5
|
+
* `SubworkflowNode` — the runner-side dispatch primitive that powers
|
|
6
|
+
* the v2 `subworkflow:` step shape. Looks up the named child workflow
|
|
7
|
+
* in the `WorkflowRegistry`, materializes a child `Configuration` +
|
|
8
|
+
* `Runner`, runs the child to completion in its own isolated `Context`,
|
|
9
|
+
* and returns the child's `ctx.response` as this step's `model.data`.
|
|
10
|
+
*
|
|
11
|
+
* **Composition with Tier 1**:
|
|
12
|
+
* - Parent step's `idempotencyKey` is consulted by `RunnerSteps` BEFORE
|
|
13
|
+
* `SubworkflowNode.run` is even called — cache hit short-circuits the
|
|
14
|
+
* entire sub-workflow (no child invocation, no side effects fire).
|
|
15
|
+
* This is the headline pattern AND the documented footgun.
|
|
16
|
+
* - Parent step's `retry` retries the whole sub-workflow on failure;
|
|
17
|
+
* each retry creates a fresh child run record under the same parent.
|
|
18
|
+
* - Replay re-creates fresh sub-run lineage automatically — the new
|
|
19
|
+
* parent run invokes the sub-workflow fresh.
|
|
20
|
+
*
|
|
21
|
+
* **Lineage**: child's `WorkflowRun.parentRunId` and
|
|
22
|
+
* `WorkflowRun.parentNodeRunId` carry the parent run + step that
|
|
23
|
+
* invoked it. Studio renders a "called from #..." breadcrumb on the
|
|
24
|
+
* child and a "Sub-runs" list on the parent.
|
|
25
|
+
*
|
|
26
|
+
* **Recursion guard**: `BLOK_MAX_SUBWORKFLOW_DEPTH` (default 10) bounds
|
|
27
|
+
* cycle / deep-nesting blast radius. Throws a clear error past the cap.
|
|
28
|
+
*/
|
|
29
|
+
export declare class SubworkflowNode extends RunnerNode {
|
|
30
|
+
/**
|
|
31
|
+
* The child workflow's `name:` field — looked up in `WorkflowRegistry`
|
|
32
|
+
* at run time. Set by `Configuration.subworkflowResolver`; this field
|
|
33
|
+
* shadows the inherited `NodeBase.subworkflow` so callers can rely on
|
|
34
|
+
* it being defined.
|
|
35
|
+
*/
|
|
36
|
+
subworkflow: string;
|
|
37
|
+
/**
|
|
38
|
+
* Wait mode for the sub-workflow dispatch:
|
|
39
|
+
*
|
|
40
|
+
* - `true` (default) — synchronous: parent step blocks on the child
|
|
41
|
+
* and the child's `ctx.response` becomes the parent step's output.
|
|
42
|
+
* - `false` — fire-and-forget: parent step returns IMMEDIATELY with
|
|
43
|
+
* `{runId, workflowName, scheduledAt}`. The child runs
|
|
44
|
+
* asynchronously via `setImmediate` and shows up in Studio's
|
|
45
|
+
* Sub-runs strip with status transitioning `running → completed |
|
|
46
|
+
* failed` independently of the parent.
|
|
47
|
+
*
|
|
48
|
+
* Combine `wait: false` with `idempotencyKey` for at-most-once
|
|
49
|
+
* dispatch deduplication (the `runId` is cached against the key
|
|
50
|
+
* regardless of child outcome — Trigger.dev / Stripe semantics).
|
|
51
|
+
*/
|
|
52
|
+
wait: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Runner-wide options (carries the `nodes` registry that the child
|
|
55
|
+
* Configuration needs for `module` step resolution). Set by
|
|
56
|
+
* `Configuration.subworkflowResolver` before this node runs.
|
|
57
|
+
*/
|
|
58
|
+
globalOptions?: GlobalOptions;
|
|
59
|
+
run(ctx: Context): Promise<ResponseContext>;
|
|
60
|
+
/**
|
|
61
|
+
* Fire-and-forget dispatch (Tier 2 #4 follow-up — `wait: false`).
|
|
62
|
+
*
|
|
63
|
+
* Schedules the child runner via `setImmediate` so the parent step
|
|
64
|
+
* can return immediately. Child errors are caught and routed to
|
|
65
|
+
* `tracker.failRun(childRunId, err)` — visible in Studio, NOT
|
|
66
|
+
* propagated to the parent step (which has already returned). Also
|
|
67
|
+
* logged via `console.error` for ops visibility.
|
|
68
|
+
*
|
|
69
|
+
* Parent step's output is the dispatch metadata `{runId,
|
|
70
|
+
* workflowName, scheduledAt}` — NOT the child's response (which
|
|
71
|
+
* doesn't exist yet). Caller polls `GET /__blok/runs/<runId>` for
|
|
72
|
+
* the actual outcome.
|
|
73
|
+
*/
|
|
74
|
+
private dispatchAsync;
|
|
75
|
+
}
|