@temporalio/client 1.11.2 → 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 +30 -7
- package/lib/base-client.js +26 -8
- 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 +26 -9
- package/lib/connection.js +35 -12
- 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.d.ts +4 -0
- package/lib/schedule-client.js +8 -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 +36 -4
- 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 +32 -6
- package/src/client.ts +4 -4
- package/src/connection.ts +42 -10
- package/src/errors.ts +34 -1
- package/src/schedule-client.ts +12 -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 +58 -3
- package/src/workflow-client.ts +36 -29
- package/src/workflow-options.ts +2 -1
- package/src/workflow-update-stage.ts +29 -21
|
@@ -1,28 +1,29 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
var WorkflowUpdateStage;
|
|
7
|
-
(function (WorkflowUpdateStage) {
|
|
8
|
-
/** This is not an allowed value. */
|
|
9
|
-
WorkflowUpdateStage[WorkflowUpdateStage["UNSPECIFIED"] = 0] = "UNSPECIFIED";
|
|
3
|
+
exports.encodeWorkflowUpdateStage = exports.WorkflowUpdateStage = void 0;
|
|
4
|
+
const internal_workflow_1 = require("@temporalio/common/lib/internal-workflow");
|
|
5
|
+
exports.WorkflowUpdateStage = {
|
|
10
6
|
/** Admitted stage. This stage is reached when the server accepts the update request. It is not
|
|
11
7
|
* allowed to wait for this stage when using startUpdate, since the update request has not yet
|
|
12
8
|
* been durably persisted at this stage. */
|
|
13
|
-
|
|
9
|
+
ADMITTED: 'ADMITTED',
|
|
14
10
|
/** Accepted stage. This stage is reached when a workflow has received the update and either
|
|
15
11
|
* accepted it (i.e. it has passed validation, or there was no validator configured on the update
|
|
16
12
|
* handler) or rejected it. This is currently the only allowed value when using startUpdate. */
|
|
17
|
-
|
|
13
|
+
ACCEPTED: 'ACCEPTED',
|
|
18
14
|
/** Completed stage. This stage is reached when a workflow has completed processing the
|
|
19
15
|
* update with either a success or failure. */
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
exports.
|
|
16
|
+
COMPLETED: 'COMPLETED',
|
|
17
|
+
/**
|
|
18
|
+
* This is not an allowed value.
|
|
19
|
+
* @deprecated
|
|
20
|
+
*/
|
|
21
|
+
UNSPECIFIED: undefined, // eslint-disable-line deprecation/deprecation
|
|
22
|
+
};
|
|
23
|
+
exports.encodeWorkflowUpdateStage = (0, internal_workflow_1.makeProtoEnumConverters)({
|
|
24
|
+
[exports.WorkflowUpdateStage.ADMITTED]: 1,
|
|
25
|
+
[exports.WorkflowUpdateStage.ACCEPTED]: 2,
|
|
26
|
+
[exports.WorkflowUpdateStage.COMPLETED]: 3,
|
|
27
|
+
UNSPECIFIED: 0,
|
|
28
|
+
}, 'UPDATE_WORKFLOW_EXECUTION_LIFECYCLE_STAGE_')[0];
|
|
28
29
|
//# sourceMappingURL=workflow-update-stage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-update-stage.js","sourceRoot":"","sources":["../src/workflow-update-stage.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"workflow-update-stage.js","sourceRoot":"","sources":["../src/workflow-update-stage.ts"],"names":[],"mappings":";;;AACA,gFAAmF;AAEtE,QAAA,mBAAmB,GAAG;IACjC;;+CAE2C;IAC3C,QAAQ,EAAE,UAAU;IAEpB;;mGAE+F;IAC/F,QAAQ,EAAE,UAAU;IAEpB;kDAC8C;IAC9C,SAAS,EAAE,WAAW;IAEtB;;;OAGG;IACH,WAAW,EAAE,SAAS,EAAE,8CAA8C;CAC9D,CAAC;AAGG,iCAAyB,GAAI,IAAA,2CAAuB,EAOhE;IACE,CAAC,2BAAmB,CAAC,QAAQ,CAAC,EAAE,CAAC;IACjC,CAAC,2BAAmB,CAAC,QAAQ,CAAC,EAAE,CAAC;IACjC,CAAC,2BAAmB,CAAC,SAAS,CAAC,EAAE,CAAC;IAClC,WAAW,EAAE,CAAC;CACN,EACV,4CAA4C,CAC7C,IAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@temporalio/client",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.4",
|
|
4
4
|
"description": "Temporal.io SDK Client sub-package",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "./lib/index.d.ts",
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@grpc/grpc-js": "^1.10.7",
|
|
17
|
-
"@temporalio/common": "1.11.
|
|
18
|
-
"@temporalio/proto": "1.11.
|
|
17
|
+
"@temporalio/common": "^1.11.4",
|
|
18
|
+
"@temporalio/proto": "^1.11.4",
|
|
19
19
|
"abort-controller": "^3.0.0",
|
|
20
20
|
"long": "^5.2.3",
|
|
21
21
|
"uuid": "^9.0.1"
|
|
@@ -39,5 +39,5 @@
|
|
|
39
39
|
"src",
|
|
40
40
|
"lib"
|
|
41
41
|
],
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "6a7e2d527c9f7078ee78abd9d59ca0d318bb70dd"
|
|
43
43
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { status as grpcStatus } from '@grpc/grpc-js';
|
|
2
2
|
import { ensureTemporalFailure } from '@temporalio/common';
|
|
3
|
-
import type { temporal } from '@temporalio/proto';
|
|
4
3
|
import {
|
|
5
4
|
encodeErrorToFailure,
|
|
6
5
|
encodeToPayloads,
|
|
@@ -216,23 +215,23 @@ export class AsyncCompletionClient extends BaseClient {
|
|
|
216
215
|
const payloads = await encodeToPayloads(this.dataConverter, details);
|
|
217
216
|
let cancelRequested = false;
|
|
218
217
|
try {
|
|
219
|
-
let response: temporal.api.workflowservice.v1.RecordActivityTaskHeartbeatResponse;
|
|
220
218
|
if (taskTokenOrFullActivityId instanceof Uint8Array) {
|
|
221
|
-
response = await this.workflowService.recordActivityTaskHeartbeat({
|
|
219
|
+
const response = await this.workflowService.recordActivityTaskHeartbeat({
|
|
222
220
|
identity: this.options.identity,
|
|
223
221
|
namespace: this.options.namespace,
|
|
224
222
|
taskToken: taskTokenOrFullActivityId,
|
|
225
223
|
details: { payloads },
|
|
226
224
|
});
|
|
225
|
+
cancelRequested = !!response.cancelRequested;
|
|
227
226
|
} else {
|
|
228
|
-
response = await this.workflowService.recordActivityTaskHeartbeatById({
|
|
227
|
+
const response = await this.workflowService.recordActivityTaskHeartbeatById({
|
|
229
228
|
identity: this.options.identity,
|
|
230
229
|
namespace: this.options.namespace,
|
|
231
230
|
...taskTokenOrFullActivityId,
|
|
232
231
|
details: { payloads },
|
|
233
232
|
});
|
|
233
|
+
cancelRequested = !!response.cancelRequested;
|
|
234
234
|
}
|
|
235
|
-
cancelRequested = !!response.cancelRequested;
|
|
236
235
|
} catch (err) {
|
|
237
236
|
this.handleError(err);
|
|
238
237
|
}
|
package/src/base-client.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import os from 'node:os';
|
|
2
|
+
import type * as _grpc from '@grpc/grpc-js'; // For JSDoc only
|
|
2
3
|
import { DataConverter, LoadedDataConverter } from '@temporalio/common';
|
|
3
4
|
import { isLoadedDataConverter, loadDataConverter } from '@temporalio/common/lib/internal-non-workflow';
|
|
4
5
|
import { Connection } from './connection';
|
|
@@ -51,7 +52,14 @@ export function defaultBaseClientOptions(): WithDefaults<BaseClientOptions> {
|
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
export class BaseClient {
|
|
55
|
+
/**
|
|
56
|
+
* The underlying {@link Connection | connection} used by this client.
|
|
57
|
+
*
|
|
58
|
+
* Clients are cheap to create, but connections are expensive. Where that make sense,
|
|
59
|
+
* a single connection may and should be reused by multiple `Client`.
|
|
60
|
+
*/
|
|
54
61
|
public readonly connection: ConnectionLike;
|
|
62
|
+
|
|
55
63
|
private readonly loadedDataConverter: LoadedDataConverter;
|
|
56
64
|
|
|
57
65
|
protected constructor(options?: BaseClientOptions) {
|
|
@@ -61,19 +69,37 @@ export class BaseClient {
|
|
|
61
69
|
}
|
|
62
70
|
|
|
63
71
|
/**
|
|
64
|
-
* Set
|
|
72
|
+
* Set a deadline for any service requests executed in `fn`'s scope.
|
|
73
|
+
*
|
|
74
|
+
* The deadline is a point in time after which any pending gRPC request will be considered as failed;
|
|
75
|
+
* this will locally result in the request call throwing a {@link _grpc.ServiceError|ServiceError}
|
|
76
|
+
* with code {@link _grpc.status.DEADLINE_EXCEEDED|DEADLINE_EXCEEDED}; see {@link isGrpcDeadlineError}.
|
|
77
|
+
*
|
|
78
|
+
* It is stronly recommended to explicitly set deadlines. If no deadline is set, then it is
|
|
79
|
+
* possible for the client to end up waiting forever for a response.
|
|
80
|
+
*
|
|
81
|
+
* This method is only a convenience wrapper around {@link Connection.withDeadline}.
|
|
82
|
+
*
|
|
83
|
+
* @param deadline a point in time after which the request will be considered as failed; either a
|
|
84
|
+
* Date object, or a number of milliseconds since the Unix epoch (UTC).
|
|
85
|
+
* @returns the value returned from `fn`
|
|
86
|
+
*
|
|
87
|
+
* @see https://grpc.io/docs/guides/deadlines/
|
|
65
88
|
*/
|
|
66
89
|
public async withDeadline<R>(deadline: number | Date, fn: () => Promise<R>): Promise<R> {
|
|
67
90
|
return await this.connection.withDeadline(deadline, fn);
|
|
68
91
|
}
|
|
69
92
|
|
|
70
93
|
/**
|
|
71
|
-
* Set an {@link
|
|
72
|
-
*
|
|
94
|
+
* Set an {@link AbortSignal} that, when aborted, cancels any ongoing service requests executed in
|
|
95
|
+
* `fn`'s scope. This will locally result in the request call throwing a {@link _grpc.ServiceError|ServiceError}
|
|
96
|
+
* with code {@link _grpc.status.CANCELLED|CANCELLED}; see {@link isGrpcCancelledError}.
|
|
97
|
+
*
|
|
98
|
+
* This method is only a convenience wrapper around {@link Connection.withAbortSignal}.
|
|
73
99
|
*
|
|
74
100
|
* @returns value returned from `fn`
|
|
75
101
|
*
|
|
76
|
-
* @see
|
|
102
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal
|
|
77
103
|
*/
|
|
78
104
|
async withAbortSignal<R>(abortSignal: AbortSignal, fn: () => Promise<R>): Promise<R> {
|
|
79
105
|
return await this.connection.withAbortSignal(abortSignal, fn);
|
|
@@ -82,9 +108,9 @@ export class BaseClient {
|
|
|
82
108
|
/**
|
|
83
109
|
* Set metadata for any service requests executed in `fn`'s scope.
|
|
84
110
|
*
|
|
85
|
-
*
|
|
111
|
+
* This method is only a convenience wrapper around {@link Connection.withMetadata}.
|
|
86
112
|
*
|
|
87
|
-
* @
|
|
113
|
+
* @returns returned value of `fn`
|
|
88
114
|
*/
|
|
89
115
|
public async withMetadata<R>(metadata: Metadata, fn: () => Promise<R>): Promise<R> {
|
|
90
116
|
return await this.connection.withMetadata(metadata, fn);
|
package/src/client.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { filterNullAndUndefined } from '@temporalio/common/lib/internal-non-workflow';
|
|
2
|
-
import { temporal } from '@temporalio/proto';
|
|
3
2
|
import { AsyncCompletionClient } from './async-completion-client';
|
|
4
3
|
import { BaseClient, BaseClientOptions, defaultBaseClientOptions, LoadedWithDefaults } from './base-client';
|
|
5
4
|
import { ClientInterceptors } from './interceptors';
|
|
6
5
|
import { ScheduleClient } from './schedule-client';
|
|
7
|
-
import { WorkflowService } from './types';
|
|
6
|
+
import { QueryRejectCondition, WorkflowService } from './types';
|
|
8
7
|
import { WorkflowClient } from './workflow-client';
|
|
9
8
|
import { TaskQueueClient } from './task-queue-client';
|
|
10
9
|
|
|
@@ -20,9 +19,9 @@ export interface ClientOptions extends BaseClientOptions {
|
|
|
20
19
|
/**
|
|
21
20
|
* Should a query be rejected by closed and failed workflows
|
|
22
21
|
*
|
|
23
|
-
* @default
|
|
22
|
+
* @default `undefined`, which means that closed and failed workflows are still queryable
|
|
24
23
|
*/
|
|
25
|
-
queryRejectCondition?:
|
|
24
|
+
queryRejectCondition?: QueryRejectCondition;
|
|
26
25
|
};
|
|
27
26
|
}
|
|
28
27
|
|
|
@@ -63,6 +62,7 @@ export class Client extends BaseClient {
|
|
|
63
62
|
connection: this.connection,
|
|
64
63
|
dataConverter: this.dataConverter,
|
|
65
64
|
interceptors: interceptors?.workflow,
|
|
65
|
+
queryRejectCondition: workflow?.queryRejectCondition,
|
|
66
66
|
});
|
|
67
67
|
|
|
68
68
|
this.activity = new AsyncCompletionClient({
|
package/src/connection.ts
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
filterNullAndUndefined,
|
|
6
6
|
normalizeTlsConfig,
|
|
7
7
|
TLSConfig,
|
|
8
|
-
|
|
8
|
+
normalizeGrpcEndpointAddress,
|
|
9
9
|
} from '@temporalio/common/lib/internal-non-workflow';
|
|
10
10
|
import { Duration, msOptionalToNumber } from '@temporalio/common/lib/time';
|
|
11
11
|
import { isGrpcServiceError, ServiceError } from './errors';
|
|
@@ -13,6 +13,11 @@ import { defaultGrpcRetryOptions, makeGrpcRetryInterceptor } from './grpc-retry'
|
|
|
13
13
|
import pkg from './pkg';
|
|
14
14
|
import { CallContext, HealthService, Metadata, OperatorService, WorkflowService } from './types';
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* The default Temporal Server's TCP port for public gRPC connections.
|
|
18
|
+
*/
|
|
19
|
+
const DEFAULT_TEMPORAL_GRPC_PORT = 7233;
|
|
20
|
+
|
|
16
21
|
/**
|
|
17
22
|
* gRPC and Temporal Server connection options
|
|
18
23
|
*/
|
|
@@ -174,7 +179,7 @@ function normalizeGRPCConfig(options?: ConnectionOptions): ConnectionOptions {
|
|
|
174
179
|
}
|
|
175
180
|
}
|
|
176
181
|
if (rest.address) {
|
|
177
|
-
rest.address =
|
|
182
|
+
rest.address = normalizeGrpcEndpointAddress(rest.address, DEFAULT_TEMPORAL_GRPC_PORT);
|
|
178
183
|
}
|
|
179
184
|
const tls = normalizeTlsConfig(tlsFromConfig);
|
|
180
185
|
if (tls) {
|
|
@@ -220,20 +225,24 @@ export interface RPCImplOptions {
|
|
|
220
225
|
export interface ConnectionCtorOptions {
|
|
221
226
|
readonly options: ConnectionOptionsWithDefaults;
|
|
222
227
|
readonly client: grpc.Client;
|
|
228
|
+
|
|
223
229
|
/**
|
|
224
230
|
* Raw gRPC access to the Temporal service.
|
|
225
231
|
*
|
|
226
232
|
* **NOTE**: The namespace provided in {@link options} is **not** automatically set on requests made to the service.
|
|
227
233
|
*/
|
|
228
234
|
readonly workflowService: WorkflowService;
|
|
235
|
+
|
|
229
236
|
/**
|
|
230
237
|
* Raw gRPC access to the Temporal {@link https://github.com/temporalio/api/blob/ddf07ab9933e8230309850e3c579e1ff34b03f53/temporal/api/operatorservice/v1/service.proto | operator service}.
|
|
231
238
|
*/
|
|
232
239
|
readonly operatorService: OperatorService;
|
|
240
|
+
|
|
233
241
|
/**
|
|
234
242
|
* Raw gRPC access to the standard gRPC {@link https://github.com/grpc/grpc/blob/92f58c18a8da2728f571138c37760a721c8915a2/doc/health-checking.md | health service}.
|
|
235
243
|
*/
|
|
236
244
|
readonly healthService: HealthService;
|
|
245
|
+
|
|
237
246
|
readonly callContextStorage: AsyncLocalStorage<CallContext>;
|
|
238
247
|
readonly apiKeyFnRef: { fn?: () => string };
|
|
239
248
|
}
|
|
@@ -241,8 +250,8 @@ export interface ConnectionCtorOptions {
|
|
|
241
250
|
/**
|
|
242
251
|
* Client connection to the Temporal Server
|
|
243
252
|
*
|
|
244
|
-
* ⚠️ Connections are expensive to construct and should be reused.
|
|
245
|
-
* avoid leaking resources.
|
|
253
|
+
* ⚠️ Connections are expensive to construct and should be reused.
|
|
254
|
+
* Make sure to {@link close} any unused connections to avoid leaking resources.
|
|
246
255
|
*/
|
|
247
256
|
export class Connection {
|
|
248
257
|
/**
|
|
@@ -275,7 +284,12 @@ export class Connection {
|
|
|
275
284
|
* Cloud namespace will result in gRPC `unauthorized` error.
|
|
276
285
|
*/
|
|
277
286
|
public readonly operatorService: OperatorService;
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Raw gRPC access to the standard gRPC {@link https://github.com/grpc/grpc/blob/92f58c18a8da2728f571138c37760a721c8915a2/doc/health-checking.md | health service}.
|
|
290
|
+
*/
|
|
278
291
|
public readonly healthService: HealthService;
|
|
292
|
+
|
|
279
293
|
readonly callContextStorage: AsyncLocalStorage<CallContext>;
|
|
280
294
|
private readonly apiKeyFnRef: { fn?: () => string };
|
|
281
295
|
|
|
@@ -424,7 +438,8 @@ export class Connection {
|
|
|
424
438
|
const metadataContainer = new grpc.Metadata();
|
|
425
439
|
const { metadata, deadline, abortSignal } = callContextStorage.getStore() ?? {};
|
|
426
440
|
if (apiKeyFnRef.fn) {
|
|
427
|
-
|
|
441
|
+
const apiKey = apiKeyFnRef.fn();
|
|
442
|
+
if (apiKey) metadataContainer.set('Authorization', `Bearer ${apiKey}`);
|
|
428
443
|
}
|
|
429
444
|
for (const [k, v] of Object.entries(staticMetadata)) {
|
|
430
445
|
metadataContainer.set(k, v);
|
|
@@ -452,9 +467,20 @@ export class Connection {
|
|
|
452
467
|
}
|
|
453
468
|
|
|
454
469
|
/**
|
|
455
|
-
* Set
|
|
470
|
+
* Set a deadline for any service requests executed in `fn`'s scope.
|
|
456
471
|
*
|
|
457
|
-
*
|
|
472
|
+
* The deadline is a point in time after which any pending gRPC request will be considered as failed;
|
|
473
|
+
* this will locally result in the request call throwing a {@link grpc.ServiceError|ServiceError}
|
|
474
|
+
* with code {@link grpc.status.DEADLINE_EXCEEDED|DEADLINE_EXCEEDED}; see {@link isGrpcDeadlineError}.
|
|
475
|
+
*
|
|
476
|
+
* It is stronly recommended to explicitly set deadlines. If no deadline is set, then it is
|
|
477
|
+
* possible for the client to end up waiting forever for a response.
|
|
478
|
+
*
|
|
479
|
+
* @param deadline a point in time after which the request will be considered as failed; either a
|
|
480
|
+
* Date object, or a number of milliseconds since the Unix epoch (UTC).
|
|
481
|
+
* @returns the value returned from `fn`
|
|
482
|
+
*
|
|
483
|
+
* @see https://grpc.io/docs/guides/deadlines/
|
|
458
484
|
*/
|
|
459
485
|
async withDeadline<ReturnType>(deadline: number | Date, fn: () => Promise<ReturnType>): Promise<ReturnType> {
|
|
460
486
|
const cc = this.callContextStorage.getStore();
|
|
@@ -462,10 +488,11 @@ export class Connection {
|
|
|
462
488
|
}
|
|
463
489
|
|
|
464
490
|
/**
|
|
465
|
-
* Set an {@link
|
|
466
|
-
*
|
|
491
|
+
* Set an {@link AbortSignal} that, when aborted, cancels any ongoing service requests executed in
|
|
492
|
+
* `fn`'s scope. This will locally result in the request call throwing a {@link grpc.ServiceError|ServiceError}
|
|
493
|
+
* with code {@link grpc.status.CANCELLED|CANCELLED}; see {@link isGrpcCancelledError}.
|
|
467
494
|
*
|
|
468
|
-
*
|
|
495
|
+
* This method is only a convenience wrapper around {@link Connection.withAbortSignal}.
|
|
469
496
|
*
|
|
470
497
|
* @example
|
|
471
498
|
*
|
|
@@ -475,6 +502,10 @@ export class Connection {
|
|
|
475
502
|
* // 👇 throws if incomplete by the timeout.
|
|
476
503
|
* await conn.withAbortSignal(ctrl.signal, () => client.workflow.execute(myWorkflow, options));
|
|
477
504
|
* ```
|
|
505
|
+
*
|
|
506
|
+
* @returns value returned from `fn`
|
|
507
|
+
*
|
|
508
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal
|
|
478
509
|
*/
|
|
479
510
|
async withAbortSignal<ReturnType>(abortSignal: AbortSignal, fn: () => Promise<ReturnType>): Promise<ReturnType> {
|
|
480
511
|
const cc = this.callContextStorage.getStore();
|
|
@@ -572,5 +603,6 @@ export class Connection {
|
|
|
572
603
|
*/
|
|
573
604
|
public async close(): Promise<void> {
|
|
574
605
|
this.client.close();
|
|
606
|
+
this.callContextStorage.disable();
|
|
575
607
|
}
|
|
576
608
|
}
|
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,
|
|
@@ -162,6 +162,10 @@ export interface ListScheduleOptions {
|
|
|
162
162
|
* @default 1000
|
|
163
163
|
*/
|
|
164
164
|
pageSize?: number;
|
|
165
|
+
/**
|
|
166
|
+
* Filter schedules by a query string.
|
|
167
|
+
*/
|
|
168
|
+
query?: string;
|
|
165
169
|
}
|
|
166
170
|
|
|
167
171
|
/**
|
|
@@ -247,7 +251,7 @@ export class ScheduleClient extends BaseClient {
|
|
|
247
251
|
? opts.state.backfill.map((x) => ({
|
|
248
252
|
startTime: optionalDateToTs(x.start),
|
|
249
253
|
endTime: optionalDateToTs(x.end),
|
|
250
|
-
overlapPolicy: x.overlap ?
|
|
254
|
+
overlapPolicy: x.overlap ? encodeScheduleOverlapPolicy(x.overlap) : undefined,
|
|
251
255
|
}))
|
|
252
256
|
: undefined,
|
|
253
257
|
},
|
|
@@ -368,6 +372,7 @@ export class ScheduleClient extends BaseClient {
|
|
|
368
372
|
nextPageToken,
|
|
369
373
|
namespace: this.options.namespace,
|
|
370
374
|
maximumPageSize: options?.pageSize,
|
|
375
|
+
query: options?.query,
|
|
371
376
|
});
|
|
372
377
|
} catch (e) {
|
|
373
378
|
this.rethrowGrpcError(e, 'Failed to list schedules', undefined);
|
|
@@ -422,7 +427,8 @@ export class ScheduleClient extends BaseClient {
|
|
|
422
427
|
memo: await decodeMapFromPayloads(this.client.dataConverter, raw.memo?.fields),
|
|
423
428
|
searchAttributes: decodeSearchAttributes(raw.searchAttributes),
|
|
424
429
|
policies: {
|
|
425
|
-
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,
|
|
426
432
|
catchupWindow: optionalTsToMs(raw.schedule.policies?.catchupWindow) ?? 60_000,
|
|
427
433
|
pauseOnFailure: raw.schedule.policies?.pauseOnFailure === true,
|
|
428
434
|
},
|
|
@@ -480,7 +486,7 @@ export class ScheduleClient extends BaseClient {
|
|
|
480
486
|
await this.client._patchSchedule(this.scheduleId, {
|
|
481
487
|
triggerImmediately: {
|
|
482
488
|
overlapPolicy: overlap
|
|
483
|
-
?
|
|
489
|
+
? encodeScheduleOverlapPolicy(overlap)
|
|
484
490
|
: temporal.api.enums.v1.ScheduleOverlapPolicy.SCHEDULE_OVERLAP_POLICY_ALLOW_ALL,
|
|
485
491
|
},
|
|
486
492
|
});
|
|
@@ -492,7 +498,7 @@ export class ScheduleClient extends BaseClient {
|
|
|
492
498
|
backfillRequest: backfills.map((x) => ({
|
|
493
499
|
startTime: optionalDateToTs(x.start),
|
|
494
500
|
endTime: optionalDateToTs(x.end),
|
|
495
|
-
overlapPolicy: x.overlap ?
|
|
501
|
+
overlapPolicy: x.overlap ? encodeScheduleOverlapPolicy(x.overlap) : undefined,
|
|
496
502
|
})),
|
|
497
503
|
});
|
|
498
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
|
/**
|