@temporalio/client 1.11.3 → 1.11.4
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/async-completion-client.js +4 -4
- package/lib/async-completion-client.js.map +1 -1
- package/lib/base-client.d.ts +2 -3
- package/lib/base-client.js +4 -4
- package/lib/base-client.js.map +1 -1
- package/lib/build-id-types.js +1 -2
- package/lib/build-id-types.js.map +1 -1
- package/lib/client.d.ts +3 -4
- package/lib/client.js +1 -0
- package/lib/client.js.map +1 -1
- package/lib/connection.d.ts +2 -4
- package/lib/connection.js +5 -5
- package/lib/connection.js.map +1 -1
- package/lib/errors.d.ts +15 -0
- package/lib/errors.js +36 -2
- package/lib/errors.js.map +1 -1
- package/lib/grpc-retry.js +4 -5
- package/lib/grpc-retry.js.map +1 -1
- package/lib/helpers.js +2 -3
- package/lib/helpers.js.map +1 -1
- package/lib/iterators-utils.js +1 -2
- package/lib/iterators-utils.js.map +1 -1
- package/lib/schedule-client.js +7 -5
- package/lib/schedule-client.js.map +1 -1
- package/lib/schedule-helpers.d.ts +1 -3
- package/lib/schedule-helpers.js +14 -27
- package/lib/schedule-helpers.js.map +1 -1
- package/lib/schedule-types.d.ts +17 -14
- package/lib/schedule-types.js +27 -18
- package/lib/schedule-types.js.map +1 -1
- package/lib/task-queue-client.d.ts +12 -1
- package/lib/task-queue-client.js +23 -38
- package/lib/task-queue-client.js.map +1 -1
- package/lib/types.d.ts +17 -3
- package/lib/types.js +22 -1
- package/lib/types.js.map +1 -1
- package/lib/workflow-client.d.ts +6 -6
- package/lib/workflow-client.js +20 -36
- package/lib/workflow-client.js.map +1 -1
- package/lib/workflow-options.d.ts +2 -1
- package/lib/workflow-options.js +1 -2
- package/lib/workflow-options.js.map +1 -1
- package/lib/workflow-update-stage.d.ts +12 -8
- package/lib/workflow-update-stage.js +18 -17
- package/lib/workflow-update-stage.js.map +1 -1
- package/package.json +4 -4
- package/src/async-completion-client.ts +4 -5
- package/src/base-client.ts +2 -2
- package/src/client.ts +4 -4
- package/src/connection.ts +2 -2
- package/src/errors.ts +34 -1
- package/src/schedule-client.ts +7 -6
- package/src/schedule-helpers.ts +2 -17
- package/src/schedule-types.ts +35 -22
- package/src/task-queue-client.ts +37 -38
- package/src/types.ts +38 -2
- package/src/workflow-client.ts +35 -28
- package/src/workflow-options.ts +2 -1
- package/src/workflow-update-stage.ts +29 -21
package/src/errors.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ServiceError as GrpcServiceError } from '@grpc/grpc-js';
|
|
1
|
+
import { ServiceError as GrpcServiceError, status } from '@grpc/grpc-js';
|
|
2
2
|
import { RetryState, TemporalFailure } from '@temporalio/common';
|
|
3
3
|
import { isError, isRecord, SymbolBasedInstanceOfError } from '@temporalio/common/lib/type-helpers';
|
|
4
4
|
|
|
@@ -79,6 +79,9 @@ export class WorkflowContinuedAsNewError extends Error {
|
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
/**
|
|
83
|
+
* Returns true if the provided error is a {@link GrpcServiceError}.
|
|
84
|
+
*/
|
|
82
85
|
export function isGrpcServiceError(err: unknown): err is GrpcServiceError {
|
|
83
86
|
return (
|
|
84
87
|
isError(err) &&
|
|
@@ -87,6 +90,36 @@ export function isGrpcServiceError(err: unknown): err is GrpcServiceError {
|
|
|
87
90
|
);
|
|
88
91
|
}
|
|
89
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Returns true if the provided error or its cause is a {@link GrpcServiceError} with code DEADLINE_EXCEEDED.
|
|
95
|
+
*
|
|
96
|
+
* @see {@link Connection.withDeadline}
|
|
97
|
+
*/
|
|
98
|
+
export function isGrpcDeadlineError(err: unknown): err is Error {
|
|
99
|
+
while (isError(err)) {
|
|
100
|
+
if (isGrpcServiceError(err) && (err as GrpcServiceError).code === status.DEADLINE_EXCEEDED) {
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
err = (err as any).cause;
|
|
104
|
+
}
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Returns true if the provided error or its cause is a {@link GrpcServiceError} with code CANCELLED.
|
|
110
|
+
*
|
|
111
|
+
* @see {@link Connection.withAbortSignal}
|
|
112
|
+
*/
|
|
113
|
+
export function isGrpcCancelledError(err: unknown): err is Error {
|
|
114
|
+
while (isError(err)) {
|
|
115
|
+
if (isGrpcServiceError(err) && (err as GrpcServiceError).code === status.CANCELLED) {
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
err = (err as any).cause;
|
|
119
|
+
}
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
|
|
90
123
|
/**
|
|
91
124
|
* @deprecated Use `isGrpcServiceError` instead
|
|
92
125
|
*/
|
package/src/schedule-client.ts
CHANGED
|
@@ -29,17 +29,17 @@ import {
|
|
|
29
29
|
ScheduleUpdateOptions,
|
|
30
30
|
ScheduleOptionsAction,
|
|
31
31
|
ScheduleOptionsStartWorkflowAction,
|
|
32
|
+
encodeScheduleOverlapPolicy,
|
|
33
|
+
decodeScheduleOverlapPolicy,
|
|
32
34
|
} from './schedule-types';
|
|
33
35
|
import {
|
|
34
36
|
compileScheduleOptions,
|
|
35
37
|
compileUpdatedScheduleOptions,
|
|
36
|
-
decodeOverlapPolicy,
|
|
37
38
|
decodeScheduleAction,
|
|
38
39
|
decodeScheduleRecentActions,
|
|
39
40
|
decodeScheduleRunningActions,
|
|
40
41
|
decodeScheduleSpec,
|
|
41
42
|
decodeSearchAttributes,
|
|
42
|
-
encodeOverlapPolicy,
|
|
43
43
|
encodeScheduleAction,
|
|
44
44
|
encodeSchedulePolicies,
|
|
45
45
|
encodeScheduleSpec,
|
|
@@ -251,7 +251,7 @@ export class ScheduleClient extends BaseClient {
|
|
|
251
251
|
? opts.state.backfill.map((x) => ({
|
|
252
252
|
startTime: optionalDateToTs(x.start),
|
|
253
253
|
endTime: optionalDateToTs(x.end),
|
|
254
|
-
overlapPolicy: x.overlap ?
|
|
254
|
+
overlapPolicy: x.overlap ? encodeScheduleOverlapPolicy(x.overlap) : undefined,
|
|
255
255
|
}))
|
|
256
256
|
: undefined,
|
|
257
257
|
},
|
|
@@ -427,7 +427,8 @@ export class ScheduleClient extends BaseClient {
|
|
|
427
427
|
memo: await decodeMapFromPayloads(this.client.dataConverter, raw.memo?.fields),
|
|
428
428
|
searchAttributes: decodeSearchAttributes(raw.searchAttributes),
|
|
429
429
|
policies: {
|
|
430
|
-
overlap
|
|
430
|
+
// 'overlap' should never be missing on describe, as the server will replace UNSPECIFIED by an actual value
|
|
431
|
+
overlap: decodeScheduleOverlapPolicy(raw.schedule.policies?.overlapPolicy) ?? ScheduleOverlapPolicy.SKIP,
|
|
431
432
|
catchupWindow: optionalTsToMs(raw.schedule.policies?.catchupWindow) ?? 60_000,
|
|
432
433
|
pauseOnFailure: raw.schedule.policies?.pauseOnFailure === true,
|
|
433
434
|
},
|
|
@@ -485,7 +486,7 @@ export class ScheduleClient extends BaseClient {
|
|
|
485
486
|
await this.client._patchSchedule(this.scheduleId, {
|
|
486
487
|
triggerImmediately: {
|
|
487
488
|
overlapPolicy: overlap
|
|
488
|
-
?
|
|
489
|
+
? encodeScheduleOverlapPolicy(overlap)
|
|
489
490
|
: temporal.api.enums.v1.ScheduleOverlapPolicy.SCHEDULE_OVERLAP_POLICY_ALLOW_ALL,
|
|
490
491
|
},
|
|
491
492
|
});
|
|
@@ -497,7 +498,7 @@ export class ScheduleClient extends BaseClient {
|
|
|
497
498
|
backfillRequest: backfills.map((x) => ({
|
|
498
499
|
startTime: optionalDateToTs(x.start),
|
|
499
500
|
endTime: optionalDateToTs(x.end),
|
|
500
|
-
overlapPolicy: x.overlap ?
|
|
501
|
+
overlapPolicy: x.overlap ? encodeScheduleOverlapPolicy(x.overlap) : undefined,
|
|
501
502
|
})),
|
|
502
503
|
});
|
|
503
504
|
},
|
package/src/schedule-helpers.ts
CHANGED
|
@@ -32,7 +32,6 @@ import {
|
|
|
32
32
|
CompiledScheduleUpdateOptions,
|
|
33
33
|
Range,
|
|
34
34
|
ScheduleOptions,
|
|
35
|
-
ScheduleOverlapPolicy,
|
|
36
35
|
ScheduleUpdateOptions,
|
|
37
36
|
DayOfWeek,
|
|
38
37
|
DAYS_OF_WEEK,
|
|
@@ -47,6 +46,7 @@ import {
|
|
|
47
46
|
ScheduleExecutionActionResult,
|
|
48
47
|
ScheduleExecutionResult,
|
|
49
48
|
ScheduleExecutionStartWorkflowActionResult,
|
|
49
|
+
encodeScheduleOverlapPolicy,
|
|
50
50
|
} from './schedule-types';
|
|
51
51
|
|
|
52
52
|
const [encodeSecond, decodeSecond] = makeCalendarSpecFieldCoders(
|
|
@@ -192,21 +192,6 @@ export function decodeOptionalStructuredCalendarSpecs(
|
|
|
192
192
|
);
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
-
export function encodeOverlapPolicy(input: ScheduleOverlapPolicy): temporal.api.enums.v1.ScheduleOverlapPolicy {
|
|
196
|
-
return temporal.api.enums.v1.ScheduleOverlapPolicy[
|
|
197
|
-
`SCHEDULE_OVERLAP_POLICY_${ScheduleOverlapPolicy[input] as keyof typeof ScheduleOverlapPolicy}`
|
|
198
|
-
];
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
export function decodeOverlapPolicy(input?: temporal.api.enums.v1.ScheduleOverlapPolicy | null): ScheduleOverlapPolicy {
|
|
202
|
-
if (!input) return ScheduleOverlapPolicy.UNSPECIFIED;
|
|
203
|
-
const encodedPolicyName = temporal.api.enums.v1.ScheduleOverlapPolicy[input];
|
|
204
|
-
const decodedPolicyName = encodedPolicyName.substring(
|
|
205
|
-
'SCHEDULE_OVERLAP_POLICY_'.length
|
|
206
|
-
) as keyof typeof ScheduleOverlapPolicy;
|
|
207
|
-
return ScheduleOverlapPolicy[decodedPolicyName];
|
|
208
|
-
}
|
|
209
|
-
|
|
210
195
|
export function compileScheduleOptions(options: ScheduleOptions): CompiledScheduleOptions {
|
|
211
196
|
const workflowTypeOrFunc = options.action.workflowType;
|
|
212
197
|
const workflowType = extractWorkflowType(workflowTypeOrFunc);
|
|
@@ -290,7 +275,7 @@ export function encodeSchedulePolicies(
|
|
|
290
275
|
): temporal.api.schedule.v1.ISchedulePolicies {
|
|
291
276
|
return {
|
|
292
277
|
catchupWindow: msOptionalToTs(policies?.catchupWindow),
|
|
293
|
-
overlapPolicy: policies?.overlap ?
|
|
278
|
+
overlapPolicy: policies?.overlap ? encodeScheduleOverlapPolicy(policies.overlap) : undefined,
|
|
294
279
|
pauseOnFailure: policies?.pauseOnFailure,
|
|
295
280
|
};
|
|
296
281
|
}
|
package/src/schedule-types.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { checkExtends, Replace } from '@temporalio/common/lib/type-helpers';
|
|
2
2
|
import { Duration, SearchAttributes, Workflow } from '@temporalio/common';
|
|
3
|
+
import { makeProtoEnumConverters } from '@temporalio/common/lib/internal-workflow';
|
|
3
4
|
import type { temporal } from '@temporalio/proto';
|
|
4
5
|
import { WorkflowStartOptions } from './workflow-options';
|
|
5
6
|
|
|
@@ -795,57 +796,69 @@ export type CompiledScheduleAction = Replace<
|
|
|
795
796
|
/**
|
|
796
797
|
* Policy for overlapping Actions.
|
|
797
798
|
*/
|
|
798
|
-
export
|
|
799
|
-
/**
|
|
800
|
-
* Use server default (currently SKIP).
|
|
801
|
-
*
|
|
802
|
-
* FIXME: remove this field if this issue is implemented: https://github.com/temporalio/temporal/issues/3240
|
|
803
|
-
*/
|
|
804
|
-
UNSPECIFIED = 0,
|
|
805
|
-
|
|
799
|
+
export const ScheduleOverlapPolicy = {
|
|
806
800
|
/**
|
|
807
801
|
* Don't start a new Action.
|
|
802
|
+
* @default
|
|
808
803
|
*/
|
|
809
|
-
SKIP,
|
|
804
|
+
SKIP: 'SKIP',
|
|
810
805
|
|
|
811
806
|
/**
|
|
812
807
|
* Start another Action as soon as the current Action completes, but only buffer one Action in this way. If another
|
|
813
808
|
* Action is supposed to start, but one Action is running and one is already buffered, then only the buffered one will
|
|
814
809
|
* be started after the running Action finishes.
|
|
815
810
|
*/
|
|
816
|
-
BUFFER_ONE,
|
|
811
|
+
BUFFER_ONE: 'BUFFER_ONE',
|
|
817
812
|
|
|
818
813
|
/**
|
|
819
814
|
* Allows an unlimited number of Actions to buffer. They are started sequentially.
|
|
820
815
|
*/
|
|
821
|
-
BUFFER_ALL,
|
|
816
|
+
BUFFER_ALL: 'BUFFER_ALL',
|
|
822
817
|
|
|
823
818
|
/**
|
|
824
819
|
* Cancels the running Action, and then starts the new Action once the cancelled one completes.
|
|
825
820
|
*/
|
|
826
|
-
CANCEL_OTHER,
|
|
821
|
+
CANCEL_OTHER: 'CANCEL_OTHER',
|
|
827
822
|
|
|
828
823
|
/**
|
|
829
824
|
* Terminate the running Action and start the new Action immediately.
|
|
830
825
|
*/
|
|
831
|
-
TERMINATE_OTHER,
|
|
826
|
+
TERMINATE_OTHER: 'TERMINATE_OTHER',
|
|
832
827
|
|
|
833
828
|
/**
|
|
834
829
|
* Allow any number of Actions to start immediately.
|
|
835
830
|
*
|
|
836
831
|
* This is the only policy under which multiple Actions can run concurrently.
|
|
837
832
|
*/
|
|
838
|
-
ALLOW_ALL,
|
|
839
|
-
}
|
|
833
|
+
ALLOW_ALL: 'ALLOW_ALL',
|
|
840
834
|
|
|
841
|
-
|
|
835
|
+
/**
|
|
836
|
+
* Use server default (currently SKIP).
|
|
837
|
+
*
|
|
838
|
+
* @deprecated Either leave property `undefined`, or use {@link SKIP} instead.
|
|
839
|
+
*/
|
|
840
|
+
UNSPECIFIED: undefined, // eslint-disable-line deprecation/deprecation
|
|
841
|
+
} as const;
|
|
842
|
+
export type ScheduleOverlapPolicy = (typeof ScheduleOverlapPolicy)[keyof typeof ScheduleOverlapPolicy];
|
|
843
|
+
|
|
844
|
+
export const [encodeScheduleOverlapPolicy, decodeScheduleOverlapPolicy] = makeProtoEnumConverters<
|
|
845
|
+
temporal.api.enums.v1.ScheduleOverlapPolicy,
|
|
846
|
+
typeof temporal.api.enums.v1.ScheduleOverlapPolicy,
|
|
842
847
|
keyof typeof temporal.api.enums.v1.ScheduleOverlapPolicy,
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
848
|
+
typeof ScheduleOverlapPolicy,
|
|
849
|
+
'SCHEDULE_OVERLAP_POLICY_'
|
|
850
|
+
>(
|
|
851
|
+
{
|
|
852
|
+
[ScheduleOverlapPolicy.SKIP]: 1,
|
|
853
|
+
[ScheduleOverlapPolicy.BUFFER_ONE]: 2,
|
|
854
|
+
[ScheduleOverlapPolicy.BUFFER_ALL]: 3,
|
|
855
|
+
[ScheduleOverlapPolicy.CANCEL_OTHER]: 4,
|
|
856
|
+
[ScheduleOverlapPolicy.TERMINATE_OTHER]: 5,
|
|
857
|
+
[ScheduleOverlapPolicy.ALLOW_ALL]: 6,
|
|
858
|
+
UNSPECIFIED: 0,
|
|
859
|
+
} as const,
|
|
860
|
+
'SCHEDULE_OVERLAP_POLICY_'
|
|
861
|
+
);
|
|
849
862
|
|
|
850
863
|
export interface Backfill {
|
|
851
864
|
/**
|
package/src/task-queue-client.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { status } from '@grpc/grpc-js';
|
|
2
2
|
import { filterNullAndUndefined } from '@temporalio/common/lib/internal-non-workflow';
|
|
3
3
|
import { assertNever, SymbolBasedInstanceOfError, RequireAtLeastOne } from '@temporalio/common/lib/type-helpers';
|
|
4
|
+
import { makeProtoEnumConverters } from '@temporalio/common/lib/internal-workflow';
|
|
4
5
|
import { temporal } from '@temporalio/proto';
|
|
5
6
|
import { BaseClient, BaseClientOptions, defaultBaseClientOptions, LoadedWithDefaults } from './base-client';
|
|
6
7
|
import { WorkflowService } from './types';
|
|
@@ -148,7 +149,7 @@ export class TaskQueueClient extends BaseClient {
|
|
|
148
149
|
namespace: this.options.namespace,
|
|
149
150
|
taskQueues: options.taskQueues,
|
|
150
151
|
buildIds,
|
|
151
|
-
reachability:
|
|
152
|
+
reachability: encodeTaskReachability(options.reachability),
|
|
152
153
|
});
|
|
153
154
|
} catch (e) {
|
|
154
155
|
this.rethrowGrpcError(e, 'Unexpected error fetching Build Id reachability');
|
|
@@ -173,6 +174,20 @@ export class TaskQueueClient extends BaseClient {
|
|
|
173
174
|
*/
|
|
174
175
|
export type ReachabilityOptions = RequireAtLeastOne<BaseReachabilityOptions, 'buildIds' | 'taskQueues'>;
|
|
175
176
|
|
|
177
|
+
export const ReachabilityType = {
|
|
178
|
+
/** The Build Id might be used by new workflows. */
|
|
179
|
+
NEW_WORKFLOWS: 'NEW_WORKFLOWS',
|
|
180
|
+
|
|
181
|
+
/** The Build Id might be used by open workflows and/or closed workflows. */
|
|
182
|
+
EXISTING_WORKFLOWS: 'EXISTING_WORKFLOWS',
|
|
183
|
+
|
|
184
|
+
/** The Build Id might be used by open workflows. */
|
|
185
|
+
OPEN_WORKFLOWS: 'OPEN_WORKFLOWS',
|
|
186
|
+
|
|
187
|
+
/** The Build Id might be used by closed workflows. */
|
|
188
|
+
CLOSED_WORKFLOWS: 'CLOSED_WORKFLOWS',
|
|
189
|
+
} as const;
|
|
190
|
+
|
|
176
191
|
/**
|
|
177
192
|
* There are different types of reachability:
|
|
178
193
|
* - `NEW_WORKFLOWS`: The Build Id might be used by new workflows
|
|
@@ -180,7 +195,24 @@ export type ReachabilityOptions = RequireAtLeastOne<BaseReachabilityOptions, 'bu
|
|
|
180
195
|
* - `OPEN_WORKFLOWS` The Build Id might be used by open workflows
|
|
181
196
|
* - `CLOSED_WORKFLOWS` The Build Id might be used by closed workflows
|
|
182
197
|
*/
|
|
183
|
-
export type ReachabilityType =
|
|
198
|
+
export type ReachabilityType = (typeof ReachabilityType)[keyof typeof ReachabilityType];
|
|
199
|
+
|
|
200
|
+
export const [encodeTaskReachability, decodeTaskReachability] = makeProtoEnumConverters<
|
|
201
|
+
temporal.api.enums.v1.TaskReachability,
|
|
202
|
+
typeof temporal.api.enums.v1.TaskReachability,
|
|
203
|
+
keyof typeof temporal.api.enums.v1.TaskReachability,
|
|
204
|
+
typeof ReachabilityType,
|
|
205
|
+
'TASK_REACHABILITY_'
|
|
206
|
+
>(
|
|
207
|
+
{
|
|
208
|
+
[ReachabilityType.NEW_WORKFLOWS]: 1,
|
|
209
|
+
[ReachabilityType.EXISTING_WORKFLOWS]: 2,
|
|
210
|
+
[ReachabilityType.OPEN_WORKFLOWS]: 3,
|
|
211
|
+
[ReachabilityType.CLOSED_WORKFLOWS]: 4,
|
|
212
|
+
UNSPECIFIED: 0,
|
|
213
|
+
} as const,
|
|
214
|
+
'TASK_REACHABILITY_'
|
|
215
|
+
);
|
|
184
216
|
|
|
185
217
|
/**
|
|
186
218
|
* See {@link ReachabilityOptions}
|
|
@@ -215,24 +247,6 @@ export interface BuildIdReachability {
|
|
|
215
247
|
taskQueueReachability: Record<string, ReachabilityTypeResponse[]>;
|
|
216
248
|
}
|
|
217
249
|
|
|
218
|
-
function reachabilityTypeToProto(type: ReachabilityType | undefined | null): temporal.api.enums.v1.TaskReachability {
|
|
219
|
-
switch (type) {
|
|
220
|
-
case null:
|
|
221
|
-
case undefined:
|
|
222
|
-
return temporal.api.enums.v1.TaskReachability.TASK_REACHABILITY_UNSPECIFIED;
|
|
223
|
-
case 'NEW_WORKFLOWS':
|
|
224
|
-
return temporal.api.enums.v1.TaskReachability.TASK_REACHABILITY_NEW_WORKFLOWS;
|
|
225
|
-
case 'EXISTING_WORKFLOWS':
|
|
226
|
-
return temporal.api.enums.v1.TaskReachability.TASK_REACHABILITY_EXISTING_WORKFLOWS;
|
|
227
|
-
case 'OPEN_WORKFLOWS':
|
|
228
|
-
return temporal.api.enums.v1.TaskReachability.TASK_REACHABILITY_OPEN_WORKFLOWS;
|
|
229
|
-
case 'CLOSED_WORKFLOWS':
|
|
230
|
-
return temporal.api.enums.v1.TaskReachability.TASK_REACHABILITY_CLOSED_WORKFLOWS;
|
|
231
|
-
default:
|
|
232
|
-
assertNever('Unknown Build Id reachability operation', type);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
250
|
export function reachabilityResponseFromProto(resp: GetWorkerTaskReachabilityResponse): ReachabilityResponse {
|
|
237
251
|
return {
|
|
238
252
|
buildIdReachability: Object.fromEntries(
|
|
@@ -247,7 +261,9 @@ export function reachabilityResponseFromProto(resp: GetWorkerTaskReachabilityRes
|
|
|
247
261
|
taskQueueReachability[tqr.taskQueue] = [];
|
|
248
262
|
continue;
|
|
249
263
|
}
|
|
250
|
-
taskQueueReachability[tqr.taskQueue] = tqr.reachability.map(
|
|
264
|
+
taskQueueReachability[tqr.taskQueue] = tqr.reachability.map(
|
|
265
|
+
(x) => decodeTaskReachability(x) ?? 'NOT_FETCHED'
|
|
266
|
+
);
|
|
251
267
|
}
|
|
252
268
|
}
|
|
253
269
|
let bid: string | UnversionedBuildIdType;
|
|
@@ -262,23 +278,6 @@ export function reachabilityResponseFromProto(resp: GetWorkerTaskReachabilityRes
|
|
|
262
278
|
};
|
|
263
279
|
}
|
|
264
280
|
|
|
265
|
-
function reachabilityTypeFromProto(rtype: temporal.api.enums.v1.TaskReachability): ReachabilityTypeResponse {
|
|
266
|
-
switch (rtype) {
|
|
267
|
-
case temporal.api.enums.v1.TaskReachability.TASK_REACHABILITY_UNSPECIFIED:
|
|
268
|
-
return 'NOT_FETCHED';
|
|
269
|
-
case temporal.api.enums.v1.TaskReachability.TASK_REACHABILITY_NEW_WORKFLOWS:
|
|
270
|
-
return 'NEW_WORKFLOWS';
|
|
271
|
-
case temporal.api.enums.v1.TaskReachability.TASK_REACHABILITY_EXISTING_WORKFLOWS:
|
|
272
|
-
return 'EXISTING_WORKFLOWS';
|
|
273
|
-
case temporal.api.enums.v1.TaskReachability.TASK_REACHABILITY_OPEN_WORKFLOWS:
|
|
274
|
-
return 'OPEN_WORKFLOWS';
|
|
275
|
-
case temporal.api.enums.v1.TaskReachability.TASK_REACHABILITY_CLOSED_WORKFLOWS:
|
|
276
|
-
return 'CLOSED_WORKFLOWS';
|
|
277
|
-
default:
|
|
278
|
-
return assertNever('Unknown Build Id reachability operation', rtype);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
|
|
282
281
|
/**
|
|
283
282
|
* Thrown when one or more Build Ids are not found while using the {@link TaskQueueClient}.
|
|
284
283
|
*
|
package/src/types.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type * as grpc from '@grpc/grpc-js';
|
|
2
2
|
import type { SearchAttributes } from '@temporalio/common';
|
|
3
|
+
import { makeProtoEnumConverters } from '@temporalio/common/lib/internal-workflow';
|
|
3
4
|
import * as proto from '@temporalio/proto';
|
|
4
5
|
import { Replace } from '@temporalio/common/lib/type-helpers';
|
|
5
6
|
|
|
@@ -102,7 +103,7 @@ export interface ConnectionLike {
|
|
|
102
103
|
*
|
|
103
104
|
* The deadline is a point in time after which any pending gRPC request will be considered as failed;
|
|
104
105
|
* this will locally result in the request call throwing a {@link grpc.ServiceError|ServiceError}
|
|
105
|
-
* with code {@link grpc.status.DEADLINE_EXCEEDED|DEADLINE_EXCEEDED}.
|
|
106
|
+
* with code {@link grpc.status.DEADLINE_EXCEEDED|DEADLINE_EXCEEDED}; see {@link isGrpcDeadlineError}.
|
|
106
107
|
*
|
|
107
108
|
* It is stronly recommended to explicitly set deadlines. If no deadline is set, then it is
|
|
108
109
|
* possible for the client to end up waiting forever for a response.
|
|
@@ -127,7 +128,7 @@ export interface ConnectionLike {
|
|
|
127
128
|
/**
|
|
128
129
|
* Set an {@link AbortSignal} that, when aborted, cancels any ongoing service requests executed in
|
|
129
130
|
* `fn`'s scope. This will locally result in the request call throwing a {@link grpc.ServiceError|ServiceError}
|
|
130
|
-
* with code {@link grpc.status.CANCELLED|CANCELLED}.
|
|
131
|
+
* with code {@link grpc.status.CANCELLED|CANCELLED}; see {@link isGrpcCancelledError}.
|
|
131
132
|
*
|
|
132
133
|
* @returns value returned from `fn`
|
|
133
134
|
*
|
|
@@ -135,3 +136,38 @@ export interface ConnectionLike {
|
|
|
135
136
|
*/
|
|
136
137
|
withAbortSignal<R>(abortSignal: AbortSignal, fn: () => Promise<R>): Promise<R>;
|
|
137
138
|
}
|
|
139
|
+
|
|
140
|
+
export const QueryRejectCondition = {
|
|
141
|
+
NONE: 'NONE',
|
|
142
|
+
NOT_OPEN: 'NOT_OPEN',
|
|
143
|
+
NOT_COMPLETED_CLEANLY: 'NOT_COMPLETED_CLEANLY',
|
|
144
|
+
|
|
145
|
+
/** @deprecated Use {@link NONE} instead. */
|
|
146
|
+
QUERY_REJECT_CONDITION_NONE: 'NONE', // eslint-disable-line deprecation/deprecation
|
|
147
|
+
|
|
148
|
+
/** @deprecated Use {@link NOT_OPEN} instead. */
|
|
149
|
+
QUERY_REJECT_CONDITION_NOT_OPEN: 'NOT_OPEN', // eslint-disable-line deprecation/deprecation
|
|
150
|
+
|
|
151
|
+
/** @deprecated Use {@link NOT_COMPLETED_CLEANLY} instead. */
|
|
152
|
+
QUERY_REJECT_CONDITION_NOT_COMPLETED_CLEANLY: 'NOT_COMPLETED_CLEANLY', // eslint-disable-line deprecation/deprecation
|
|
153
|
+
|
|
154
|
+
/** @deprecated Use `undefined` instead. */
|
|
155
|
+
QUERY_REJECT_CONDITION_UNSPECIFIED: undefined, // eslint-disable-line deprecation/deprecation
|
|
156
|
+
} as const;
|
|
157
|
+
export type QueryRejectCondition = (typeof QueryRejectCondition)[keyof typeof QueryRejectCondition];
|
|
158
|
+
|
|
159
|
+
export const [encodeQueryRejectCondition, decodeQueryRejectCondition] = makeProtoEnumConverters<
|
|
160
|
+
proto.temporal.api.enums.v1.QueryRejectCondition,
|
|
161
|
+
typeof proto.temporal.api.enums.v1.QueryRejectCondition,
|
|
162
|
+
keyof typeof proto.temporal.api.enums.v1.QueryRejectCondition,
|
|
163
|
+
typeof QueryRejectCondition,
|
|
164
|
+
'QUERY_REJECT_CONDITION_'
|
|
165
|
+
>(
|
|
166
|
+
{
|
|
167
|
+
[QueryRejectCondition.NONE]: 1,
|
|
168
|
+
[QueryRejectCondition.NOT_OPEN]: 2,
|
|
169
|
+
[QueryRejectCondition.NOT_COMPLETED_CLEANLY]: 3,
|
|
170
|
+
UNSPECIFIED: 0,
|
|
171
|
+
} as const,
|
|
172
|
+
'QUERY_REJECT_CONDITION_'
|
|
173
|
+
);
|
package/src/workflow-client.ts
CHANGED
|
@@ -20,6 +20,9 @@ import {
|
|
|
20
20
|
WorkflowNotFoundError,
|
|
21
21
|
WorkflowResultType,
|
|
22
22
|
extractWorkflowType,
|
|
23
|
+
encodeWorkflowIdReusePolicy,
|
|
24
|
+
decodeRetryState,
|
|
25
|
+
encodeWorkflowIdConflictPolicy,
|
|
23
26
|
} from '@temporalio/common';
|
|
24
27
|
import { composeInterceptors } from '@temporalio/common/lib/interceptors';
|
|
25
28
|
import { History } from '@temporalio/common/lib/proto-utils';
|
|
@@ -56,7 +59,9 @@ import {
|
|
|
56
59
|
} from './interceptors';
|
|
57
60
|
import {
|
|
58
61
|
DescribeWorkflowExecutionResponse,
|
|
62
|
+
encodeQueryRejectCondition,
|
|
59
63
|
GetWorkflowExecutionHistoryRequest,
|
|
64
|
+
QueryRejectCondition,
|
|
60
65
|
RequestCancelWorkflowExecutionResponse,
|
|
61
66
|
StartWorkflowExecutionRequest,
|
|
62
67
|
TerminateWorkflowExecutionResponse,
|
|
@@ -81,8 +86,9 @@ import {
|
|
|
81
86
|
WithDefaults,
|
|
82
87
|
} from './base-client';
|
|
83
88
|
import { mapAsyncIterable } from './iterators-utils';
|
|
84
|
-
import { WorkflowUpdateStage } from './workflow-update-stage';
|
|
85
|
-
|
|
89
|
+
import { WorkflowUpdateStage, encodeWorkflowUpdateStage } from './workflow-update-stage';
|
|
90
|
+
|
|
91
|
+
const UpdateWorkflowExecutionLifecycleStage = temporal.api.enums.v1.UpdateWorkflowExecutionLifecycleStage;
|
|
86
92
|
|
|
87
93
|
/**
|
|
88
94
|
* A client side handle to a single Workflow instance.
|
|
@@ -168,7 +174,7 @@ export interface WorkflowHandle<T extends Workflow = Workflow> extends BaseWorkf
|
|
|
168
174
|
* ```ts
|
|
169
175
|
* const updateHandle = await handle.startUpdate(incrementAndGetValueUpdate, {
|
|
170
176
|
* args: [2],
|
|
171
|
-
* waitForStage:
|
|
177
|
+
* waitForStage: 'ACCEPTED',
|
|
172
178
|
* });
|
|
173
179
|
* const updateResult = await updateHandle.result();
|
|
174
180
|
* ```
|
|
@@ -177,7 +183,7 @@ export interface WorkflowHandle<T extends Workflow = Workflow> extends BaseWorkf
|
|
|
177
183
|
def: UpdateDefinition<Ret, Args, Name> | string,
|
|
178
184
|
options: WorkflowUpdateOptions & {
|
|
179
185
|
args: Args;
|
|
180
|
-
waitForStage:
|
|
186
|
+
waitForStage: 'ACCEPTED';
|
|
181
187
|
}
|
|
182
188
|
): Promise<WorkflowUpdateHandle<Ret>>;
|
|
183
189
|
|
|
@@ -185,7 +191,7 @@ export interface WorkflowHandle<T extends Workflow = Workflow> extends BaseWorkf
|
|
|
185
191
|
def: UpdateDefinition<Ret, Args, Name> | string,
|
|
186
192
|
options: WorkflowUpdateOptions & {
|
|
187
193
|
args?: Args;
|
|
188
|
-
waitForStage: WorkflowUpdateStage.ACCEPTED;
|
|
194
|
+
waitForStage: typeof WorkflowUpdateStage.ACCEPTED;
|
|
189
195
|
}
|
|
190
196
|
): Promise<WorkflowUpdateHandle<Ret>>;
|
|
191
197
|
|
|
@@ -280,9 +286,9 @@ export interface WorkflowClientOptions extends BaseClientOptions {
|
|
|
280
286
|
/**
|
|
281
287
|
* Should a query be rejected by closed and failed workflows
|
|
282
288
|
*
|
|
283
|
-
* @default
|
|
289
|
+
* @default `undefined` which means that closed and failed workflows are still queryable
|
|
284
290
|
*/
|
|
285
|
-
queryRejectCondition?:
|
|
291
|
+
queryRejectCondition?: QueryRejectCondition;
|
|
286
292
|
}
|
|
287
293
|
|
|
288
294
|
export type LoadedWorkflowClientOptions = LoadedWithDefaults<WorkflowClientOptions>;
|
|
@@ -291,7 +297,7 @@ function defaultWorkflowClientOptions(): WithDefaults<WorkflowClientOptions> {
|
|
|
291
297
|
return {
|
|
292
298
|
...defaultBaseClientOptions(),
|
|
293
299
|
interceptors: [],
|
|
294
|
-
queryRejectCondition:
|
|
300
|
+
queryRejectCondition: 'NONE',
|
|
295
301
|
};
|
|
296
302
|
}
|
|
297
303
|
|
|
@@ -659,7 +665,7 @@ export class WorkflowClient extends BaseClient {
|
|
|
659
665
|
throw new WorkflowFailedError(
|
|
660
666
|
'Workflow execution failed',
|
|
661
667
|
await decodeOptionalFailureToOptionalError(this.dataConverter, failure),
|
|
662
|
-
retryState
|
|
668
|
+
decodeRetryState(retryState)
|
|
663
669
|
);
|
|
664
670
|
} else if (ev.workflowExecutionCanceledEventAttributes) {
|
|
665
671
|
const failure = new CancelledFailure(
|
|
@@ -670,11 +676,7 @@ export class WorkflowClient extends BaseClient {
|
|
|
670
676
|
)
|
|
671
677
|
);
|
|
672
678
|
failure.stack = '';
|
|
673
|
-
throw new WorkflowFailedError(
|
|
674
|
-
'Workflow execution cancelled',
|
|
675
|
-
failure,
|
|
676
|
-
RetryState.RETRY_STATE_NON_RETRYABLE_FAILURE
|
|
677
|
-
);
|
|
679
|
+
throw new WorkflowFailedError('Workflow execution cancelled', failure, RetryState.NON_RETRYABLE_FAILURE);
|
|
678
680
|
} else if (ev.workflowExecutionTerminatedEventAttributes) {
|
|
679
681
|
const failure = new TerminatedFailure(
|
|
680
682
|
ev.workflowExecutionTerminatedEventAttributes.reason || 'Workflow execution terminated'
|
|
@@ -683,7 +685,7 @@ export class WorkflowClient extends BaseClient {
|
|
|
683
685
|
throw new WorkflowFailedError(
|
|
684
686
|
ev.workflowExecutionTerminatedEventAttributes.reason || 'Workflow execution terminated',
|
|
685
687
|
failure,
|
|
686
|
-
RetryState.
|
|
688
|
+
RetryState.NON_RETRYABLE_FAILURE
|
|
687
689
|
);
|
|
688
690
|
} else if (ev.workflowExecutionTimedOutEventAttributes) {
|
|
689
691
|
if (followRuns && ev.workflowExecutionTimedOutEventAttributes.newExecutionRunId) {
|
|
@@ -691,16 +693,12 @@ export class WorkflowClient extends BaseClient {
|
|
|
691
693
|
req.nextPageToken = undefined;
|
|
692
694
|
continue;
|
|
693
695
|
}
|
|
694
|
-
const failure = new TimeoutFailure(
|
|
695
|
-
'Workflow execution timed out',
|
|
696
|
-
undefined,
|
|
697
|
-
TimeoutType.TIMEOUT_TYPE_START_TO_CLOSE
|
|
698
|
-
);
|
|
696
|
+
const failure = new TimeoutFailure('Workflow execution timed out', undefined, TimeoutType.START_TO_CLOSE);
|
|
699
697
|
failure.stack = '';
|
|
700
698
|
throw new WorkflowFailedError(
|
|
701
699
|
'Workflow execution timed out',
|
|
702
700
|
failure,
|
|
703
|
-
ev.workflowExecutionTimedOutEventAttributes.retryState
|
|
701
|
+
decodeRetryState(ev.workflowExecutionTimedOutEventAttributes.retryState)
|
|
704
702
|
);
|
|
705
703
|
} else if (ev.workflowExecutionContinuedAsNewEventAttributes) {
|
|
706
704
|
const { newExecutionRunId } = ev.workflowExecutionContinuedAsNewEventAttributes;
|
|
@@ -806,8 +804,15 @@ export class WorkflowClient extends BaseClient {
|
|
|
806
804
|
waitForStage: WorkflowUpdateStage,
|
|
807
805
|
input: WorkflowStartUpdateInput
|
|
808
806
|
): Promise<WorkflowStartUpdateOutput> {
|
|
809
|
-
|
|
810
|
-
|
|
807
|
+
let waitForStageProto: temporal.api.enums.v1.UpdateWorkflowExecutionLifecycleStage =
|
|
808
|
+
encodeWorkflowUpdateStage(waitForStage) ??
|
|
809
|
+
UpdateWorkflowExecutionLifecycleStage.UPDATE_WORKFLOW_EXECUTION_LIFECYCLE_STAGE_ACCEPTED;
|
|
810
|
+
|
|
811
|
+
waitForStageProto =
|
|
812
|
+
waitForStageProto >= UpdateWorkflowExecutionLifecycleStage.UPDATE_WORKFLOW_EXECUTION_LIFECYCLE_STAGE_ACCEPTED
|
|
813
|
+
? waitForStageProto
|
|
814
|
+
: UpdateWorkflowExecutionLifecycleStage.UPDATE_WORKFLOW_EXECUTION_LIFECYCLE_STAGE_ACCEPTED;
|
|
815
|
+
|
|
811
816
|
const updateId = input.options?.updateId ?? uuid4();
|
|
812
817
|
const req: temporal.api.workflowservice.v1.IUpdateWorkflowExecutionRequest = {
|
|
813
818
|
namespace: this.options.namespace,
|
|
@@ -886,7 +891,7 @@ export class WorkflowClient extends BaseClient {
|
|
|
886
891
|
updateRef: { workflowExecution, updateId },
|
|
887
892
|
identity: this.options.identity,
|
|
888
893
|
waitPolicy: {
|
|
889
|
-
lifecycleStage:
|
|
894
|
+
lifecycleStage: encodeWorkflowUpdateStage(WorkflowUpdateStage.COMPLETED),
|
|
890
895
|
},
|
|
891
896
|
};
|
|
892
897
|
for (;;) {
|
|
@@ -938,7 +943,8 @@ export class WorkflowClient extends BaseClient {
|
|
|
938
943
|
identity,
|
|
939
944
|
requestId: uuid4(),
|
|
940
945
|
workflowId: options.workflowId,
|
|
941
|
-
workflowIdReusePolicy: options.workflowIdReusePolicy,
|
|
946
|
+
workflowIdReusePolicy: encodeWorkflowIdReusePolicy(options.workflowIdReusePolicy),
|
|
947
|
+
workflowIdConflictPolicy: encodeWorkflowIdConflictPolicy(options.workflowIdConflictPolicy),
|
|
942
948
|
workflowType: { name: workflowType },
|
|
943
949
|
input: { payloads: await encodeToPayloads(this.dataConverter, ...options.args) },
|
|
944
950
|
signalName,
|
|
@@ -988,7 +994,8 @@ export class WorkflowClient extends BaseClient {
|
|
|
988
994
|
identity,
|
|
989
995
|
requestId: uuid4(),
|
|
990
996
|
workflowId: opts.workflowId,
|
|
991
|
-
workflowIdReusePolicy: opts.workflowIdReusePolicy,
|
|
997
|
+
workflowIdReusePolicy: encodeWorkflowIdReusePolicy(opts.workflowIdReusePolicy),
|
|
998
|
+
workflowIdConflictPolicy: encodeWorkflowIdConflictPolicy(opts.workflowIdConflictPolicy),
|
|
992
999
|
workflowType: { name: workflowType },
|
|
993
1000
|
input: { payloads: await encodeToPayloads(this.dataConverter, ...opts.args) },
|
|
994
1001
|
taskQueue: {
|
|
@@ -1178,7 +1185,7 @@ export class WorkflowClient extends BaseClient {
|
|
|
1178
1185
|
def: UpdateDefinition<Ret, Args> | string,
|
|
1179
1186
|
options: WorkflowUpdateOptions & {
|
|
1180
1187
|
args?: Args;
|
|
1181
|
-
waitForStage: WorkflowUpdateStage.ACCEPTED;
|
|
1188
|
+
waitForStage: typeof WorkflowUpdateStage.ACCEPTED;
|
|
1182
1189
|
}
|
|
1183
1190
|
): Promise<WorkflowUpdateHandle<Ret>> {
|
|
1184
1191
|
return await _startUpdate(def, options.waitForStage, options);
|
|
@@ -1208,7 +1215,7 @@ export class WorkflowClient extends BaseClient {
|
|
|
1208
1215
|
const fn = composeInterceptors(interceptors, 'query', next);
|
|
1209
1216
|
return fn({
|
|
1210
1217
|
workflowExecution: { workflowId, runId },
|
|
1211
|
-
queryRejectCondition: this.client.options.queryRejectCondition,
|
|
1218
|
+
queryRejectCondition: encodeQueryRejectCondition(this.client.options.queryRejectCondition),
|
|
1212
1219
|
queryType: typeof def === 'string' ? def : def.name,
|
|
1213
1220
|
args,
|
|
1214
1221
|
headers: {},
|
package/src/workflow-options.ts
CHANGED
|
@@ -15,7 +15,8 @@ export interface WorkflowOptions extends CommonWorkflowOptions {
|
|
|
15
15
|
*
|
|
16
16
|
* Assign a meaningful business id.
|
|
17
17
|
* This ID can be used to ensure starting Workflows is idempotent.
|
|
18
|
-
* Workflow IDs are unique
|
|
18
|
+
* Workflow IDs are unique: see {@link WorkflowOptions.workflowIdReusePolicy}
|
|
19
|
+
* and {@link WorkflowOptions.workflowIdConflictPolicy}.
|
|
19
20
|
*/
|
|
20
21
|
workflowId: string;
|
|
21
22
|
|