@proompteng/temporal-bun-sdk 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -11
- package/dist/src/bin/replay-command.d.ts.map +1 -1
- package/dist/src/bin/replay-command.js +6 -2
- package/dist/src/bin/replay-command.js.map +1 -1
- package/dist/src/bin/temporal-bun.d.ts +1 -1
- package/dist/src/bin/temporal-bun.d.ts.map +1 -1
- package/dist/src/bin/temporal-bun.js +75 -1
- package/dist/src/bin/temporal-bun.js.map +1 -1
- package/dist/src/client/layer.d.ts +2 -2
- package/dist/src/client/layer.d.ts.map +1 -1
- package/dist/src/client/retries.d.ts.map +1 -1
- package/dist/src/client/retries.js +27 -3
- package/dist/src/client/retries.js.map +1 -1
- package/dist/src/client/serialization.d.ts +4 -1
- package/dist/src/client/serialization.d.ts.map +1 -1
- package/dist/src/client/serialization.js +2 -2
- package/dist/src/client/serialization.js.map +1 -1
- package/dist/src/client.d.ts +12 -4
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/client.js +270 -63
- package/dist/src/client.js.map +1 -1
- package/dist/src/common/payloads/codecs.d.ts +38 -0
- package/dist/src/common/payloads/codecs.d.ts.map +1 -0
- package/dist/src/common/payloads/codecs.js +174 -0
- package/dist/src/common/payloads/codecs.js.map +1 -0
- package/dist/src/common/payloads/converter.d.ts +52 -3
- package/dist/src/common/payloads/converter.d.ts.map +1 -1
- package/dist/src/common/payloads/converter.js +340 -2
- package/dist/src/common/payloads/converter.js.map +1 -1
- package/dist/src/common/payloads/failure.d.ts +5 -6
- package/dist/src/common/payloads/failure.d.ts.map +1 -1
- package/dist/src/common/payloads/failure.js +3 -52
- package/dist/src/common/payloads/failure.js.map +1 -1
- package/dist/src/common/payloads/index.d.ts +1 -0
- package/dist/src/common/payloads/index.d.ts.map +1 -1
- package/dist/src/common/payloads/index.js +1 -0
- package/dist/src/common/payloads/index.js.map +1 -1
- package/dist/src/common/payloads/json-codec.d.ts.map +1 -1
- package/dist/src/common/payloads/json-codec.js +4 -6
- package/dist/src/common/payloads/json-codec.js.map +1 -1
- package/dist/src/config.d.ts +25 -0
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +111 -1
- package/dist/src/config.js.map +1 -1
- package/dist/src/interceptors/client.d.ts +28 -0
- package/dist/src/interceptors/client.d.ts.map +1 -0
- package/dist/src/interceptors/client.js +190 -0
- package/dist/src/interceptors/client.js.map +1 -0
- package/dist/src/interceptors/types.d.ts +33 -0
- package/dist/src/interceptors/types.d.ts.map +1 -0
- package/dist/src/interceptors/types.js +44 -0
- package/dist/src/interceptors/types.js.map +1 -0
- package/dist/src/interceptors/worker.d.ts +22 -0
- package/dist/src/interceptors/worker.d.ts.map +1 -0
- package/dist/src/interceptors/worker.js +177 -0
- package/dist/src/interceptors/worker.js.map +1 -0
- package/dist/src/observability/index.d.ts +4 -0
- package/dist/src/observability/index.d.ts.map +1 -1
- package/dist/src/observability/index.js +4 -0
- package/dist/src/observability/index.js.map +1 -1
- package/dist/src/observability/metrics.d.ts.map +1 -1
- package/dist/src/observability/metrics.js +70 -10
- package/dist/src/observability/metrics.js.map +1 -1
- package/dist/src/observability/opentelemetry.d.ts +20 -0
- package/dist/src/observability/opentelemetry.d.ts.map +1 -0
- package/dist/src/observability/opentelemetry.js +334 -0
- package/dist/src/observability/opentelemetry.js.map +1 -0
- package/dist/src/proto/temporal/api/activity/v1/message_pb.js +1 -1
- package/dist/src/proto/temporal/api/batch/v1/message_pb.js +1 -1
- package/dist/src/proto/temporal/api/command/v1/message_pb.js +1 -1
- package/dist/src/proto/temporal/api/common/v1/message_pb.js +1 -1
- package/dist/src/proto/temporal/api/deployment/v1/message_pb.js +1 -1
- package/dist/src/proto/temporal/api/enums/v1/batch_operation_pb.js +1 -1
- package/dist/src/proto/temporal/api/enums/v1/command_type_pb.js +1 -1
- package/dist/src/proto/temporal/api/enums/v1/common_pb.js +1 -1
- package/dist/src/proto/temporal/api/enums/v1/deployment_pb.js +1 -1
- package/dist/src/proto/temporal/api/enums/v1/event_type_pb.js +1 -1
- package/dist/src/proto/temporal/api/enums/v1/failed_cause_pb.js +1 -1
- package/dist/src/proto/temporal/api/enums/v1/namespace_pb.js +1 -1
- package/dist/src/proto/temporal/api/enums/v1/nexus_pb.js +1 -1
- package/dist/src/proto/temporal/api/enums/v1/query_pb.js +1 -1
- package/dist/src/proto/temporal/api/enums/v1/reset_pb.js +1 -1
- package/dist/src/proto/temporal/api/enums/v1/schedule_pb.js +1 -1
- package/dist/src/proto/temporal/api/enums/v1/task_queue_pb.js +1 -1
- package/dist/src/proto/temporal/api/enums/v1/update_pb.js +1 -1
- package/dist/src/proto/temporal/api/enums/v1/workflow_pb.js +1 -1
- package/dist/src/proto/temporal/api/errordetails/v1/message_pb.js +1 -1
- package/dist/src/proto/temporal/api/export/v1/message_pb.js +1 -1
- package/dist/src/proto/temporal/api/failure/v1/message_pb.js +1 -1
- package/dist/src/proto/temporal/api/filter/v1/message_pb.js +1 -1
- package/dist/src/proto/temporal/api/history/v1/message_pb.js +1 -1
- package/dist/src/proto/temporal/api/namespace/v1/message_pb.js +1 -1
- package/dist/src/proto/temporal/api/nexus/v1/message_pb.js +1 -1
- package/dist/src/proto/temporal/api/operatorservice/v1/request_response_pb.js +1 -1
- package/dist/src/proto/temporal/api/operatorservice/v1/service_pb.js +1 -1
- package/dist/src/proto/temporal/api/protocol/v1/message_pb.js +1 -1
- package/dist/src/proto/temporal/api/query/v1/message_pb.js +1 -1
- package/dist/src/proto/temporal/api/replication/v1/message_pb.js +1 -1
- package/dist/src/proto/temporal/api/rules/v1/message_pb.js +1 -1
- package/dist/src/proto/temporal/api/sdk/v1/enhanced_stack_trace_pb.js +1 -1
- package/dist/src/proto/temporal/api/sdk/v1/task_complete_metadata_pb.js +1 -1
- package/dist/src/proto/temporal/api/sdk/v1/user_metadata_pb.js +1 -1
- package/dist/src/proto/temporal/api/sdk/v1/worker_config_pb.js +1 -1
- package/dist/src/proto/temporal/api/sdk/v1/workflow_metadata_pb.js +1 -1
- package/dist/src/proto/temporal/api/taskqueue/v1/message_pb.js +1 -1
- package/dist/src/proto/temporal/api/update/v1/message_pb.js +1 -1
- package/dist/src/proto/temporal/api/version/v1/message_pb.js +1 -1
- package/dist/src/proto/temporal/api/worker/v1/message_pb.js +1 -1
- package/dist/src/proto/temporal/api/workflow/v1/message_pb.js +1 -1
- package/dist/src/proto/temporal/api/workflowservice/v1/request_response_pb.js +1 -1
- package/dist/src/proto/temporal/api/workflowservice/v1/service_pb.js +1 -1
- package/dist/src/runtime/cli-layer.d.ts +4 -3
- package/dist/src/runtime/cli-layer.d.ts.map +1 -1
- package/dist/src/runtime/cli-layer.js +5 -2
- package/dist/src/runtime/cli-layer.js.map +1 -1
- package/dist/src/runtime/effect-layers.d.ts +9 -0
- package/dist/src/runtime/effect-layers.d.ts.map +1 -1
- package/dist/src/runtime/effect-layers.js +15 -0
- package/dist/src/runtime/effect-layers.js.map +1 -1
- package/dist/src/worker/runtime.d.ts +6 -0
- package/dist/src/worker/runtime.d.ts.map +1 -1
- package/dist/src/worker/runtime.js +853 -70
- package/dist/src/worker/runtime.js.map +1 -1
- package/dist/src/worker/sticky-cache.d.ts +15 -0
- package/dist/src/worker/sticky-cache.d.ts.map +1 -1
- package/dist/src/worker/sticky-cache.js +26 -0
- package/dist/src/worker/sticky-cache.js.map +1 -1
- package/dist/src/worker/update-protocol.d.ts.map +1 -1
- package/dist/src/worker/update-protocol.js +15 -0
- package/dist/src/worker/update-protocol.js.map +1 -1
- package/dist/src/worker.js +1 -0
- package/dist/src/worker.js.map +1 -1
- package/dist/src/workflow/commands.d.ts +40 -3
- package/dist/src/workflow/commands.d.ts.map +1 -1
- package/dist/src/workflow/commands.js +161 -7
- package/dist/src/workflow/commands.js.map +1 -1
- package/dist/src/workflow/context.d.ts +59 -2
- package/dist/src/workflow/context.d.ts.map +1 -1
- package/dist/src/workflow/context.js +345 -16
- package/dist/src/workflow/context.js.map +1 -1
- package/dist/src/workflow/definition.js.map +1 -1
- package/dist/src/workflow/determinism.d.ts +9 -0
- package/dist/src/workflow/determinism.d.ts.map +1 -1
- package/dist/src/workflow/determinism.js +145 -16
- package/dist/src/workflow/determinism.js.map +1 -1
- package/dist/src/workflow/errors.d.ts +3 -0
- package/dist/src/workflow/errors.d.ts.map +1 -1
- package/dist/src/workflow/errors.js +6 -0
- package/dist/src/workflow/errors.js.map +1 -1
- package/dist/src/workflow/executor.d.ts +6 -0
- package/dist/src/workflow/executor.d.ts.map +1 -1
- package/dist/src/workflow/executor.js +147 -18
- package/dist/src/workflow/executor.js.map +1 -1
- package/dist/src/workflow/inbound.d.ts +1 -0
- package/dist/src/workflow/inbound.d.ts.map +1 -1
- package/dist/src/workflow/inbound.js +1 -0
- package/dist/src/workflow/inbound.js.map +1 -1
- package/dist/src/workflow/index.d.ts +5 -0
- package/dist/src/workflow/index.d.ts.map +1 -1
- package/dist/src/workflow/index.js +3 -0
- package/dist/src/workflow/index.js.map +1 -1
- package/dist/src/workflow/log.d.ts +18 -0
- package/dist/src/workflow/log.d.ts.map +1 -0
- package/dist/src/workflow/log.js +36 -0
- package/dist/src/workflow/log.js.map +1 -0
- package/dist/src/workflow/replay.d.ts +31 -3
- package/dist/src/workflow/replay.d.ts.map +1 -1
- package/dist/src/workflow/replay.js +763 -67
- package/dist/src/workflow/replay.js.map +1 -1
- package/package.json +4 -3
package/dist/src/client.js
CHANGED
|
@@ -5,17 +5,19 @@ import { Context, Effect } from 'effect';
|
|
|
5
5
|
import * as Option from 'effect/Option';
|
|
6
6
|
import { createDefaultHeaders, mergeHeaders, normalizeMetadataHeaders } from './client/headers';
|
|
7
7
|
import { makeDefaultInterceptorBuilder } from './client/interceptors';
|
|
8
|
-
import { withTemporalRetry } from './client/retries';
|
|
9
8
|
import { buildCancelRequest, buildPollWorkflowUpdateRequest, buildQueryRequest, buildSignalRequest, buildSignalWithStartRequest, buildStartWorkflowRequest, buildTerminateRequest, buildUpdateWorkflowRequest, computeSignalRequestId, createSignalRequestEntropy, createUpdateRequestId, decodeMemoAttributes, decodeSearchAttributes, decodeUpdateOutcome, encodeMemoAttributes, encodeSearchAttributes, } from './client/serialization';
|
|
10
9
|
import { buildTransportOptions, normalizeTemporalAddress } from './client/transport';
|
|
11
10
|
import { createWorkflowHandle, } from './client/types';
|
|
12
|
-
import { createDefaultDataConverter, decodePayloadsToValues } from './common/payloads';
|
|
11
|
+
import { buildCodecsFromConfig, createDefaultDataConverter, decodePayloadsToValues, } from './common/payloads';
|
|
13
12
|
import { loadTemporalConfig } from './config';
|
|
13
|
+
import { makeDefaultClientInterceptors, runClientInterceptors, } from './interceptors/client';
|
|
14
14
|
import { createObservabilityServices } from './observability';
|
|
15
|
+
import { WorkflowExecutionSchema, } from './proto/temporal/api/common/v1/message_pb';
|
|
15
16
|
import { UpdateWorkflowExecutionLifecycleStage } from './proto/temporal/api/enums/v1/update_pb';
|
|
16
|
-
import {
|
|
17
|
+
import { HistoryEventFilterType } from './proto/temporal/api/enums/v1/workflow_pb';
|
|
18
|
+
import { DescribeNamespaceRequestSchema, DescribeNamespaceResponseSchema, GetWorkflowExecutionHistoryRequestSchema, } from './proto/temporal/api/workflowservice/v1/request_response_pb';
|
|
17
19
|
import { WorkflowService } from './proto/temporal/api/workflowservice/v1/service_pb';
|
|
18
|
-
import { LoggerService, MetricsExporterService, MetricsService, TemporalConfigService, WorkflowServiceClientService, } from './runtime/effect-layers';
|
|
20
|
+
import { DataConverterService, LoggerService, MetricsExporterService, MetricsService, TemporalConfigService, WorkflowServiceClientService, } from './runtime/effect-layers';
|
|
19
21
|
export const temporalCallOptions = (options) => {
|
|
20
22
|
const copy = { ...options };
|
|
21
23
|
Object.defineProperty(copy, CALL_OPTIONS_MARKER, {
|
|
@@ -54,6 +56,38 @@ const describeError = (error) => {
|
|
|
54
56
|
};
|
|
55
57
|
const TLS_ERROR_CODE_PREFIXES = ['ERR_TLS_', 'ERR_SSL_'];
|
|
56
58
|
const TLS_ERROR_MESSAGE_HINTS = [/handshake/i, /certificate/i, /secure tls/i, /ssl/i];
|
|
59
|
+
const isAbortLikeError = (error) => (error instanceof Error && error.name === 'AbortError') ||
|
|
60
|
+
(error instanceof ConnectError && error.code === Code.Canceled);
|
|
61
|
+
const normalizeUnknownError = (error) => {
|
|
62
|
+
const unwrap = (value) => {
|
|
63
|
+
if (!value || typeof value !== 'object') {
|
|
64
|
+
return value;
|
|
65
|
+
}
|
|
66
|
+
if (value instanceof TemporalTlsHandshakeError || value instanceof ConnectError) {
|
|
67
|
+
return value;
|
|
68
|
+
}
|
|
69
|
+
const candidate = value;
|
|
70
|
+
if (candidate.cause !== undefined) {
|
|
71
|
+
return unwrap(candidate.cause);
|
|
72
|
+
}
|
|
73
|
+
if (candidate.error !== undefined) {
|
|
74
|
+
return unwrap(candidate.error);
|
|
75
|
+
}
|
|
76
|
+
if (candidate._tag === 'UnknownException') {
|
|
77
|
+
return unwrap(candidate.cause ?? candidate.error ?? value);
|
|
78
|
+
}
|
|
79
|
+
const symbols = Object.getOwnPropertySymbols(value);
|
|
80
|
+
for (const symbol of symbols) {
|
|
81
|
+
const inner = value[symbol];
|
|
82
|
+
const unwrapped = unwrap(inner);
|
|
83
|
+
if (unwrapped !== inner) {
|
|
84
|
+
return unwrapped;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return value;
|
|
88
|
+
};
|
|
89
|
+
return unwrap(error);
|
|
90
|
+
};
|
|
57
91
|
const isCallOptionsCandidate = (value) => {
|
|
58
92
|
if (!value || typeof value !== 'object') {
|
|
59
93
|
return false;
|
|
@@ -132,6 +166,12 @@ export const createTemporalClient = async (options = {}) => {
|
|
|
132
166
|
if (!workflowService) {
|
|
133
167
|
throw new Error('Temporal workflow service is not available');
|
|
134
168
|
}
|
|
169
|
+
const dataConverter = options.dataConverter ??
|
|
170
|
+
createDefaultDataConverter({
|
|
171
|
+
payloadCodecs: buildCodecsFromConfig(config.payloadCodecs),
|
|
172
|
+
logger,
|
|
173
|
+
metricsRegistry,
|
|
174
|
+
});
|
|
135
175
|
const effect = makeTemporalClientEffect({
|
|
136
176
|
...options,
|
|
137
177
|
config,
|
|
@@ -140,9 +180,10 @@ export const createTemporalClient = async (options = {}) => {
|
|
|
140
180
|
metricsExporter,
|
|
141
181
|
workflowService,
|
|
142
182
|
transport,
|
|
183
|
+
dataConverter,
|
|
143
184
|
});
|
|
144
185
|
try {
|
|
145
|
-
return await Effect.runPromise(effect.pipe(Effect.provideService(TemporalConfigService, config), Effect.provideService(LoggerService, logger), Effect.provideService(MetricsService, metricsRegistry), Effect.provideService(MetricsExporterService, metricsExporter), Effect.provideService(WorkflowServiceClientService, workflowService)));
|
|
186
|
+
return await Effect.runPromise(effect.pipe(Effect.provideService(TemporalConfigService, config), Effect.provideService(LoggerService, logger), Effect.provideService(MetricsService, metricsRegistry), Effect.provideService(MetricsExporterService, metricsExporter), Effect.provideService(WorkflowServiceClientService, workflowService), Effect.provideService(DataConverterService, dataConverter)));
|
|
146
187
|
}
|
|
147
188
|
catch (error) {
|
|
148
189
|
await createdTransport?.close?.();
|
|
@@ -154,11 +195,33 @@ export const makeTemporalClientEffect = (options = {}) => Effect.gen(function* (
|
|
|
154
195
|
const namespace = options.namespace ?? config.namespace;
|
|
155
196
|
const identity = options.identity ?? config.workerIdentity;
|
|
156
197
|
const taskQueue = options.taskQueue ?? config.taskQueue;
|
|
157
|
-
const dataConverter = options.dataConverter ?? createDefaultDataConverter();
|
|
158
|
-
const initialHeaders = createDefaultHeaders(config.apiKey);
|
|
159
198
|
const logger = options.logger ?? (yield* LoggerService);
|
|
160
199
|
const metricsRegistry = options.metrics ?? (yield* MetricsService);
|
|
161
200
|
const metricsExporter = options.metricsExporter ?? (yield* MetricsExporterService);
|
|
201
|
+
const contextualDataConverter = yield* Effect.contextWith((context) => Context.getOption(context, DataConverterService));
|
|
202
|
+
const dataConverter = options.dataConverter ??
|
|
203
|
+
Option.getOrUndefined(contextualDataConverter) ??
|
|
204
|
+
createDefaultDataConverter({
|
|
205
|
+
payloadCodecs: buildCodecsFromConfig(config.payloadCodecs),
|
|
206
|
+
logger,
|
|
207
|
+
metricsRegistry,
|
|
208
|
+
});
|
|
209
|
+
const initialHeaders = createDefaultHeaders(config.apiKey);
|
|
210
|
+
const tracingEnabled = options.tracingEnabled ?? config.tracingInterceptorsEnabled ?? false;
|
|
211
|
+
const clientInterceptorBuilder = options.clientInterceptorBuilder ?? {
|
|
212
|
+
build: (input) => makeDefaultClientInterceptors(input),
|
|
213
|
+
};
|
|
214
|
+
const defaultClientInterceptors = yield* clientInterceptorBuilder.build({
|
|
215
|
+
namespace,
|
|
216
|
+
taskQueue,
|
|
217
|
+
identity,
|
|
218
|
+
logger,
|
|
219
|
+
metricsRegistry,
|
|
220
|
+
metricsExporter,
|
|
221
|
+
retryPolicy: config.rpcRetryPolicy,
|
|
222
|
+
tracingEnabled,
|
|
223
|
+
});
|
|
224
|
+
const clientInterceptors = [...defaultClientInterceptors, ...(options.clientInterceptors ?? [])];
|
|
162
225
|
const workflowServiceFromContext = yield* Effect.contextWith((context) => Context.getOption(context, WorkflowServiceClientService));
|
|
163
226
|
let workflowService = options.workflowService ?? Option.getOrUndefined(workflowServiceFromContext);
|
|
164
227
|
let transport = options.transport;
|
|
@@ -199,6 +262,7 @@ export const makeTemporalClientEffect = (options = {}) => Effect.gen(function* (
|
|
|
199
262
|
logger,
|
|
200
263
|
metrics: clientMetrics,
|
|
201
264
|
metricsExporter,
|
|
265
|
+
clientInterceptors,
|
|
202
266
|
});
|
|
203
267
|
return { client, config };
|
|
204
268
|
});
|
|
@@ -216,7 +280,9 @@ class TemporalClientImpl {
|
|
|
216
280
|
#logger;
|
|
217
281
|
#clientMetrics;
|
|
218
282
|
#metricsExporter;
|
|
283
|
+
#clientInterceptors;
|
|
219
284
|
#pendingUpdateControllers = new Map();
|
|
285
|
+
#abortedUpdates = new Set();
|
|
220
286
|
closed = false;
|
|
221
287
|
headers;
|
|
222
288
|
static async initMetrics(registry) {
|
|
@@ -240,6 +306,7 @@ class TemporalClientImpl {
|
|
|
240
306
|
this.#logger = handles.logger;
|
|
241
307
|
this.#clientMetrics = handles.metrics;
|
|
242
308
|
this.#metricsExporter = handles.metricsExporter;
|
|
309
|
+
this.#clientInterceptors = handles.clientInterceptors;
|
|
243
310
|
this.memo = {
|
|
244
311
|
encode: (input) => encodeMemoAttributes(this.dataConverter, input),
|
|
245
312
|
decode: (memo) => decodeMemoAttributes(this.dataConverter, memo),
|
|
@@ -259,12 +326,13 @@ class TemporalClientImpl {
|
|
|
259
326
|
awaitUpdate: (updateHandle, options, callOptions) => this.awaitWorkflowUpdate(updateHandle, options, callOptions),
|
|
260
327
|
cancelUpdate: (updateHandle) => this.cancelWorkflowUpdate(updateHandle),
|
|
261
328
|
getUpdateHandle: (workflowHandle, updateId, firstExecutionRunId) => this.getWorkflowUpdateHandle(workflowHandle, updateId, firstExecutionRunId),
|
|
329
|
+
result: (handle, callOptions) => this.getWorkflowResult(handle, callOptions),
|
|
262
330
|
};
|
|
263
331
|
}
|
|
264
332
|
async startWorkflow(options, callOptions) {
|
|
265
|
-
|
|
333
|
+
const parsedOptions = sanitizeStartWorkflowOptions(options);
|
|
334
|
+
return this.#instrumentOperation('workflow.start', async () => {
|
|
266
335
|
this.ensureOpen();
|
|
267
|
-
const parsedOptions = sanitizeStartWorkflowOptions(options);
|
|
268
336
|
const request = await buildStartWorkflowRequest({
|
|
269
337
|
options: parsedOptions,
|
|
270
338
|
defaults: {
|
|
@@ -279,12 +347,15 @@ class TemporalClientImpl {
|
|
|
279
347
|
namespace: request.namespace,
|
|
280
348
|
firstExecutionRunId: response.started ? response.runId : undefined,
|
|
281
349
|
});
|
|
350
|
+
}, {
|
|
351
|
+
workflowId: parsedOptions.workflowId,
|
|
352
|
+
taskQueue: options.taskQueue ?? this.defaultTaskQueue,
|
|
282
353
|
});
|
|
283
354
|
}
|
|
284
355
|
async signalWorkflow(handle, signalName, ...rawArgs) {
|
|
285
|
-
|
|
356
|
+
const resolvedHandle = resolveHandle(this.namespace, handle);
|
|
357
|
+
return this.#instrumentOperation('workflow.signal', async () => {
|
|
286
358
|
this.ensureOpen();
|
|
287
|
-
const resolvedHandle = resolveHandle(this.namespace, handle);
|
|
288
359
|
const normalizedSignalName = ensureNonEmptyString(signalName, 'signalName');
|
|
289
360
|
const { values, callOptions } = this.#splitArgsAndOptions(rawArgs);
|
|
290
361
|
const identity = this.defaultIdentity;
|
|
@@ -306,39 +377,101 @@ class TemporalClientImpl {
|
|
|
306
377
|
requestId,
|
|
307
378
|
}, this.dataConverter);
|
|
308
379
|
await this.executeRpc('signalWorkflow', (rpcOptions) => this.workflowService.signalWorkflowExecution(request, rpcOptions), callOptions);
|
|
309
|
-
});
|
|
380
|
+
}, { workflowId: resolvedHandle.workflowId, runId: resolvedHandle.runId, taskQueue: this.defaultTaskQueue });
|
|
310
381
|
}
|
|
311
382
|
async queryWorkflow(handle, queryName, ...rawArgs) {
|
|
312
|
-
|
|
383
|
+
const resolvedHandle = resolveHandle(this.namespace, handle);
|
|
384
|
+
return this.#instrumentOperation('workflow.query', async () => {
|
|
313
385
|
this.ensureOpen();
|
|
314
|
-
const resolvedHandle = resolveHandle(this.namespace, handle);
|
|
315
386
|
const { values, callOptions } = this.#splitArgsAndOptions(rawArgs);
|
|
316
|
-
const request = await buildQueryRequest(resolvedHandle, queryName, values, this.dataConverter
|
|
387
|
+
const request = await buildQueryRequest(resolvedHandle, queryName, values, this.dataConverter, {
|
|
388
|
+
rejectCondition: callOptions?.queryRejectCondition,
|
|
389
|
+
});
|
|
317
390
|
const response = await this.executeRpc('queryWorkflow', (rpcOptions) => this.workflowService.queryWorkflow(request, rpcOptions), callOptions);
|
|
318
391
|
return this.parseQueryResult(response);
|
|
319
|
-
});
|
|
392
|
+
}, { workflowId: resolvedHandle.workflowId, runId: resolvedHandle.runId });
|
|
320
393
|
}
|
|
321
394
|
async terminateWorkflow(handle, options = {}, callOptions) {
|
|
322
|
-
return this.#instrumentOperation('
|
|
395
|
+
return this.#instrumentOperation('workflow.terminate', async () => {
|
|
323
396
|
this.ensureOpen();
|
|
324
397
|
const resolvedHandle = resolveHandle(this.namespace, handle);
|
|
325
398
|
const parsedOptions = sanitizeTerminateWorkflowOptions(options);
|
|
326
399
|
const request = await buildTerminateRequest(resolvedHandle, parsedOptions, this.dataConverter, this.defaultIdentity);
|
|
327
400
|
await this.executeRpc('terminateWorkflow', (rpcOptions) => this.workflowService.terminateWorkflowExecution(request, rpcOptions), callOptions);
|
|
328
|
-
});
|
|
401
|
+
}, { workflowId: handle.workflowId, runId: handle.runId });
|
|
329
402
|
}
|
|
330
403
|
async cancelWorkflow(handle, callOptions) {
|
|
331
|
-
|
|
404
|
+
const resolvedHandle = resolveHandle(this.namespace, handle);
|
|
405
|
+
return this.#instrumentOperation('workflow.cancel', async () => {
|
|
332
406
|
this.ensureOpen();
|
|
333
|
-
const resolvedHandle = resolveHandle(this.namespace, handle);
|
|
334
407
|
const request = buildCancelRequest(resolvedHandle, this.defaultIdentity);
|
|
335
408
|
await this.executeRpc('cancelWorkflow', (rpcOptions) => this.workflowService.requestCancelWorkflowExecution(request, rpcOptions), callOptions);
|
|
336
|
-
});
|
|
409
|
+
}, { workflowId: resolvedHandle.workflowId, runId: resolvedHandle.runId });
|
|
410
|
+
}
|
|
411
|
+
async getWorkflowResult(handle, callOptions) {
|
|
412
|
+
let resolvedHandle = resolveHandle(this.namespace, handle);
|
|
413
|
+
return this.#instrumentOperation('workflow.result', async () => {
|
|
414
|
+
this.ensureOpen();
|
|
415
|
+
while (true) {
|
|
416
|
+
const execution = create(WorkflowExecutionSchema, {
|
|
417
|
+
workflowId: resolvedHandle.workflowId,
|
|
418
|
+
...(resolvedHandle.runId ? { runId: resolvedHandle.runId } : {}),
|
|
419
|
+
});
|
|
420
|
+
const request = create(GetWorkflowExecutionHistoryRequestSchema, {
|
|
421
|
+
namespace: resolvedHandle.namespace ?? this.namespace,
|
|
422
|
+
execution,
|
|
423
|
+
maximumPageSize: 1,
|
|
424
|
+
historyEventFilterType: HistoryEventFilterType.CLOSE_EVENT,
|
|
425
|
+
waitNewEvent: true,
|
|
426
|
+
skipArchival: true,
|
|
427
|
+
});
|
|
428
|
+
const response = await this.executeRpc('getWorkflowExecutionHistory', (rpcOptions) => this.workflowService.getWorkflowExecutionHistory(request, rpcOptions), callOptions);
|
|
429
|
+
const closeEvent = this.#extractCloseEvent(response);
|
|
430
|
+
if (!closeEvent || !closeEvent.attributes) {
|
|
431
|
+
throw new Error('Workflow close event not found');
|
|
432
|
+
}
|
|
433
|
+
const attributes = closeEvent.attributes;
|
|
434
|
+
switch (attributes.case) {
|
|
435
|
+
case 'workflowExecutionContinuedAsNewEventAttributes': {
|
|
436
|
+
const nextRunId = attributes.value.newExecutionRunId;
|
|
437
|
+
if (!nextRunId) {
|
|
438
|
+
throw new Error('Continue-as-new event missing newExecutionRunId');
|
|
439
|
+
}
|
|
440
|
+
resolvedHandle = { ...resolvedHandle, runId: nextRunId };
|
|
441
|
+
continue;
|
|
442
|
+
}
|
|
443
|
+
case 'workflowExecutionCompletedEventAttributes': {
|
|
444
|
+
const payloads = attributes.value.result?.payloads ?? [];
|
|
445
|
+
const decoded = await this.dataConverter.fromPayloads(payloads);
|
|
446
|
+
return (decoded.length <= 1 ? decoded[0] : decoded) ?? undefined;
|
|
447
|
+
}
|
|
448
|
+
case 'workflowExecutionFailedEventAttributes': {
|
|
449
|
+
const failure = await this.dataConverter.decodeFailurePayloads(attributes.value.failure);
|
|
450
|
+
const error = await this.dataConverter.failureToError(failure);
|
|
451
|
+
throw error ?? new Error('Workflow failed');
|
|
452
|
+
}
|
|
453
|
+
case 'workflowExecutionTimedOutEventAttributes':
|
|
454
|
+
throw new Error('Workflow timed out');
|
|
455
|
+
case 'workflowExecutionCanceledEventAttributes': {
|
|
456
|
+
const details = attributes.value.details?.payloads ?? [];
|
|
457
|
+
const decoded = await this.dataConverter.fromPayloads(details);
|
|
458
|
+
const detail = decoded.length <= 1 ? decoded[0] : decoded;
|
|
459
|
+
throw new Error(detail ? `Workflow canceled: ${JSON.stringify(detail)}` : 'Workflow canceled without details');
|
|
460
|
+
}
|
|
461
|
+
case 'workflowExecutionTerminatedEventAttributes': {
|
|
462
|
+
const reason = attributes.value.reason;
|
|
463
|
+
throw new Error(reason ? `Workflow terminated: ${reason}` : 'Workflow terminated');
|
|
464
|
+
}
|
|
465
|
+
default:
|
|
466
|
+
throw new Error(`Unsupported workflow close event type: ${attributes.case}`);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
}, { workflowId: resolvedHandle.workflowId, runId: resolvedHandle.runId });
|
|
337
470
|
}
|
|
338
471
|
async signalWithStart(options, callOptions) {
|
|
339
|
-
|
|
472
|
+
const startOptions = sanitizeStartWorkflowOptions(options);
|
|
473
|
+
return this.#instrumentOperation('workflow.signalWithStart', async () => {
|
|
340
474
|
this.ensureOpen();
|
|
341
|
-
const startOptions = sanitizeStartWorkflowOptions(options);
|
|
342
475
|
const signalName = ensureNonEmptyString(options.signalName, 'signalName');
|
|
343
476
|
const signalArgs = options.signalArgs ?? [];
|
|
344
477
|
if (!Array.isArray(signalArgs)) {
|
|
@@ -362,17 +495,17 @@ class TemporalClientImpl {
|
|
|
362
495
|
namespace: request.namespace,
|
|
363
496
|
firstExecutionRunId: response.started ? response.runId : undefined,
|
|
364
497
|
});
|
|
365
|
-
});
|
|
498
|
+
}, { workflowId: startOptions.workflowId });
|
|
366
499
|
}
|
|
367
500
|
async updateWorkflow(handle, options, callOptions) {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
501
|
+
this.ensureOpen();
|
|
502
|
+
const resolvedHandle = resolveHandle(this.namespace, handle);
|
|
503
|
+
const parsedOptions = sanitizeWorkflowUpdateOptions(options);
|
|
504
|
+
const updateId = parsedOptions.updateId ?? createUpdateRequestId();
|
|
505
|
+
const waitStage = this.#stageToProto(parsedOptions.waitForStage);
|
|
506
|
+
return this.#instrumentOperation('workflow.update', async () => {
|
|
374
507
|
const updateKey = this.#makeUpdateKey(resolvedHandle, updateId);
|
|
375
|
-
const { options: mergedCallOptions, controller, cleanup } = this.#prepareUpdateCallOptions(updateKey, callOptions);
|
|
508
|
+
const { options: mergedCallOptions, controller, cleanup, } = this.#prepareUpdateCallOptions(updateKey, callOptions);
|
|
376
509
|
try {
|
|
377
510
|
const request = await buildUpdateWorkflowRequest({
|
|
378
511
|
handle: resolvedHandle,
|
|
@@ -407,21 +540,21 @@ class TemporalClientImpl {
|
|
|
407
540
|
this.#releaseUpdateController(updateKey, controller);
|
|
408
541
|
cleanup?.();
|
|
409
542
|
}
|
|
410
|
-
});
|
|
543
|
+
}, { workflowId: resolvedHandle.workflowId, runId: resolvedHandle.runId, updateId });
|
|
411
544
|
}
|
|
412
545
|
async awaitWorkflowUpdate(handle, options = {}, callOptions) {
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
546
|
+
this.ensureOpen();
|
|
547
|
+
const resolvedHandle = resolveHandle(this.namespace, handle);
|
|
548
|
+
const updateId = ensureNonEmptyString(handle.updateId, 'updateId');
|
|
549
|
+
const waitStage = this.#stageToProto(options.waitForStage ?? 'completed');
|
|
550
|
+
const firstExecutionRunIdOverride = ensureOptionalTrimmedString(options.firstExecutionRunId, 'firstExecutionRunId', 1);
|
|
551
|
+
const pollHandle = {
|
|
552
|
+
workflowId: resolvedHandle.workflowId,
|
|
553
|
+
namespace: resolvedHandle.namespace,
|
|
554
|
+
runId: resolvedHandle.runId,
|
|
555
|
+
firstExecutionRunId: firstExecutionRunIdOverride ?? resolvedHandle.firstExecutionRunId,
|
|
556
|
+
};
|
|
557
|
+
return this.#instrumentOperation('workflow.awaitUpdate', async () => {
|
|
425
558
|
const request = buildPollWorkflowUpdateRequest({
|
|
426
559
|
handle: pollHandle,
|
|
427
560
|
namespace: this.namespace,
|
|
@@ -430,7 +563,16 @@ class TemporalClientImpl {
|
|
|
430
563
|
waitStage,
|
|
431
564
|
});
|
|
432
565
|
const updateKey = this.#makeUpdateKey(resolvedHandle, updateId);
|
|
433
|
-
const { options: mergedCallOptions, controller, cleanup } = this.#prepareUpdateCallOptions(updateKey, callOptions);
|
|
566
|
+
const { options: mergedCallOptions, controller, cleanup, } = this.#prepareUpdateCallOptions(updateKey, callOptions);
|
|
567
|
+
const throwIfAborted = () => {
|
|
568
|
+
if (controller.signal.aborted || this.#abortedUpdates.has(updateKey)) {
|
|
569
|
+
this.#abortedUpdates.delete(updateKey);
|
|
570
|
+
const abortError = new Error('Workflow update polling aborted');
|
|
571
|
+
abortError.name = 'AbortError';
|
|
572
|
+
throw abortError;
|
|
573
|
+
}
|
|
574
|
+
};
|
|
575
|
+
throwIfAborted();
|
|
434
576
|
try {
|
|
435
577
|
const response = await this.executeRpc('pollWorkflowExecutionUpdate', (rpcOptions) => this.workflowService.pollWorkflowExecutionUpdate(request, rpcOptions), mergedCallOptions);
|
|
436
578
|
const stage = this.#stageFromProto(response.stage);
|
|
@@ -447,11 +589,16 @@ class TemporalClientImpl {
|
|
|
447
589
|
outcome,
|
|
448
590
|
};
|
|
449
591
|
}
|
|
592
|
+
catch (error) {
|
|
593
|
+
throwIfAborted();
|
|
594
|
+
throw error;
|
|
595
|
+
}
|
|
450
596
|
finally {
|
|
597
|
+
this.#abortedUpdates.delete(updateKey);
|
|
451
598
|
this.#releaseUpdateController(updateKey, controller);
|
|
452
599
|
cleanup?.();
|
|
453
600
|
}
|
|
454
|
-
});
|
|
601
|
+
}, { workflowId: resolvedHandle.workflowId, runId: resolvedHandle.runId, updateId });
|
|
455
602
|
}
|
|
456
603
|
getWorkflowUpdateHandle(handle, updateId, firstExecutionRunId) {
|
|
457
604
|
const resolvedHandle = resolveHandle(this.namespace, handle);
|
|
@@ -463,7 +610,7 @@ class TemporalClientImpl {
|
|
|
463
610
|
});
|
|
464
611
|
}
|
|
465
612
|
async cancelWorkflowUpdate(handle) {
|
|
466
|
-
return this.#instrumentOperation('
|
|
613
|
+
return this.#instrumentOperation('workflow.update', async () => {
|
|
467
614
|
this.ensureOpen();
|
|
468
615
|
const resolvedHandle = resolveHandle(this.namespace, handle);
|
|
469
616
|
const updateId = ensureNonEmptyString(handle.updateId, 'updateId');
|
|
@@ -475,17 +622,17 @@ class TemporalClientImpl {
|
|
|
475
622
|
updateId,
|
|
476
623
|
});
|
|
477
624
|
}
|
|
478
|
-
});
|
|
625
|
+
}, { workflowId: handle.workflowId, runId: handle.runId, updateId: handle.updateId });
|
|
479
626
|
}
|
|
480
627
|
async describeNamespace(targetNamespace, callOptions) {
|
|
481
|
-
return this.#instrumentOperation('
|
|
628
|
+
return this.#instrumentOperation('workflow.describe', async () => {
|
|
482
629
|
this.ensureOpen();
|
|
483
630
|
const request = create(DescribeNamespaceRequestSchema, {
|
|
484
631
|
namespace: targetNamespace ?? this.namespace,
|
|
485
632
|
});
|
|
486
633
|
const response = await this.executeRpc('describeNamespace', (rpcOptions) => this.workflowService.describeNamespace(request, rpcOptions), callOptions);
|
|
487
634
|
return toBinary(DescribeNamespaceResponseSchema, response);
|
|
488
|
-
});
|
|
635
|
+
}, { namespace: targetNamespace ?? this.namespace });
|
|
489
636
|
}
|
|
490
637
|
async updateHeaders(headers) {
|
|
491
638
|
if (this.closed) {
|
|
@@ -523,24 +670,66 @@ class TemporalClientImpl {
|
|
|
523
670
|
void Effect.runPromise(this.#clientMetrics.operationErrors.inc());
|
|
524
671
|
}
|
|
525
672
|
}
|
|
526
|
-
async #instrumentOperation(operation, action) {
|
|
673
|
+
async #instrumentOperation(operation, action, metadata = {}) {
|
|
674
|
+
const context = {
|
|
675
|
+
kind: operation,
|
|
676
|
+
namespace: this.namespace,
|
|
677
|
+
taskQueue: metadata.taskQueue ?? this.defaultTaskQueue,
|
|
678
|
+
identity: this.defaultIdentity,
|
|
679
|
+
workflowId: metadata.workflowId,
|
|
680
|
+
runId: metadata.runId,
|
|
681
|
+
updateId: metadata.updateId,
|
|
682
|
+
metadata,
|
|
683
|
+
};
|
|
527
684
|
const start = Date.now();
|
|
685
|
+
const effect = runClientInterceptors(this.#clientInterceptors, context, () => Effect.tryPromise(action));
|
|
528
686
|
try {
|
|
529
|
-
const result = await
|
|
687
|
+
const result = await Effect.runPromise(effect);
|
|
530
688
|
this.#log('debug', `temporal client ${operation} succeeded`, {
|
|
531
689
|
operation,
|
|
532
690
|
namespace: this.namespace,
|
|
691
|
+
...metadata,
|
|
533
692
|
});
|
|
534
693
|
this.#recordMetrics(Date.now() - start, false);
|
|
535
694
|
return result;
|
|
536
695
|
}
|
|
537
696
|
catch (error) {
|
|
697
|
+
const normalized = normalizeUnknownError(error);
|
|
698
|
+
const finalError = normalized instanceof Error &&
|
|
699
|
+
normalized.message.toLowerCase().includes('unknown error occurred in effect.trypromise')
|
|
700
|
+
? (normalized.cause ??
|
|
701
|
+
normalized.error ??
|
|
702
|
+
normalized)
|
|
703
|
+
: normalized;
|
|
704
|
+
const message = finalError instanceof Error ? finalError.message.toLowerCase() : '';
|
|
705
|
+
const isUnknownPollAbort = operation === 'workflow.awaitUpdate' && message.includes('unknown error occurred in effect.trypromise');
|
|
706
|
+
if (isAbortLikeError(normalized)) {
|
|
707
|
+
this.#log('warn', `temporal client ${operation} aborted`, {
|
|
708
|
+
operation,
|
|
709
|
+
error: describeError(normalized),
|
|
710
|
+
...metadata,
|
|
711
|
+
});
|
|
712
|
+
this.#recordMetrics(Date.now() - start, true);
|
|
713
|
+
throw finalError;
|
|
714
|
+
}
|
|
715
|
+
if (isUnknownPollAbort) {
|
|
716
|
+
const abortError = new Error('Workflow update polling aborted');
|
|
717
|
+
abortError.name = 'AbortError';
|
|
718
|
+
this.#log('warn', `temporal client ${operation} aborted`, {
|
|
719
|
+
operation,
|
|
720
|
+
error: describeError(abortError),
|
|
721
|
+
...metadata,
|
|
722
|
+
});
|
|
723
|
+
this.#recordMetrics(Date.now() - start, true);
|
|
724
|
+
throw abortError;
|
|
725
|
+
}
|
|
538
726
|
this.#log('error', `temporal client ${operation} failed`, {
|
|
539
727
|
operation,
|
|
540
|
-
error: describeError(
|
|
728
|
+
error: describeError(finalError),
|
|
729
|
+
...metadata,
|
|
541
730
|
});
|
|
542
731
|
this.#recordMetrics(Date.now() - start, true);
|
|
543
|
-
throw
|
|
732
|
+
throw finalError;
|
|
544
733
|
}
|
|
545
734
|
}
|
|
546
735
|
#log(level, message, fields) {
|
|
@@ -587,6 +776,7 @@ class TemporalClientImpl {
|
|
|
587
776
|
return { options: overrides, controller, cleanup };
|
|
588
777
|
}
|
|
589
778
|
#registerUpdateController(key, controller) {
|
|
779
|
+
this.#abortedUpdates.delete(key);
|
|
590
780
|
const current = this.#pendingUpdateControllers.get(key);
|
|
591
781
|
if (current) {
|
|
592
782
|
current.add(controller);
|
|
@@ -607,12 +797,14 @@ class TemporalClientImpl {
|
|
|
607
797
|
#abortUpdateControllers(key) {
|
|
608
798
|
const current = this.#pendingUpdateControllers.get(key);
|
|
609
799
|
if (!current || current.size === 0) {
|
|
800
|
+
this.#abortedUpdates.add(key);
|
|
610
801
|
return false;
|
|
611
802
|
}
|
|
612
803
|
for (const controller of current) {
|
|
613
804
|
controller.abort();
|
|
614
805
|
}
|
|
615
806
|
this.#pendingUpdateControllers.delete(key);
|
|
807
|
+
this.#abortedUpdates.add(key);
|
|
616
808
|
return true;
|
|
617
809
|
}
|
|
618
810
|
#makeUpdateKey(handle, updateId) {
|
|
@@ -689,6 +881,13 @@ class TemporalClientImpl {
|
|
|
689
881
|
retryableStatusCodes,
|
|
690
882
|
};
|
|
691
883
|
}
|
|
884
|
+
#extractCloseEvent(response) {
|
|
885
|
+
const events = response?.history?.events ?? [];
|
|
886
|
+
if (events.length === 0) {
|
|
887
|
+
return undefined;
|
|
888
|
+
}
|
|
889
|
+
return events[events.length - 1];
|
|
890
|
+
}
|
|
692
891
|
#buildCallContext(overrides) {
|
|
693
892
|
const userHeaders = overrides?.headers ? normalizeMetadataHeaders(overrides.headers) : undefined;
|
|
694
893
|
const mergedHeaders = userHeaders ? mergeHeaders(this.headers, userHeaders) : { ...this.headers };
|
|
@@ -701,29 +900,37 @@ class TemporalClientImpl {
|
|
|
701
900
|
signal,
|
|
702
901
|
}),
|
|
703
902
|
retryPolicy: this.#mergeRetryPolicy(overrides?.retryPolicy),
|
|
903
|
+
headers: mergedHeaders,
|
|
704
904
|
};
|
|
705
905
|
}
|
|
706
906
|
async executeRpc(operation, rpc, overrides) {
|
|
707
|
-
const { create, retryPolicy } = this.#buildCallContext(overrides);
|
|
708
|
-
|
|
709
|
-
|
|
907
|
+
const { create, retryPolicy, headers } = this.#buildCallContext(overrides);
|
|
908
|
+
const interceptorContext = {
|
|
909
|
+
kind: 'rpc',
|
|
910
|
+
namespace: this.namespace,
|
|
911
|
+
taskQueue: this.defaultTaskQueue,
|
|
912
|
+
identity: this.defaultIdentity,
|
|
913
|
+
headers,
|
|
914
|
+
metadata: { retryPolicy },
|
|
915
|
+
};
|
|
916
|
+
const baseEffect = () => Effect.tryPromise({
|
|
710
917
|
try: () => {
|
|
711
|
-
attempt
|
|
918
|
+
interceptorContext.attempt = (interceptorContext.attempt ?? 0) + 1;
|
|
712
919
|
return rpc(create());
|
|
713
920
|
},
|
|
714
921
|
catch: (error) => wrapRpcError(error),
|
|
715
922
|
}).pipe(Effect.tapError((error) => Effect.sync(() => {
|
|
716
923
|
this.#log('warn', `temporal rpc ${operation} attempt failed`, {
|
|
717
924
|
operation,
|
|
718
|
-
attempt,
|
|
925
|
+
attempt: interceptorContext.attempt,
|
|
719
926
|
error: describeError(error),
|
|
720
927
|
});
|
|
721
928
|
})));
|
|
722
|
-
const result = await Effect.runPromise(
|
|
723
|
-
if (attempt > 1) {
|
|
724
|
-
this.#log('info', `temporal rpc ${operation} succeeded after ${attempt} attempts`, {
|
|
929
|
+
const result = await Effect.runPromise(runClientInterceptors(this.#clientInterceptors, interceptorContext, baseEffect));
|
|
930
|
+
if ((interceptorContext.attempt ?? 1) > 1) {
|
|
931
|
+
this.#log('info', `temporal rpc ${operation} succeeded after ${interceptorContext.attempt} attempts`, {
|
|
725
932
|
operation,
|
|
726
|
-
attempts: attempt,
|
|
933
|
+
attempts: interceptorContext.attempt,
|
|
727
934
|
});
|
|
728
935
|
}
|
|
729
936
|
return result;
|