@webda/workflow 0.0.0-stage → 4.0.0-beta.14
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 +166 -0
- package/README.md +54 -2
- package/lib/authoring.d.ts +115 -0
- package/lib/authoring.d.ts.map +1 -0
- package/lib/authoring.js +107 -0
- package/lib/authoring.js.map +1 -0
- package/lib/expression.d.ts +21 -0
- package/lib/expression.d.ts.map +1 -0
- package/lib/expression.js +196 -0
- package/lib/expression.js.map +1 -0
- package/lib/graph.d.ts +429 -0
- package/lib/graph.d.ts.map +1 -0
- package/lib/graph.js +72 -0
- package/lib/graph.js.map +1 -0
- package/lib/hooks.d.ts +38 -0
- package/lib/hooks.d.ts.map +1 -0
- package/lib/hooks.js +23 -0
- package/lib/hooks.js.map +1 -0
- package/lib/index.d.ts +11 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +15 -0
- package/lib/index.js.map +1 -0
- package/lib/interpreter.d.ts +69 -0
- package/lib/interpreter.d.ts.map +1 -0
- package/lib/interpreter.js +332 -0
- package/lib/interpreter.js.map +1 -0
- package/lib/models/workflow.model.d.ts +71 -0
- package/lib/models/workflow.model.d.ts.map +1 -0
- package/lib/models/workflow.model.js +70 -0
- package/lib/models/workflow.model.js.map +1 -0
- package/lib/models/workflowinstance.model.d.ts +132 -0
- package/lib/models/workflowinstance.model.d.ts.map +1 -0
- package/lib/models/workflowinstance.model.js +168 -0
- package/lib/models/workflowinstance.model.js.map +1 -0
- package/lib/models/workflowsignal.model.d.ts +51 -0
- package/lib/models/workflowsignal.model.d.ts.map +1 -0
- package/lib/models/workflowsignal.model.js +53 -0
- package/lib/models/workflowsignal.model.js.map +1 -0
- package/lib/models/workflowtask.model.d.ts +103 -0
- package/lib/models/workflowtask.model.d.ts.map +1 -0
- package/lib/models/workflowtask.model.js +104 -0
- package/lib/models/workflowtask.model.js.map +1 -0
- package/lib/workflow.service.d.ts +685 -0
- package/lib/workflow.service.d.ts.map +1 -0
- package/lib/workflow.service.js +1951 -0
- package/lib/workflow.service.js.map +1 -0
- package/package.json +68 -3
- package/webda.module.json +2688 -0
|
@@ -0,0 +1,685 @@
|
|
|
1
|
+
import { Service, ServiceParameters, SimpleOperationContext, type OperationContext } from "@webda/core";
|
|
2
|
+
import { type FlowDefinition, type FlowDefinitionData, type FlowError, type JournalEntry } from "./graph.js";
|
|
3
|
+
import { type ScheduledTask } from "./interpreter.js";
|
|
4
|
+
import { type WorkflowControls } from "./hooks.js";
|
|
5
|
+
import { WorkflowInstance, type WorkflowLauncher } from "./models/workflowinstance.model.js";
|
|
6
|
+
import { WorkflowTask } from "./models/workflowtask.model.js";
|
|
7
|
+
import { WorkflowSignal } from "./models/workflowsignal.model.js";
|
|
8
|
+
import { Workflow as StoredWorkflow } from "./models/workflow.model.js";
|
|
9
|
+
/**
|
|
10
|
+
* Output schema of every flow launch operation
|
|
11
|
+
*/
|
|
12
|
+
export declare const LAUNCH_OUTPUT_SCHEMA = "Webda/WorkflowLaunch.output";
|
|
13
|
+
/**
|
|
14
|
+
* `runAt` of a wait without timeout (JSON has no Infinity)
|
|
15
|
+
*/
|
|
16
|
+
export declare const NO_TIMEOUT: number;
|
|
17
|
+
/**
|
|
18
|
+
* A stored workflow registered on this replica
|
|
19
|
+
*/
|
|
20
|
+
interface RegisteredStoredFlow {
|
|
21
|
+
/**
|
|
22
|
+
* Flow ID
|
|
23
|
+
*/
|
|
24
|
+
flowId: string;
|
|
25
|
+
/**
|
|
26
|
+
* Version
|
|
27
|
+
*/
|
|
28
|
+
version: string;
|
|
29
|
+
/**
|
|
30
|
+
* Updated by
|
|
31
|
+
*/
|
|
32
|
+
updatedBy?: string;
|
|
33
|
+
/**
|
|
34
|
+
* JSON of its crons, to notice a change
|
|
35
|
+
*/
|
|
36
|
+
crons: string;
|
|
37
|
+
/**
|
|
38
|
+
* Export ids of the crons registered for it: only those are removed
|
|
39
|
+
*/
|
|
40
|
+
cronIds: string[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Abort signal of the current workflow task attempt
|
|
44
|
+
*
|
|
45
|
+
* It is aborted on timeout, when the worker loses the task lease, and when the service stops. An operation run by a
|
|
46
|
+
* workflow should observe it to stop early: an attempt that keeps running is ignored, and the task may run again
|
|
47
|
+
* (operations are assumed idempotent).
|
|
48
|
+
* @returns the signal, undefined outside a workflow task
|
|
49
|
+
*/
|
|
50
|
+
export declare function useAbortSignal(): AbortSignal | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* An attempt running on this replica
|
|
53
|
+
*/
|
|
54
|
+
interface RunningAttempt {
|
|
55
|
+
/**
|
|
56
|
+
* Task
|
|
57
|
+
*/
|
|
58
|
+
task: WorkflowTask;
|
|
59
|
+
/**
|
|
60
|
+
* Controller
|
|
61
|
+
*/
|
|
62
|
+
controller: AbortController;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Parameters of the {@link WorkflowService}
|
|
66
|
+
*/
|
|
67
|
+
export declare class WorkflowServiceParameters extends ServiceParameters {
|
|
68
|
+
/**
|
|
69
|
+
* Interval between two polls of the worker (ms)
|
|
70
|
+
* @default 1000
|
|
71
|
+
*/
|
|
72
|
+
pollInterval: number;
|
|
73
|
+
/**
|
|
74
|
+
* Maximum number of tasks running at once on this replica
|
|
75
|
+
* @default 10
|
|
76
|
+
*/
|
|
77
|
+
concurrency: number;
|
|
78
|
+
/**
|
|
79
|
+
* Lease of a claimed task (ms), renewed while it runs
|
|
80
|
+
* @default 60000
|
|
81
|
+
*/
|
|
82
|
+
leaseDuration: number;
|
|
83
|
+
/**
|
|
84
|
+
* Maximum size of the journal and input of an instance (bytes of JSON)
|
|
85
|
+
* @default 262144
|
|
86
|
+
*/
|
|
87
|
+
maxContextSize: number;
|
|
88
|
+
/**
|
|
89
|
+
* Run the worker loop on this replica
|
|
90
|
+
* @default true
|
|
91
|
+
*/
|
|
92
|
+
worker: boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Allow `useSystem` tasks in stored workflows
|
|
95
|
+
* @default false
|
|
96
|
+
*/
|
|
97
|
+
allowStoredSystem: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* How long a signal sent before any wait is kept (Duration syntax)
|
|
100
|
+
* @default "1d"
|
|
101
|
+
*/
|
|
102
|
+
signalTtl: string;
|
|
103
|
+
/**
|
|
104
|
+
* Interval of the recovery sweep (ms): an active instance not updated for this long and without a live task is
|
|
105
|
+
* replayed
|
|
106
|
+
* @default 60000
|
|
107
|
+
*/
|
|
108
|
+
sweepInterval: number;
|
|
109
|
+
/**
|
|
110
|
+
* Grace period of stop() for the running attempts (ms), then they are aborted and their outcome dropped
|
|
111
|
+
* @default 30000
|
|
112
|
+
*/
|
|
113
|
+
stopTimeout: number;
|
|
114
|
+
/**
|
|
115
|
+
* Flows to register
|
|
116
|
+
*/
|
|
117
|
+
flows?: FlowDefinitionData[];
|
|
118
|
+
/**
|
|
119
|
+
* Maximum size of a signal payload (bytes of JSON)
|
|
120
|
+
* @default 65536
|
|
121
|
+
*/
|
|
122
|
+
maxSignalPayload: number;
|
|
123
|
+
/**
|
|
124
|
+
* Maximum number of unexpired buffered signals per `(event, key)`: a new one past it is refused
|
|
125
|
+
* @default 100
|
|
126
|
+
*/
|
|
127
|
+
maxBufferedSignals: number;
|
|
128
|
+
/**
|
|
129
|
+
* Role needed to create, update or delete a stored workflow
|
|
130
|
+
* @default "workflow-admin"
|
|
131
|
+
*/
|
|
132
|
+
storedWorkflowRole: string;
|
|
133
|
+
/**
|
|
134
|
+
* PubSub service announcing the stored workflow changes to the other replicas
|
|
135
|
+
*/
|
|
136
|
+
syncPubSub?: string;
|
|
137
|
+
/**
|
|
138
|
+
* Without `syncPubSub`, interval between two reloads of the stored workflows (ms)
|
|
139
|
+
* @default 60000
|
|
140
|
+
*/
|
|
141
|
+
syncInterval: number;
|
|
142
|
+
/**
|
|
143
|
+
* @override
|
|
144
|
+
* @param params - the input parameters
|
|
145
|
+
* @returns this
|
|
146
|
+
*/
|
|
147
|
+
load(params?: any): this;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Runs durable workflows: registers each flow as an operation, launches instances and runs their tasks
|
|
151
|
+
*
|
|
152
|
+
* Every replica runs the worker loop: a task is claimed with a lease (a conditional patch on `leaseUntil`), so it
|
|
153
|
+
* runs on one replica at a time. Its outcome goes to the instance journal (a conditional patch on `revision`), then
|
|
154
|
+
* the flow is replayed to find the next tasks.
|
|
155
|
+
*
|
|
156
|
+
* @WebdaModda WorkflowService
|
|
157
|
+
*/
|
|
158
|
+
export declare class WorkflowService<T extends WorkflowServiceParameters = WorkflowServiceParameters> extends Service<T> implements WorkflowControls {
|
|
159
|
+
/**
|
|
160
|
+
* Flows registered on this service, by flow id
|
|
161
|
+
*/
|
|
162
|
+
protected flows: Map<string, FlowDefinition>;
|
|
163
|
+
/**
|
|
164
|
+
* Every version registered of each flow, for migrate
|
|
165
|
+
*/
|
|
166
|
+
protected versions: Map<string, Map<string, FlowDefinition>>;
|
|
167
|
+
/**
|
|
168
|
+
* Flows of the modules (compiled `.flow.ts`) registered by this service
|
|
169
|
+
*/
|
|
170
|
+
protected moduleFlows: Set<string>;
|
|
171
|
+
/**
|
|
172
|
+
* Worker id, the lease owner of the tasks it claims
|
|
173
|
+
*/
|
|
174
|
+
protected workerId: `${string}-${string}-${string}-${string}-${string}`;
|
|
175
|
+
/**
|
|
176
|
+
* Attempts running on this replica, by task uuid
|
|
177
|
+
*/
|
|
178
|
+
protected running: Map<string, RunningAttempt>;
|
|
179
|
+
/**
|
|
180
|
+
* Tasks reclaimed after too many crashes: they fail without running
|
|
181
|
+
*/
|
|
182
|
+
protected crashed: WeakSet<WorkflowTask>;
|
|
183
|
+
/**
|
|
184
|
+
* The service is stopping: nothing more is claimed
|
|
185
|
+
*/
|
|
186
|
+
protected stopping: boolean;
|
|
187
|
+
/**
|
|
188
|
+
* Poll in progress
|
|
189
|
+
*/
|
|
190
|
+
protected pollPromise?: Promise<void>;
|
|
191
|
+
/**
|
|
192
|
+
* Last recovery sweep (ms)
|
|
193
|
+
*/
|
|
194
|
+
protected lastSweep: number;
|
|
195
|
+
/**
|
|
196
|
+
* Executions started by the worker loop
|
|
197
|
+
*/
|
|
198
|
+
protected executions: Set<Promise<void>>;
|
|
199
|
+
/**
|
|
200
|
+
* Worker loop timer
|
|
201
|
+
*/
|
|
202
|
+
protected timer?: NodeJS.Timeout;
|
|
203
|
+
/**
|
|
204
|
+
* Stored workflows registered here, by workflow uuid
|
|
205
|
+
*/
|
|
206
|
+
protected storedFlows: Map<string, RegisteredStoredFlow>;
|
|
207
|
+
/**
|
|
208
|
+
* Stored workflows reload timer
|
|
209
|
+
*/
|
|
210
|
+
protected syncTimer?: NodeJS.Timeout;
|
|
211
|
+
/**
|
|
212
|
+
* Subscription to the stored workflow changes
|
|
213
|
+
*/
|
|
214
|
+
protected syncConsumer?: {
|
|
215
|
+
cancel: () => any;
|
|
216
|
+
};
|
|
217
|
+
/**
|
|
218
|
+
* @override
|
|
219
|
+
*/
|
|
220
|
+
resolve(): this;
|
|
221
|
+
/**
|
|
222
|
+
* Register the flows compiled from the `.flow.ts` files (`flows` of the modules), with their crons
|
|
223
|
+
*
|
|
224
|
+
* The first WorkflowService to resolve registers them; the typed calls are resolved in {@link init}, once every
|
|
225
|
+
* service registered its operations.
|
|
226
|
+
*/
|
|
227
|
+
protected registerModuleFlows(): void;
|
|
228
|
+
/**
|
|
229
|
+
* The operation a typed call (`target: { class, method }`) runs: the operation of the configured service whose
|
|
230
|
+
* instance is of that class (matched by constructor name, the class or an ancestor)
|
|
231
|
+
* @param target - the target of the task
|
|
232
|
+
* @param target.class - the service class name
|
|
233
|
+
* @param target.method - the method name
|
|
234
|
+
* @returns the operation id, or why there is none: no service (missing) or several (ambiguous)
|
|
235
|
+
*/
|
|
236
|
+
resolveTarget(target: {
|
|
237
|
+
class: string;
|
|
238
|
+
method: string;
|
|
239
|
+
}): {
|
|
240
|
+
operation?: string;
|
|
241
|
+
missing?: string;
|
|
242
|
+
ambiguous?: string;
|
|
243
|
+
};
|
|
244
|
+
/**
|
|
245
|
+
* Resolve the typed calls of a flow body in place
|
|
246
|
+
* @param body - the statements
|
|
247
|
+
* @returns the problems, by statement id
|
|
248
|
+
*/
|
|
249
|
+
protected resolveTargets(body: any[]): {
|
|
250
|
+
missing: string[];
|
|
251
|
+
ambiguous: string[];
|
|
252
|
+
};
|
|
253
|
+
/**
|
|
254
|
+
* Point every typed call of the compiled flows at the operation of the configured service of its class
|
|
255
|
+
*
|
|
256
|
+
* A flow whose service is not configured (a packaged unit without it) is removed with its crons; a call that several
|
|
257
|
+
* services serve, or a flow whose operation was taken over, stops the startup.
|
|
258
|
+
* @throws FatalInitError on an ambiguous call, or a flow id taken by another operation
|
|
259
|
+
*/
|
|
260
|
+
protected resolveModuleTargets(): void;
|
|
261
|
+
/**
|
|
262
|
+
* Remove a module flow: its operation and its crons
|
|
263
|
+
* @param id - the flow id
|
|
264
|
+
*/
|
|
265
|
+
protected unregisterModuleFlow(id: string): void;
|
|
266
|
+
/**
|
|
267
|
+
* @override
|
|
268
|
+
*/
|
|
269
|
+
init(): Promise<this>;
|
|
270
|
+
/**
|
|
271
|
+
* Stop the worker loop
|
|
272
|
+
*
|
|
273
|
+
* Running attempts get `stopTimeout` to finish, then they are aborted and their outcome dropped: their lease
|
|
274
|
+
* expires and another worker runs them again.
|
|
275
|
+
* @override
|
|
276
|
+
*/
|
|
277
|
+
stop(): Promise<void>;
|
|
278
|
+
/**
|
|
279
|
+
* Register a schema in the validator and the application
|
|
280
|
+
* @param name - schema name
|
|
281
|
+
* @param schema - the JSON schema
|
|
282
|
+
*/
|
|
283
|
+
protected registerSchema(name: string, schema: any): void;
|
|
284
|
+
/**
|
|
285
|
+
* Register a flow as an operation `<flow id>` served by {@link launch}
|
|
286
|
+
* @param def - the flow definition
|
|
287
|
+
*/
|
|
288
|
+
registerFlow(def: FlowDefinition): void;
|
|
289
|
+
/**
|
|
290
|
+
* Get a registered flow
|
|
291
|
+
* @param flowId - the flow id
|
|
292
|
+
* @returns the definition
|
|
293
|
+
*/
|
|
294
|
+
getFlow(flowId: string): FlowDefinition | undefined;
|
|
295
|
+
/**
|
|
296
|
+
* Find a flow registered on any WorkflowService, by its operation
|
|
297
|
+
* @param flowId - the flow id
|
|
298
|
+
* @returns the current definition, undefined when the operation is not a flow
|
|
299
|
+
*/
|
|
300
|
+
resolveFlow(flowId: string | undefined): FlowDefinition | undefined;
|
|
301
|
+
/**
|
|
302
|
+
* Find a version of a flow
|
|
303
|
+
* @param flowId - the flow id
|
|
304
|
+
* @param version - the version
|
|
305
|
+
* @returns the definition
|
|
306
|
+
*/
|
|
307
|
+
getFlowVersion(flowId: string, version: string): FlowDefinition | undefined;
|
|
308
|
+
/**
|
|
309
|
+
* Role needed to write a stored workflow
|
|
310
|
+
* @returns the role
|
|
311
|
+
*/
|
|
312
|
+
getStoredWorkflowRole(): string;
|
|
313
|
+
/**
|
|
314
|
+
* Validate and stamp stored workflows on save, and register them once saved
|
|
315
|
+
*/
|
|
316
|
+
protected listenStored(): void;
|
|
317
|
+
/**
|
|
318
|
+
* Validate a stored workflow about to be saved and stamp its version and last saver
|
|
319
|
+
* @param workflow - the workflow as it will be saved
|
|
320
|
+
* @param target - the data written: receives `version` and `updatedBy`
|
|
321
|
+
*/
|
|
322
|
+
protected prepareStored(workflow: any, target: any): void;
|
|
323
|
+
/**
|
|
324
|
+
* Validate a stored workflow
|
|
325
|
+
* @param workflow - the workflow
|
|
326
|
+
* @throws BadRequest when its name, graph or options are refused
|
|
327
|
+
*/
|
|
328
|
+
validateStored(workflow: any): void;
|
|
329
|
+
/**
|
|
330
|
+
* The flow served by an operation, if it is a flow
|
|
331
|
+
* @param flowId - the operation id
|
|
332
|
+
* @returns the flow of the WorkflowService serving the operation
|
|
333
|
+
*/
|
|
334
|
+
protected operationFlow(flowId: string): FlowDefinition | undefined;
|
|
335
|
+
/**
|
|
336
|
+
* User a stored flow runs as when the system launches it: its last saver
|
|
337
|
+
* @param flowId - the flow id
|
|
338
|
+
* @returns the user id, undefined when unknown
|
|
339
|
+
*/
|
|
340
|
+
storedRunAs(flowId: string): string | undefined;
|
|
341
|
+
/**
|
|
342
|
+
* Identity of a new instance: a stored flow never runs as the system, it runs as its last saver
|
|
343
|
+
* @param def - the flow
|
|
344
|
+
* @param launcher - the identity of the caller (launch) or of the parent instance (child flows)
|
|
345
|
+
* @returns the launcher of the instance
|
|
346
|
+
* @throws Forbidden when a stored flow launched by the system has no user to run as
|
|
347
|
+
*/
|
|
348
|
+
protected instanceLauncher(def: FlowDefinition, launcher: WorkflowLauncher): WorkflowLauncher;
|
|
349
|
+
/**
|
|
350
|
+
* Identity of a child flow, which must be allowed to call the flow operation like a launch
|
|
351
|
+
* @param def - the child flow
|
|
352
|
+
* @param launcher - the launcher of the parent
|
|
353
|
+
* @param input - the child input
|
|
354
|
+
* @returns the launcher of the child
|
|
355
|
+
* @throws TaskError Forbidden when the child may not be started
|
|
356
|
+
*/
|
|
357
|
+
protected childLauncher(def: FlowDefinition, launcher: WorkflowLauncher, input: any): Promise<WorkflowLauncher>;
|
|
358
|
+
/**
|
|
359
|
+
* A stored workflow changed on this replica: register it here and tell the others
|
|
360
|
+
* @param uuid - the workflow uuid
|
|
361
|
+
*/
|
|
362
|
+
protected storedChanged(uuid: string): Promise<void>;
|
|
363
|
+
/**
|
|
364
|
+
* Register, re-register or remove a stored workflow from the store
|
|
365
|
+
* @param uuid - the workflow uuid
|
|
366
|
+
*/
|
|
367
|
+
protected syncStored(uuid: string): Promise<void>;
|
|
368
|
+
/**
|
|
369
|
+
* Validate then register a stored workflow; an invalid one is removed and logged
|
|
370
|
+
* @param workflow - the stored workflow
|
|
371
|
+
* @returns true when registered
|
|
372
|
+
*/
|
|
373
|
+
protected registerStored(workflow: StoredWorkflow): boolean;
|
|
374
|
+
/**
|
|
375
|
+
* Register a stored workflow as a flow, with its crons
|
|
376
|
+
* @param workflow - the stored workflow
|
|
377
|
+
*/
|
|
378
|
+
protected applyStored(workflow: StoredWorkflow): void;
|
|
379
|
+
/**
|
|
380
|
+
* Remove a stored workflow: its operation and its crons (running instances keep their pinned definition)
|
|
381
|
+
* @param uuid - the workflow uuid
|
|
382
|
+
*/
|
|
383
|
+
protected unregisterStored(uuid: string): void;
|
|
384
|
+
/**
|
|
385
|
+
* Load every stored workflow: register the new and changed ones, remove the deleted ones
|
|
386
|
+
*/
|
|
387
|
+
protected reloadStored(): Promise<void>;
|
|
388
|
+
/**
|
|
389
|
+
* Follow the stored workflow changes of the other replicas: through `syncPubSub`, or a reload every
|
|
390
|
+
* `syncInterval`
|
|
391
|
+
*/
|
|
392
|
+
protected startSync(): void;
|
|
393
|
+
/**
|
|
394
|
+
* Launch the flow of the current operation, as the caller
|
|
395
|
+
* @param args - the flow parameters, in order
|
|
396
|
+
* @returns the instance uuid
|
|
397
|
+
*/
|
|
398
|
+
launch(...args: any[]): Promise<{
|
|
399
|
+
uuid: string;
|
|
400
|
+
}>;
|
|
401
|
+
/**
|
|
402
|
+
* Create an instance and run it to its first tasks
|
|
403
|
+
* @param def - the flow definition, pinned in the instance
|
|
404
|
+
* @param input - the flow input
|
|
405
|
+
* @param launcher - the identity of the steps
|
|
406
|
+
* @param options - the parent of an awaited child, a fixed uuid (created once)
|
|
407
|
+
* @param options.parent - parent instance and task key
|
|
408
|
+
* @param options.parent.instance - parent instance uuid
|
|
409
|
+
* @param options.parent.key - task key in the parent
|
|
410
|
+
* @param options.uuid - uuid of the instance: an existing one is not created again
|
|
411
|
+
* @returns the instance
|
|
412
|
+
*/
|
|
413
|
+
protected createInstance(def: FlowDefinition, input: Record<string, any>, launcher: WorkflowLauncher, options?: {
|
|
414
|
+
parent?: {
|
|
415
|
+
instance: string;
|
|
416
|
+
key: string;
|
|
417
|
+
};
|
|
418
|
+
uuid?: string;
|
|
419
|
+
}): Promise<WorkflowInstance>;
|
|
420
|
+
/**
|
|
421
|
+
* Start the worker loop
|
|
422
|
+
*/
|
|
423
|
+
protected startWorker(): void;
|
|
424
|
+
/**
|
|
425
|
+
* One iteration of the worker loop: claim due tasks and run them in the background
|
|
426
|
+
* @returns the poll in progress, it ends when the tasks are claimed and started
|
|
427
|
+
*/
|
|
428
|
+
protected poll(): Promise<void>;
|
|
429
|
+
/**
|
|
430
|
+
* Run the recovery sweep when `sweepInterval` passed since the last one
|
|
431
|
+
*/
|
|
432
|
+
protected maybeSweep(): Promise<void>;
|
|
433
|
+
/**
|
|
434
|
+
* Replay the stranded instances: active, not updated for `sweepInterval`, without a PENDING or RUNNING task
|
|
435
|
+
*
|
|
436
|
+
* A crash between two steps leaves such an instance: replay is idempotent, and the revision CAS of
|
|
437
|
+
* {@link advance} guards against a concurrent writer.
|
|
438
|
+
* @returns the number of instances replayed
|
|
439
|
+
*/
|
|
440
|
+
protected sweep(): Promise<number>;
|
|
441
|
+
/**
|
|
442
|
+
* One poll: claim the due tasks and run them
|
|
443
|
+
* @returns the number of tasks claimed
|
|
444
|
+
*/
|
|
445
|
+
protected tick(): Promise<number>;
|
|
446
|
+
/**
|
|
447
|
+
* Claim the due tasks, up to the free slots of this replica
|
|
448
|
+
*
|
|
449
|
+
* The PENDING tasks due now, and the RUNNING ones whose lease expired (their worker crashed)
|
|
450
|
+
* @returns the tasks claimed
|
|
451
|
+
*/
|
|
452
|
+
protected claimDue(): Promise<WorkflowTask[]>;
|
|
453
|
+
/**
|
|
454
|
+
* Claim a task with a lease: a conditional patch on its `leaseUntil`
|
|
455
|
+
*
|
|
456
|
+
* Reclaiming an expired lease counts as a new attempt.
|
|
457
|
+
* @param task - the task, as queried
|
|
458
|
+
* @param extra - other fields to set with the claim
|
|
459
|
+
* @returns true when this worker holds the task
|
|
460
|
+
*/
|
|
461
|
+
protected claim(task: WorkflowTask, extra?: Partial<WorkflowTask>): Promise<boolean>;
|
|
462
|
+
/**
|
|
463
|
+
* Run a claimed task, write its outcome and advance its instance
|
|
464
|
+
*
|
|
465
|
+
* Every write of the attempt is conditional on the lease this worker holds: an attempt whose lease was lost (its
|
|
466
|
+
* worker was too slow and another one reclaimed it) drops its outcome.
|
|
467
|
+
* @param task - the task
|
|
468
|
+
* @param advance - advance the instance after the outcome is journaled
|
|
469
|
+
*/
|
|
470
|
+
protected execute(task: WorkflowTask, advance?: boolean): Promise<void>;
|
|
471
|
+
/**
|
|
472
|
+
* Conditional patch of a task row on the lease this worker holds
|
|
473
|
+
* @param task - the task, with the lease this worker holds
|
|
474
|
+
* @param data - the changes
|
|
475
|
+
* @returns false when another worker holds the lease now
|
|
476
|
+
*/
|
|
477
|
+
protected patchLeased(task: WorkflowTask, data: Partial<WorkflowTask>): Promise<boolean>;
|
|
478
|
+
/**
|
|
479
|
+
* Check this worker still holds the lease of a task, and extend it
|
|
480
|
+
* @param task - the task
|
|
481
|
+
* @returns false when the lease was lost
|
|
482
|
+
*/
|
|
483
|
+
protected holdsLease(task: WorkflowTask): Promise<boolean>;
|
|
484
|
+
/**
|
|
485
|
+
* Extend the lease of a running task, abort the attempt when the lease was lost
|
|
486
|
+
* @param task - the task
|
|
487
|
+
*/
|
|
488
|
+
protected renewLease(task: WorkflowTask): Promise<void>;
|
|
489
|
+
/**
|
|
490
|
+
* Record the end of an attempt, if this worker still holds its lease
|
|
491
|
+
*
|
|
492
|
+
* `leaseUntil` becomes the end time, never 0: a worker that queried the task before cannot claim it again.
|
|
493
|
+
* @param task - the task
|
|
494
|
+
* @param data - status and outcome
|
|
495
|
+
* @returns false when the lease was lost
|
|
496
|
+
*/
|
|
497
|
+
protected finishTask(task: WorkflowTask, data: Partial<WorkflowTask>): Promise<boolean>;
|
|
498
|
+
/**
|
|
499
|
+
* Create the next attempt of a failed task, after the backoff delay
|
|
500
|
+
* @param task - the failed attempt
|
|
501
|
+
*/
|
|
502
|
+
protected scheduleRetry(task: WorkflowTask): Promise<void>;
|
|
503
|
+
/**
|
|
504
|
+
* Run the operation (or built-in) of a task
|
|
505
|
+
* @param task - the task
|
|
506
|
+
* @param instance - its instance
|
|
507
|
+
* @param controller - aborted on timeout
|
|
508
|
+
* @returns the result
|
|
509
|
+
*/
|
|
510
|
+
protected runTask(task: WorkflowTask, instance: WorkflowInstance, controller: AbortController): Promise<any>;
|
|
511
|
+
/**
|
|
512
|
+
* Build the context of the launcher: the session is rebuilt from the user id, so the permissions are fresh
|
|
513
|
+
* @param launcher - the launcher
|
|
514
|
+
* @param input - the operation input
|
|
515
|
+
* @returns the context
|
|
516
|
+
*/
|
|
517
|
+
protected launcherContext(launcher: WorkflowLauncher, input: any): SimpleOperationContext;
|
|
518
|
+
/**
|
|
519
|
+
* Convert an error to the data the flow sees
|
|
520
|
+
* @param err - the error
|
|
521
|
+
* @param operation - the operation of the task
|
|
522
|
+
* @returns the flow error
|
|
523
|
+
*/
|
|
524
|
+
protected toFlowError(err: any, operation: string): FlowError;
|
|
525
|
+
/**
|
|
526
|
+
* Write a task outcome to the instance journal: a conditional patch on `revision`, retried on conflict
|
|
527
|
+
*
|
|
528
|
+
* The first outcome of a key wins. A journal over `maxContextSize` fails the instance.
|
|
529
|
+
* @param instanceId - the instance uuid
|
|
530
|
+
* @param key - the task key
|
|
531
|
+
* @param entry - the outcome
|
|
532
|
+
* @returns true when the outcome is in the journal
|
|
533
|
+
*/
|
|
534
|
+
protected writeJournal(instanceId: string, key: string, entry: JournalEntry): Promise<boolean>;
|
|
535
|
+
/**
|
|
536
|
+
* Patch an instance if its revision did not change
|
|
537
|
+
* @param instance - the instance as read
|
|
538
|
+
* @param data - the changes
|
|
539
|
+
* @returns false when another writer changed it first
|
|
540
|
+
*/
|
|
541
|
+
protected patchInstance(instance: WorkflowInstance, data: Partial<WorkflowInstance>): Promise<boolean>;
|
|
542
|
+
/**
|
|
543
|
+
* Replay an instance and act on the result: finish it, or create its missing tasks
|
|
544
|
+
* @param instanceId - the instance uuid
|
|
545
|
+
*/
|
|
546
|
+
protected advance(instanceId: string): Promise<void>;
|
|
547
|
+
/**
|
|
548
|
+
* Create the task of a scheduled key, unless a PENDING or RUNNING one exists
|
|
549
|
+
* @param instance - the instance
|
|
550
|
+
* @param scheduled - the task to run
|
|
551
|
+
* @returns true when the task was resolved at once (a buffered signal): the journal changed
|
|
552
|
+
*/
|
|
553
|
+
protected scheduleTask(instance: WorkflowInstance, scheduled: ScheduledTask): Promise<boolean>;
|
|
554
|
+
/**
|
|
555
|
+
* Start an awaited child flow: the task waits for the child instance, which runs as the same launcher
|
|
556
|
+
* @param instance - the parent instance
|
|
557
|
+
* @param scheduled - the task, its operation is a flow id
|
|
558
|
+
* @param index - row index of the key
|
|
559
|
+
* @returns true when the child finished at once: the parent journal changed
|
|
560
|
+
*/
|
|
561
|
+
protected scheduleChild(instance: WorkflowInstance, scheduled: ScheduledTask, index: number): Promise<boolean>;
|
|
562
|
+
/**
|
|
563
|
+
* Journal the end of a child into its parent: its output, its error, or `Cancelled`
|
|
564
|
+
* @param childId - the child instance uuid
|
|
565
|
+
*/
|
|
566
|
+
protected deliverToParent(childId: string): Promise<void>;
|
|
567
|
+
/**
|
|
568
|
+
* Cancel an instance, its live tasks and the children it waits on
|
|
569
|
+
* @param uuid - the instance uuid
|
|
570
|
+
*/
|
|
571
|
+
cancelInstance(uuid: string): Promise<void>;
|
|
572
|
+
/**
|
|
573
|
+
* Cancel an instance and, recursively, the children it waits on
|
|
574
|
+
* @param uuid - the instance uuid
|
|
575
|
+
* @returns false when the instance was not running
|
|
576
|
+
*/
|
|
577
|
+
protected cancelTree(uuid: string): Promise<boolean>;
|
|
578
|
+
/**
|
|
579
|
+
* Mark a task row CANCELLED, conditionally on its lease: whoever holds it can no longer write its outcome
|
|
580
|
+
* @param row - the task row, as read
|
|
581
|
+
*/
|
|
582
|
+
protected supersede(row: WorkflowTask): Promise<void>;
|
|
583
|
+
/**
|
|
584
|
+
* Restart a failed instance: drop the outcome that failed it and every outcome journaled after it, then replay
|
|
585
|
+
* @param uuid - the instance uuid
|
|
586
|
+
*/
|
|
587
|
+
retryInstance(uuid: string): Promise<void>;
|
|
588
|
+
/**
|
|
589
|
+
* Move a running instance to another version of its flow
|
|
590
|
+
*
|
|
591
|
+
* Refused when a journaled or live task key has no statement in the target graph.
|
|
592
|
+
* @param uuid - the instance uuid
|
|
593
|
+
* @param version - the target version, the latest registered when undefined
|
|
594
|
+
*/
|
|
595
|
+
migrateInstance(uuid: string, version?: string): Promise<void>;
|
|
596
|
+
/**
|
|
597
|
+
* Deliver a signal: resolve the waits on `(event, key)` whose instance accepts the caller, or buffer it when
|
|
598
|
+
* nothing waits
|
|
599
|
+
* @param event - event name
|
|
600
|
+
* @param key - business key
|
|
601
|
+
* @param payload - the result of the waits
|
|
602
|
+
* @returns the number of waits resolved
|
|
603
|
+
*/
|
|
604
|
+
signal(event: string, key: string, payload?: any): Promise<{
|
|
605
|
+
delivered: number;
|
|
606
|
+
}>;
|
|
607
|
+
/**
|
|
608
|
+
* The waits on `(event, key)` of active instances
|
|
609
|
+
* @param event - event name
|
|
610
|
+
* @param key - business key
|
|
611
|
+
* @returns the waits and their instance
|
|
612
|
+
*/
|
|
613
|
+
protected waitsFor(event: string, key: string): Promise<{
|
|
614
|
+
instance: WorkflowInstance;
|
|
615
|
+
task: WorkflowTask;
|
|
616
|
+
}[]>;
|
|
617
|
+
/**
|
|
618
|
+
* Whether a sender may signal a wait: the launcher, the system, and the users in the `allow` of the wait
|
|
619
|
+
* @param context - the sender
|
|
620
|
+
* @param instance - the instance waiting
|
|
621
|
+
* @param task - the wait
|
|
622
|
+
* @returns true when allowed
|
|
623
|
+
*/
|
|
624
|
+
protected canSignal(context: OperationContext, instance: WorkflowInstance, task: WorkflowTask): Promise<boolean>;
|
|
625
|
+
/**
|
|
626
|
+
* Save a signal nothing waits for yet
|
|
627
|
+
* @param context - the sender
|
|
628
|
+
* @param event - event name
|
|
629
|
+
* @param key - business key
|
|
630
|
+
* @param payload - the payload
|
|
631
|
+
* @returns the buffered signal
|
|
632
|
+
*/
|
|
633
|
+
protected bufferSignal(context: OperationContext, event: string, key: string, payload: any): Promise<WorkflowSignal>;
|
|
634
|
+
/**
|
|
635
|
+
* Deliver a just buffered signal to a wait created while it was being saved
|
|
636
|
+
* @param signal - the buffered signal
|
|
637
|
+
* @returns true when a wait consumed it
|
|
638
|
+
*/
|
|
639
|
+
protected deliverBuffered(signal: WorkflowSignal): Promise<boolean>;
|
|
640
|
+
/**
|
|
641
|
+
* Resolve a new wait with the oldest unexpired buffered signal its instance accepts
|
|
642
|
+
* @param instance - the instance
|
|
643
|
+
* @param task - the wait
|
|
644
|
+
* @returns true when a signal was consumed
|
|
645
|
+
*/
|
|
646
|
+
protected consumeBuffered(instance: WorkflowInstance, task: WorkflowTask): Promise<boolean>;
|
|
647
|
+
/**
|
|
648
|
+
* Consume a buffered signal for a wait: its sender is checked now, against this instance
|
|
649
|
+
* @param signal - the buffered signal
|
|
650
|
+
* @param instance - the instance waiting
|
|
651
|
+
* @param task - the wait
|
|
652
|
+
* @param advance - advance the instance once the payload is journaled
|
|
653
|
+
* @returns true when consumed and delivered
|
|
654
|
+
*/
|
|
655
|
+
protected consumeSignal(signal: WorkflowSignal, instance: WorkflowInstance, task: WorkflowTask, advance: boolean): Promise<boolean>;
|
|
656
|
+
/**
|
|
657
|
+
* Resolve a wait with a payload: claimed like a task, so it resolves once
|
|
658
|
+
* @param task - the wait
|
|
659
|
+
* @param payload - its result
|
|
660
|
+
* @param advance - advance the instance once the payload is journaled
|
|
661
|
+
* @returns false when the wait was already resolved or timed out
|
|
662
|
+
*/
|
|
663
|
+
protected resolveWait(task: WorkflowTask, payload: any, advance?: boolean): Promise<boolean>;
|
|
664
|
+
/**
|
|
665
|
+
* End of a `Workflow.Sleep`
|
|
666
|
+
* @param input - `{ duration?: string, until?: number }`
|
|
667
|
+
* @param now - the current time
|
|
668
|
+
* @returns when the timer fires
|
|
669
|
+
*/
|
|
670
|
+
protected sleepUntil(input: any, now: number): number;
|
|
671
|
+
/**
|
|
672
|
+
* Create a task row, unless another worker created the same row first
|
|
673
|
+
* @param instance - the instance uuid
|
|
674
|
+
* @param scheduled - the task
|
|
675
|
+
* @param launcherId - user id of the launcher
|
|
676
|
+
* @param runAt - when it becomes runnable
|
|
677
|
+
* @param attempt - attempt number
|
|
678
|
+
* @param index - row index of the key, when known
|
|
679
|
+
* @param extra - other fields of the row
|
|
680
|
+
* @returns the task created, undefined when another worker created it
|
|
681
|
+
*/
|
|
682
|
+
protected createTask(instance: string, scheduled: ScheduledTask, launcherId: string | undefined, runAt: number, attempt: number, index?: number, extra?: Partial<WorkflowTask>): Promise<WorkflowTask | undefined>;
|
|
683
|
+
}
|
|
684
|
+
export default WorkflowService;
|
|
685
|
+
//# sourceMappingURL=workflow.service.d.ts.map
|