@temporalio/workflow 1.4.4 → 1.5.1
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/lib/cancellation-scope.d.ts +1 -2
- package/lib/cancellation-scope.js +6 -4
- package/lib/cancellation-scope.js.map +1 -1
- package/lib/errors.d.ts +0 -1
- package/lib/errors.js +1 -3
- package/lib/errors.js.map +1 -1
- package/lib/index.d.ts +4 -3
- package/lib/index.js +1 -3
- package/lib/index.js.map +1 -1
- package/lib/interceptors.d.ts +1 -1
- package/lib/interfaces.d.ts +13 -3
- package/lib/internals.d.ts +81 -72
- package/lib/internals.js +328 -305
- package/lib/internals.js.map +1 -1
- package/lib/stack-helpers.js +1 -1
- package/lib/stack-helpers.js.map +1 -1
- package/lib/worker-interface.d.ts +3 -27
- package/lib/worker-interface.js +57 -100
- package/lib/worker-interface.js.map +1 -1
- package/lib/workflow.js +92 -86
- package/lib/workflow.js.map +1 -1
- package/package.json +4 -4
- package/src/cancellation-scope.ts +7 -5
- package/src/errors.ts +0 -2
- package/src/index.ts +16 -5
- package/src/interceptors.ts +1 -1
- package/src/interfaces.ts +15 -3
- package/src/internals.ts +403 -347
- package/src/stack-helpers.ts +1 -1
- package/src/worker-interface.ts +59 -105
- package/src/workflow.ts +93 -88
package/src/workflow.ts
CHANGED
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
EnhancedStackTrace,
|
|
36
36
|
WorkflowInfo,
|
|
37
37
|
} from './interfaces';
|
|
38
|
-
import { LocalActivityDoBackoff,
|
|
38
|
+
import { LocalActivityDoBackoff, getActivator } from './internals';
|
|
39
39
|
import { Sinks } from './sinks';
|
|
40
40
|
import { untrackPromise } from './stack-helpers';
|
|
41
41
|
import { ChildWorkflowHandle, ExternalWorkflowHandle } from './workflow-handle';
|
|
@@ -62,6 +62,7 @@ export function addDefaultWorkflowOptions<T extends Workflow>(
|
|
|
62
62
|
* Push a startTimer command into state accumulator and register completion
|
|
63
63
|
*/
|
|
64
64
|
function timerNextHandler(input: TimerInput) {
|
|
65
|
+
const activator = getActivator();
|
|
65
66
|
return new Promise<void>((resolve, reject) => {
|
|
66
67
|
const scope = CancellationScope.current();
|
|
67
68
|
if (scope.consideredCancelled) {
|
|
@@ -71,10 +72,10 @@ function timerNextHandler(input: TimerInput) {
|
|
|
71
72
|
if (scope.cancellable) {
|
|
72
73
|
untrackPromise(
|
|
73
74
|
scope.cancelRequested.catch((err) => {
|
|
74
|
-
if (!
|
|
75
|
+
if (!activator.completions.timer.delete(input.seq)) {
|
|
75
76
|
return; // Already resolved or never scheduled
|
|
76
77
|
}
|
|
77
|
-
|
|
78
|
+
activator.pushCommand({
|
|
78
79
|
cancelTimer: {
|
|
79
80
|
seq: input.seq,
|
|
80
81
|
},
|
|
@@ -83,13 +84,13 @@ function timerNextHandler(input: TimerInput) {
|
|
|
83
84
|
})
|
|
84
85
|
);
|
|
85
86
|
}
|
|
86
|
-
|
|
87
|
+
activator.pushCommand({
|
|
87
88
|
startTimer: {
|
|
88
89
|
seq: input.seq,
|
|
89
90
|
startToFireTimeout: msToTs(input.durationMs),
|
|
90
91
|
},
|
|
91
92
|
});
|
|
92
|
-
|
|
93
|
+
activator.completions.timer.set(input.seq, {
|
|
93
94
|
resolve,
|
|
94
95
|
reject,
|
|
95
96
|
});
|
|
@@ -105,11 +106,12 @@ function timerNextHandler(input: TimerInput) {
|
|
|
105
106
|
* If given a negative number or 0, value will be set to 1.
|
|
106
107
|
*/
|
|
107
108
|
export function sleep(ms: number | string): Promise<void> {
|
|
108
|
-
const
|
|
109
|
+
const activator = getActivator();
|
|
110
|
+
const seq = activator.nextSeqs.timer++;
|
|
109
111
|
|
|
110
112
|
const durationMs = Math.max(1, msToNumber(ms));
|
|
111
113
|
|
|
112
|
-
const execute = composeInterceptors(
|
|
114
|
+
const execute = composeInterceptors(activator.interceptors.outbound, 'startTimer', timerNextHandler);
|
|
113
115
|
|
|
114
116
|
return execute({
|
|
115
117
|
durationMs,
|
|
@@ -132,9 +134,10 @@ const validateLocalActivityOptions = validateActivityOptions;
|
|
|
132
134
|
* Returns `false` if the current scope is already cancelled.
|
|
133
135
|
*/
|
|
134
136
|
/**
|
|
135
|
-
* Push a scheduleActivity command into
|
|
137
|
+
* Push a scheduleActivity command into activator accumulator and register completion
|
|
136
138
|
*/
|
|
137
139
|
function scheduleActivityNextHandler({ options, args, headers, seq, activityType }: ActivityInput): Promise<unknown> {
|
|
140
|
+
const activator = getActivator();
|
|
138
141
|
validateActivityOptions(options);
|
|
139
142
|
return new Promise((resolve, reject) => {
|
|
140
143
|
const scope = CancellationScope.current();
|
|
@@ -145,10 +148,10 @@ function scheduleActivityNextHandler({ options, args, headers, seq, activityType
|
|
|
145
148
|
if (scope.cancellable) {
|
|
146
149
|
untrackPromise(
|
|
147
150
|
scope.cancelRequested.catch(() => {
|
|
148
|
-
if (!
|
|
151
|
+
if (!activator.completions.activity.has(seq)) {
|
|
149
152
|
return; // Already resolved or never scheduled
|
|
150
153
|
}
|
|
151
|
-
|
|
154
|
+
activator.pushCommand({
|
|
152
155
|
requestCancelActivity: {
|
|
153
156
|
seq,
|
|
154
157
|
},
|
|
@@ -156,14 +159,14 @@ function scheduleActivityNextHandler({ options, args, headers, seq, activityType
|
|
|
156
159
|
})
|
|
157
160
|
);
|
|
158
161
|
}
|
|
159
|
-
|
|
162
|
+
activator.pushCommand({
|
|
160
163
|
scheduleActivity: {
|
|
161
164
|
seq,
|
|
162
165
|
activityId: options.activityId ?? `${seq}`,
|
|
163
166
|
activityType,
|
|
164
|
-
arguments: toPayloads(
|
|
167
|
+
arguments: toPayloads(activator.payloadConverter, ...args),
|
|
165
168
|
retryPolicy: options.retry ? compileRetryPolicy(options.retry) : undefined,
|
|
166
|
-
taskQueue: options.taskQueue ||
|
|
169
|
+
taskQueue: options.taskQueue || activator.info?.taskQueue,
|
|
167
170
|
heartbeatTimeout: msOptionalToTs(options.heartbeatTimeout),
|
|
168
171
|
scheduleToCloseTimeout: msOptionalToTs(options.scheduleToCloseTimeout),
|
|
169
172
|
startToCloseTimeout: msOptionalToTs(options.startToCloseTimeout),
|
|
@@ -173,7 +176,7 @@ function scheduleActivityNextHandler({ options, args, headers, seq, activityType
|
|
|
173
176
|
doNotEagerlyExecute: !(options.allowEagerDispatch ?? true),
|
|
174
177
|
},
|
|
175
178
|
});
|
|
176
|
-
|
|
179
|
+
activator.completions.activity.set(seq, {
|
|
177
180
|
resolve,
|
|
178
181
|
reject,
|
|
179
182
|
});
|
|
@@ -192,6 +195,7 @@ async function scheduleLocalActivityNextHandler({
|
|
|
192
195
|
attempt,
|
|
193
196
|
originalScheduleTime,
|
|
194
197
|
}: LocalActivityInput): Promise<unknown> {
|
|
198
|
+
const activator = getActivator();
|
|
195
199
|
validateLocalActivityOptions(options);
|
|
196
200
|
|
|
197
201
|
return new Promise((resolve, reject) => {
|
|
@@ -203,10 +207,10 @@ async function scheduleLocalActivityNextHandler({
|
|
|
203
207
|
if (scope.cancellable) {
|
|
204
208
|
untrackPromise(
|
|
205
209
|
scope.cancelRequested.catch(() => {
|
|
206
|
-
if (!
|
|
210
|
+
if (!activator.completions.activity.has(seq)) {
|
|
207
211
|
return; // Already resolved or never scheduled
|
|
208
212
|
}
|
|
209
|
-
|
|
213
|
+
activator.pushCommand({
|
|
210
214
|
requestCancelLocalActivity: {
|
|
211
215
|
seq,
|
|
212
216
|
},
|
|
@@ -214,7 +218,7 @@ async function scheduleLocalActivityNextHandler({
|
|
|
214
218
|
})
|
|
215
219
|
);
|
|
216
220
|
}
|
|
217
|
-
|
|
221
|
+
activator.pushCommand({
|
|
218
222
|
scheduleLocalActivity: {
|
|
219
223
|
seq,
|
|
220
224
|
attempt,
|
|
@@ -222,7 +226,7 @@ async function scheduleLocalActivityNextHandler({
|
|
|
222
226
|
// Intentionally not exposing activityId as an option
|
|
223
227
|
activityId: `${seq}`,
|
|
224
228
|
activityType,
|
|
225
|
-
arguments: toPayloads(
|
|
229
|
+
arguments: toPayloads(activator.payloadConverter, ...args),
|
|
226
230
|
retryPolicy: options.retry ? compileRetryPolicy(options.retry) : undefined,
|
|
227
231
|
scheduleToCloseTimeout: msOptionalToTs(options.scheduleToCloseTimeout),
|
|
228
232
|
startToCloseTimeout: msOptionalToTs(options.startToCloseTimeout),
|
|
@@ -232,7 +236,7 @@ async function scheduleLocalActivityNextHandler({
|
|
|
232
236
|
cancellationType: options.cancellationType,
|
|
233
237
|
},
|
|
234
238
|
});
|
|
235
|
-
|
|
239
|
+
activator.completions.activity.set(seq, {
|
|
236
240
|
resolve,
|
|
237
241
|
reject,
|
|
238
242
|
});
|
|
@@ -244,11 +248,12 @@ async function scheduleLocalActivityNextHandler({
|
|
|
244
248
|
* @hidden
|
|
245
249
|
*/
|
|
246
250
|
export function scheduleActivity<R>(activityType: string, args: any[], options: ActivityOptions): Promise<R> {
|
|
251
|
+
const activator = getActivator();
|
|
247
252
|
if (options === undefined) {
|
|
248
253
|
throw new TypeError('Got empty activity options');
|
|
249
254
|
}
|
|
250
|
-
const seq =
|
|
251
|
-
const execute = composeInterceptors(
|
|
255
|
+
const seq = activator.nextSeqs.activity++;
|
|
256
|
+
const execute = composeInterceptors(activator.interceptors.outbound, 'scheduleActivity', scheduleActivityNextHandler);
|
|
252
257
|
|
|
253
258
|
return execute({
|
|
254
259
|
activityType,
|
|
@@ -268,6 +273,7 @@ export async function scheduleLocalActivity<R>(
|
|
|
268
273
|
args: any[],
|
|
269
274
|
options: LocalActivityOptions
|
|
270
275
|
): Promise<R> {
|
|
276
|
+
const activator = getActivator();
|
|
271
277
|
if (options === undefined) {
|
|
272
278
|
throw new TypeError('Got empty activity options');
|
|
273
279
|
}
|
|
@@ -276,9 +282,9 @@ export async function scheduleLocalActivity<R>(
|
|
|
276
282
|
let originalScheduleTime = undefined;
|
|
277
283
|
|
|
278
284
|
for (;;) {
|
|
279
|
-
const seq =
|
|
285
|
+
const seq = activator.nextSeqs.activity++;
|
|
280
286
|
const execute = composeInterceptors(
|
|
281
|
-
|
|
287
|
+
activator.interceptors.outbound,
|
|
282
288
|
'scheduleLocalActivity',
|
|
283
289
|
scheduleLocalActivityNextHandler
|
|
284
290
|
);
|
|
@@ -314,6 +320,7 @@ function startChildWorkflowExecutionNextHandler({
|
|
|
314
320
|
workflowType,
|
|
315
321
|
seq,
|
|
316
322
|
}: StartChildWorkflowExecutionInput): Promise<[Promise<string>, Promise<unknown>]> {
|
|
323
|
+
const activator = getActivator();
|
|
317
324
|
const workflowId = options.workflowId ?? uuid4();
|
|
318
325
|
const startPromise = new Promise<string>((resolve, reject) => {
|
|
319
326
|
const scope = CancellationScope.current();
|
|
@@ -324,10 +331,10 @@ function startChildWorkflowExecutionNextHandler({
|
|
|
324
331
|
if (scope.cancellable) {
|
|
325
332
|
untrackPromise(
|
|
326
333
|
scope.cancelRequested.catch(() => {
|
|
327
|
-
const complete = !
|
|
334
|
+
const complete = !activator.completions.childWorkflowComplete.has(seq);
|
|
328
335
|
|
|
329
336
|
if (!complete) {
|
|
330
|
-
|
|
337
|
+
activator.pushCommand({
|
|
331
338
|
cancelChildWorkflowExecution: { childWorkflowSeq: seq },
|
|
332
339
|
});
|
|
333
340
|
}
|
|
@@ -335,14 +342,14 @@ function startChildWorkflowExecutionNextHandler({
|
|
|
335
342
|
})
|
|
336
343
|
);
|
|
337
344
|
}
|
|
338
|
-
|
|
345
|
+
activator.pushCommand({
|
|
339
346
|
startChildWorkflowExecution: {
|
|
340
347
|
seq,
|
|
341
348
|
workflowId,
|
|
342
349
|
workflowType,
|
|
343
|
-
input: toPayloads(
|
|
350
|
+
input: toPayloads(activator.payloadConverter, ...options.args),
|
|
344
351
|
retryPolicy: options.retry ? compileRetryPolicy(options.retry) : undefined,
|
|
345
|
-
taskQueue: options.taskQueue ||
|
|
352
|
+
taskQueue: options.taskQueue || activator.info?.taskQueue,
|
|
346
353
|
workflowExecutionTimeout: msOptionalToTs(options.workflowExecutionTimeout),
|
|
347
354
|
workflowRunTimeout: msOptionalToTs(options.workflowRunTimeout),
|
|
348
355
|
workflowTaskTimeout: msOptionalToTs(options.workflowTaskTimeout),
|
|
@@ -355,10 +362,10 @@ function startChildWorkflowExecutionNextHandler({
|
|
|
355
362
|
searchAttributes: options.searchAttributes
|
|
356
363
|
? mapToPayloads(searchAttributePayloadConverter, options.searchAttributes)
|
|
357
364
|
: undefined,
|
|
358
|
-
memo: options.memo && mapToPayloads(
|
|
365
|
+
memo: options.memo && mapToPayloads(activator.payloadConverter, options.memo),
|
|
359
366
|
},
|
|
360
367
|
});
|
|
361
|
-
|
|
368
|
+
activator.completions.childWorkflowStart.set(seq, {
|
|
362
369
|
resolve,
|
|
363
370
|
reject,
|
|
364
371
|
});
|
|
@@ -369,7 +376,7 @@ function startChildWorkflowExecutionNextHandler({
|
|
|
369
376
|
const completePromise = new Promise((resolve, reject) => {
|
|
370
377
|
// Chain start Promise rejection to the complete Promise.
|
|
371
378
|
untrackPromise(startPromise.catch(reject));
|
|
372
|
-
|
|
379
|
+
activator.completions.childWorkflowComplete.set(seq, {
|
|
373
380
|
resolve,
|
|
374
381
|
reject,
|
|
375
382
|
});
|
|
@@ -384,10 +391,8 @@ function startChildWorkflowExecutionNextHandler({
|
|
|
384
391
|
}
|
|
385
392
|
|
|
386
393
|
function signalWorkflowNextHandler({ seq, signalName, args, target, headers }: SignalWorkflowInput) {
|
|
394
|
+
const activator = getActivator();
|
|
387
395
|
return new Promise<any>((resolve, reject) => {
|
|
388
|
-
if (state.info === undefined) {
|
|
389
|
-
throw new IllegalStateError('Workflow uninitialized');
|
|
390
|
-
}
|
|
391
396
|
const scope = CancellationScope.current();
|
|
392
397
|
if (scope.consideredCancelled) {
|
|
393
398
|
untrackPromise(scope.cancelRequested.catch(reject));
|
|
@@ -397,23 +402,23 @@ function signalWorkflowNextHandler({ seq, signalName, args, target, headers }: S
|
|
|
397
402
|
if (scope.cancellable) {
|
|
398
403
|
untrackPromise(
|
|
399
404
|
scope.cancelRequested.catch(() => {
|
|
400
|
-
if (!
|
|
405
|
+
if (!activator.completions.signalWorkflow.has(seq)) {
|
|
401
406
|
return;
|
|
402
407
|
}
|
|
403
|
-
|
|
408
|
+
activator.pushCommand({ cancelSignalWorkflow: { seq } });
|
|
404
409
|
})
|
|
405
410
|
);
|
|
406
411
|
}
|
|
407
|
-
|
|
412
|
+
activator.pushCommand({
|
|
408
413
|
signalExternalWorkflowExecution: {
|
|
409
414
|
seq,
|
|
410
|
-
args: toPayloads(
|
|
415
|
+
args: toPayloads(activator.payloadConverter, ...args),
|
|
411
416
|
headers,
|
|
412
417
|
signalName,
|
|
413
418
|
...(target.type === 'external'
|
|
414
419
|
? {
|
|
415
420
|
workflowExecution: {
|
|
416
|
-
namespace:
|
|
421
|
+
namespace: activator.info.namespace,
|
|
417
422
|
...target.workflowExecution,
|
|
418
423
|
},
|
|
419
424
|
}
|
|
@@ -423,7 +428,7 @@ function signalWorkflowNextHandler({ seq, signalName, args, target, headers }: S
|
|
|
423
428
|
},
|
|
424
429
|
});
|
|
425
430
|
|
|
426
|
-
|
|
431
|
+
activator.completions.signalWorkflow.set(seq, { resolve, reject });
|
|
427
432
|
});
|
|
428
433
|
}
|
|
429
434
|
|
|
@@ -564,15 +569,12 @@ const EXTERNAL_WF_CANCEL_PATCH = '__temporal_internal_connect_external_handle_ca
|
|
|
564
569
|
* It takes a Workflow ID and optional run ID.
|
|
565
570
|
*/
|
|
566
571
|
export function getExternalWorkflowHandle(workflowId: string, runId?: string): ExternalWorkflowHandle {
|
|
572
|
+
const activator = getActivator();
|
|
567
573
|
return {
|
|
568
574
|
workflowId,
|
|
569
575
|
runId,
|
|
570
576
|
cancel() {
|
|
571
577
|
return new Promise<void>((resolve, reject) => {
|
|
572
|
-
if (state.info === undefined) {
|
|
573
|
-
throw new IllegalStateError('Uninitialized workflow');
|
|
574
|
-
}
|
|
575
|
-
|
|
576
578
|
// Connect this cancel operation to the current cancellation scope.
|
|
577
579
|
// This is behavior was introduced after v0.22.0 and is incompatible
|
|
578
580
|
// with histories generated with previous SDK versions and thus requires
|
|
@@ -596,27 +598,27 @@ export function getExternalWorkflowHandle(workflowId: string, runId?: string): E
|
|
|
596
598
|
}
|
|
597
599
|
}
|
|
598
600
|
|
|
599
|
-
const seq =
|
|
600
|
-
|
|
601
|
+
const seq = activator.nextSeqs.cancelWorkflow++;
|
|
602
|
+
activator.pushCommand({
|
|
601
603
|
requestCancelExternalWorkflowExecution: {
|
|
602
604
|
seq,
|
|
603
605
|
workflowExecution: {
|
|
604
|
-
namespace:
|
|
606
|
+
namespace: activator.info.namespace,
|
|
605
607
|
workflowId,
|
|
606
608
|
runId,
|
|
607
609
|
},
|
|
608
610
|
},
|
|
609
611
|
});
|
|
610
|
-
|
|
612
|
+
activator.completions.cancelWorkflow.set(seq, { resolve, reject });
|
|
611
613
|
});
|
|
612
614
|
},
|
|
613
615
|
signal<Args extends any[]>(def: SignalDefinition<Args> | string, ...args: Args): Promise<void> {
|
|
614
616
|
return composeInterceptors(
|
|
615
|
-
|
|
617
|
+
activator.interceptors.outbound,
|
|
616
618
|
'signalWorkflow',
|
|
617
619
|
signalWorkflowNextHandler
|
|
618
620
|
)({
|
|
619
|
-
seq:
|
|
621
|
+
seq: activator.nextSeqs.signalWorkflow++,
|
|
620
622
|
signalName: typeof def === 'string' ? def : def.name,
|
|
621
623
|
args,
|
|
622
624
|
target: {
|
|
@@ -689,15 +691,16 @@ export async function startChild<T extends Workflow>(
|
|
|
689
691
|
workflowTypeOrFunc: string | T,
|
|
690
692
|
options?: WithWorkflowArgs<T, ChildWorkflowOptions>
|
|
691
693
|
): Promise<ChildWorkflowHandle<T>> {
|
|
694
|
+
const activator = getActivator();
|
|
692
695
|
const optionsWithDefaults = addDefaultWorkflowOptions(options ?? {});
|
|
693
696
|
const workflowType = typeof workflowTypeOrFunc === 'string' ? workflowTypeOrFunc : workflowTypeOrFunc.name;
|
|
694
697
|
const execute = composeInterceptors(
|
|
695
|
-
|
|
698
|
+
activator.interceptors.outbound,
|
|
696
699
|
'startChildWorkflowExecution',
|
|
697
700
|
startChildWorkflowExecutionNextHandler
|
|
698
701
|
);
|
|
699
702
|
const [started, completed] = await execute({
|
|
700
|
-
seq:
|
|
703
|
+
seq: activator.nextSeqs.childWorkflow++,
|
|
701
704
|
options: optionsWithDefaults,
|
|
702
705
|
headers: {},
|
|
703
706
|
workflowType,
|
|
@@ -712,11 +715,11 @@ export async function startChild<T extends Workflow>(
|
|
|
712
715
|
},
|
|
713
716
|
async signal<Args extends any[]>(def: SignalDefinition<Args> | string, ...args: Args): Promise<void> {
|
|
714
717
|
return composeInterceptors(
|
|
715
|
-
|
|
718
|
+
activator.interceptors.outbound,
|
|
716
719
|
'signalWorkflow',
|
|
717
720
|
signalWorkflowNextHandler
|
|
718
721
|
)({
|
|
719
|
-
seq:
|
|
722
|
+
seq: activator.nextSeqs.signalWorkflow++,
|
|
720
723
|
signalName: typeof def === 'string' ? def : def.name,
|
|
721
724
|
args,
|
|
722
725
|
target: {
|
|
@@ -787,15 +790,16 @@ export async function executeChild<T extends Workflow>(
|
|
|
787
790
|
workflowTypeOrFunc: string | T,
|
|
788
791
|
options?: WithWorkflowArgs<T, ChildWorkflowOptions>
|
|
789
792
|
): Promise<WorkflowResultType<T>> {
|
|
793
|
+
const activator = getActivator();
|
|
790
794
|
const optionsWithDefaults = addDefaultWorkflowOptions(options ?? {});
|
|
791
795
|
const workflowType = typeof workflowTypeOrFunc === 'string' ? workflowTypeOrFunc : workflowTypeOrFunc.name;
|
|
792
796
|
const execute = composeInterceptors(
|
|
793
|
-
|
|
797
|
+
activator.interceptors.outbound,
|
|
794
798
|
'startChildWorkflowExecution',
|
|
795
799
|
startChildWorkflowExecutionNextHandler
|
|
796
800
|
);
|
|
797
801
|
const execPromise = execute({
|
|
798
|
-
seq:
|
|
802
|
+
seq: activator.nextSeqs.childWorkflow++,
|
|
799
803
|
options: optionsWithDefaults,
|
|
800
804
|
headers: {},
|
|
801
805
|
workflowType,
|
|
@@ -832,10 +836,7 @@ export async function executeChild<T extends Workflow>(
|
|
|
832
836
|
* }
|
|
833
837
|
*/
|
|
834
838
|
export function workflowInfo(): WorkflowInfo {
|
|
835
|
-
|
|
836
|
-
throw new IllegalStateError('Workflow uninitialized');
|
|
837
|
-
}
|
|
838
|
-
return state.info;
|
|
839
|
+
return getActivator().info;
|
|
839
840
|
}
|
|
840
841
|
|
|
841
842
|
/**
|
|
@@ -843,7 +844,7 @@ export function workflowInfo(): WorkflowInfo {
|
|
|
843
844
|
*/
|
|
844
845
|
export function inWorkflowContext(): boolean {
|
|
845
846
|
try {
|
|
846
|
-
|
|
847
|
+
getActivator();
|
|
847
848
|
return true;
|
|
848
849
|
} catch (err: any) {
|
|
849
850
|
// Use string comparison in case multiple versions of @temporalio/common are
|
|
@@ -896,7 +897,8 @@ export function proxySinks<T extends Sinks>(): T {
|
|
|
896
897
|
{
|
|
897
898
|
get(_, fnName) {
|
|
898
899
|
return (...args: any[]) => {
|
|
899
|
-
|
|
900
|
+
const activator = getActivator();
|
|
901
|
+
activator.sinkCalls.push({
|
|
900
902
|
ifaceName: ifaceName as string,
|
|
901
903
|
fnName: fnName as string,
|
|
902
904
|
args,
|
|
@@ -920,6 +922,7 @@ export function proxySinks<T extends Sinks>(): T {
|
|
|
920
922
|
export function makeContinueAsNewFunc<F extends Workflow>(
|
|
921
923
|
options?: ContinueAsNewOptions
|
|
922
924
|
): (...args: Parameters<F>) => Promise<never> {
|
|
925
|
+
const activator = getActivator();
|
|
923
926
|
const info = workflowInfo();
|
|
924
927
|
const { workflowType, taskQueue, ...rest } = options ?? {};
|
|
925
928
|
const requiredOptions = {
|
|
@@ -929,14 +932,14 @@ export function makeContinueAsNewFunc<F extends Workflow>(
|
|
|
929
932
|
};
|
|
930
933
|
|
|
931
934
|
return (...args: Parameters<F>): Promise<never> => {
|
|
932
|
-
const fn = composeInterceptors(
|
|
935
|
+
const fn = composeInterceptors(activator.interceptors.outbound, 'continueAsNew', async (input) => {
|
|
933
936
|
const { headers, args, options } = input;
|
|
934
937
|
throw new ContinueAsNew({
|
|
935
938
|
workflowType: options.workflowType,
|
|
936
|
-
arguments: toPayloads(
|
|
939
|
+
arguments: toPayloads(activator.payloadConverter, ...args),
|
|
937
940
|
headers,
|
|
938
941
|
taskQueue: options.taskQueue,
|
|
939
|
-
memo: options.memo,
|
|
942
|
+
memo: options.memo && mapToPayloads(activator.payloadConverter, options.memo),
|
|
940
943
|
searchAttributes: options.searchAttributes
|
|
941
944
|
? mapToPayloads(searchAttributePayloadConverter, options.searchAttributes)
|
|
942
945
|
: undefined,
|
|
@@ -1043,23 +1046,21 @@ export function deprecatePatch(patchId: string): void {
|
|
|
1043
1046
|
}
|
|
1044
1047
|
|
|
1045
1048
|
function patchInternal(patchId: string, deprecated: boolean): boolean {
|
|
1049
|
+
const activator = getActivator();
|
|
1046
1050
|
// Patch operation does not support interception at the moment, if it did,
|
|
1047
1051
|
// this would be the place to start the interception chain
|
|
1048
1052
|
|
|
1049
|
-
if (
|
|
1053
|
+
if (activator.workflow === undefined) {
|
|
1050
1054
|
throw new IllegalStateError('Patches cannot be used before Workflow starts');
|
|
1051
1055
|
}
|
|
1052
|
-
|
|
1053
|
-
throw new IllegalStateError('Workflow uninitialized');
|
|
1054
|
-
}
|
|
1055
|
-
const usePatch = !state.info.unsafe.isReplaying || state.knownPresentPatches.has(patchId);
|
|
1056
|
+
const usePatch = !activator.info.unsafe.isReplaying || activator.knownPresentPatches.has(patchId);
|
|
1056
1057
|
// Avoid sending commands for patches core already knows about.
|
|
1057
1058
|
// This optimization enables development of automatic patching tools.
|
|
1058
|
-
if (usePatch && !
|
|
1059
|
-
|
|
1059
|
+
if (usePatch && !activator.sentPatches.has(patchId)) {
|
|
1060
|
+
activator.pushCommand({
|
|
1060
1061
|
setPatchMarker: { patchId, deprecated },
|
|
1061
1062
|
});
|
|
1062
|
-
|
|
1063
|
+
activator.sentPatches.add(patchId);
|
|
1063
1064
|
}
|
|
1064
1065
|
return usePatch;
|
|
1065
1066
|
}
|
|
@@ -1079,7 +1080,11 @@ export function condition(fn: () => boolean, timeout: number | string): Promise<
|
|
|
1079
1080
|
export function condition(fn: () => boolean): Promise<void>;
|
|
1080
1081
|
|
|
1081
1082
|
export async function condition(fn: () => boolean, timeout?: number | string): Promise<void | boolean> {
|
|
1082
|
-
|
|
1083
|
+
// Prior to 1.5.0, `condition(fn, 0)` was treated as equivalent to `condition(fn, undefined)`
|
|
1084
|
+
if (timeout === 0 && !getActivator().checkInternalPatchAtLeast(1)) {
|
|
1085
|
+
return conditionInner(fn);
|
|
1086
|
+
}
|
|
1087
|
+
if (typeof timeout === 'number' || typeof timeout === 'string') {
|
|
1083
1088
|
return CancellationScope.cancellable(async () => {
|
|
1084
1089
|
try {
|
|
1085
1090
|
return await Promise.race([sleep(timeout).then(() => false), conditionInner(fn).then(() => true)]);
|
|
@@ -1092,6 +1097,7 @@ export async function condition(fn: () => boolean, timeout?: number | string): P
|
|
|
1092
1097
|
}
|
|
1093
1098
|
|
|
1094
1099
|
function conditionInner(fn: () => boolean): Promise<void> {
|
|
1100
|
+
const activator = getActivator();
|
|
1095
1101
|
return new Promise((resolve, reject) => {
|
|
1096
1102
|
const scope = CancellationScope.current();
|
|
1097
1103
|
if (scope.consideredCancelled) {
|
|
@@ -1099,11 +1105,11 @@ function conditionInner(fn: () => boolean): Promise<void> {
|
|
|
1099
1105
|
return;
|
|
1100
1106
|
}
|
|
1101
1107
|
|
|
1102
|
-
const seq =
|
|
1108
|
+
const seq = activator.nextSeqs.condition++;
|
|
1103
1109
|
if (scope.cancellable) {
|
|
1104
1110
|
untrackPromise(
|
|
1105
1111
|
scope.cancelRequested.catch((err) => {
|
|
1106
|
-
|
|
1112
|
+
activator.blockedConditions.delete(seq);
|
|
1107
1113
|
reject(err);
|
|
1108
1114
|
})
|
|
1109
1115
|
);
|
|
@@ -1115,7 +1121,7 @@ function conditionInner(fn: () => boolean): Promise<void> {
|
|
|
1115
1121
|
return;
|
|
1116
1122
|
}
|
|
1117
1123
|
|
|
1118
|
-
|
|
1124
|
+
activator.blockedConditions.set(seq, { fn, resolve });
|
|
1119
1125
|
});
|
|
1120
1126
|
}
|
|
1121
1127
|
|
|
@@ -1170,17 +1176,18 @@ export function setHandler<Ret, Args extends any[], T extends SignalDefinition<A
|
|
|
1170
1176
|
def: T,
|
|
1171
1177
|
handler: Handler<Ret, Args, T> | undefined
|
|
1172
1178
|
): void {
|
|
1179
|
+
const activator = getActivator();
|
|
1173
1180
|
if (def.type === 'signal') {
|
|
1174
|
-
|
|
1175
|
-
const bufferedSignals =
|
|
1181
|
+
activator.signalHandlers.set(def.name, handler as any);
|
|
1182
|
+
const bufferedSignals = activator.bufferedSignals.get(def.name);
|
|
1176
1183
|
if (bufferedSignals !== undefined && handler !== undefined) {
|
|
1177
|
-
|
|
1184
|
+
activator.bufferedSignals.delete(def.name);
|
|
1178
1185
|
for (const signal of bufferedSignals) {
|
|
1179
|
-
|
|
1186
|
+
activator.signalWorkflow(signal);
|
|
1180
1187
|
}
|
|
1181
1188
|
}
|
|
1182
1189
|
} else if (def.type === 'query') {
|
|
1183
|
-
|
|
1190
|
+
activator.queryHandlers.set(def.name, handler as any);
|
|
1184
1191
|
} else {
|
|
1185
1192
|
throw new TypeError(`Invalid definition type: ${(def as any).type}`);
|
|
1186
1193
|
}
|
|
@@ -1216,22 +1223,20 @@ export function setHandler<Ret, Args extends any[], T extends SignalDefinition<A
|
|
|
1216
1223
|
* @param searchAttributes The Record to merge. Use a value of `[]` to clear a Search Attribute.
|
|
1217
1224
|
*/
|
|
1218
1225
|
export function upsertSearchAttributes(searchAttributes: SearchAttributes): void {
|
|
1219
|
-
|
|
1220
|
-
throw new IllegalStateError('`state.info` should be defined');
|
|
1221
|
-
}
|
|
1226
|
+
const activator = getActivator();
|
|
1222
1227
|
|
|
1223
|
-
const mergedSearchAttributes = { ...
|
|
1228
|
+
const mergedSearchAttributes = { ...activator.info.searchAttributes, ...searchAttributes };
|
|
1224
1229
|
if (!mergedSearchAttributes) {
|
|
1225
1230
|
throw new Error('searchAttributes must be a non-null SearchAttributes');
|
|
1226
1231
|
}
|
|
1227
1232
|
|
|
1228
|
-
|
|
1233
|
+
activator.pushCommand({
|
|
1229
1234
|
upsertWorkflowSearchAttributes: {
|
|
1230
1235
|
searchAttributes: mapToPayloads(searchAttributePayloadConverter, searchAttributes),
|
|
1231
1236
|
},
|
|
1232
1237
|
});
|
|
1233
1238
|
|
|
1234
|
-
|
|
1239
|
+
activator.info.searchAttributes = mergedSearchAttributes;
|
|
1235
1240
|
}
|
|
1236
1241
|
|
|
1237
1242
|
export const stackTraceQuery = defineQuery<string>('__stack_trace');
|