@hotmeshio/hotmesh 0.12.1 → 0.14.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 +18 -22
- package/build/modules/enums.d.ts +60 -5
- package/build/modules/enums.js +62 -7
- package/build/modules/errors.d.ts +15 -2
- package/build/modules/errors.js +17 -1
- package/build/modules/storage.d.ts +1 -0
- package/build/modules/storage.js +2 -1
- package/build/package.json +8 -2
- package/build/services/activities/activity/context.d.ts +22 -0
- package/build/services/activities/activity/context.js +76 -0
- package/build/services/activities/activity/index.d.ts +116 -0
- package/build/services/activities/activity/index.js +299 -0
- package/build/services/activities/activity/mapping.d.ts +12 -0
- package/build/services/activities/activity/mapping.js +63 -0
- package/build/services/activities/activity/process.d.ts +28 -0
- package/build/services/activities/activity/process.js +100 -0
- package/build/services/activities/activity/protocol.d.ts +39 -0
- package/build/services/activities/activity/protocol.js +151 -0
- package/build/services/activities/activity/state.d.ts +40 -0
- package/build/services/activities/activity/state.js +143 -0
- package/build/services/activities/activity/transition.d.ts +23 -0
- package/build/services/activities/activity/transition.js +71 -0
- package/build/services/activities/activity/verify.d.ts +22 -0
- package/build/services/activities/activity/verify.js +85 -0
- package/build/services/activities/await.d.ts +1 -4
- package/build/services/activities/await.js +2 -36
- package/build/services/activities/cycle.d.ts +1 -11
- package/build/services/activities/cycle.js +3 -46
- package/build/services/activities/hook.d.ts +2 -11
- package/build/services/activities/hook.js +30 -50
- package/build/services/activities/interrupt.d.ts +2 -4
- package/build/services/activities/interrupt.js +4 -38
- package/build/services/activities/signal.d.ts +1 -11
- package/build/services/activities/signal.js +3 -48
- package/build/services/activities/trigger.d.ts +1 -3
- package/build/services/activities/trigger.js +0 -3
- package/build/services/activities/worker.d.ts +3 -6
- package/build/services/activities/worker.js +4 -40
- package/build/services/connector/factory.d.ts +6 -0
- package/build/services/connector/factory.js +24 -0
- package/build/services/dba/index.d.ts +14 -4
- package/build/services/dba/index.js +57 -18
- package/build/services/durable/activity.d.ts +30 -0
- package/build/services/durable/activity.js +46 -0
- package/build/services/durable/client.d.ts +26 -31
- package/build/services/durable/client.js +26 -31
- package/build/services/durable/connection.d.ts +13 -7
- package/build/services/durable/connection.js +13 -7
- package/build/services/durable/exporter.d.ts +2 -2
- package/build/services/durable/exporter.js +27 -12
- package/build/services/durable/handle.d.ts +59 -41
- package/build/services/durable/handle.js +61 -41
- package/build/services/durable/index.d.ts +152 -283
- package/build/services/durable/index.js +161 -289
- package/build/services/durable/interceptor.d.ts +43 -33
- package/build/services/durable/interceptor.js +59 -39
- package/build/services/durable/schemas/factory.d.ts +2 -3
- package/build/services/durable/schemas/factory.js +180 -30
- package/build/services/durable/telemetry.d.ts +80 -0
- package/build/services/durable/telemetry.js +137 -0
- package/build/services/durable/worker.d.ts +100 -21
- package/build/services/durable/worker.js +314 -60
- package/build/services/durable/workflow/all.d.ts +1 -1
- package/build/services/durable/workflow/all.js +1 -1
- package/build/services/durable/workflow/cancellationScope.d.ts +104 -0
- package/build/services/durable/workflow/cancellationScope.js +139 -0
- package/build/services/durable/workflow/common.d.ts +5 -4
- package/build/services/durable/workflow/common.js +6 -1
- package/build/services/durable/workflow/{waitFor.d.ts → condition.d.ts} +9 -8
- package/build/services/durable/workflow/{waitFor.js → condition.js} +44 -11
- package/build/services/durable/workflow/continueAsNew.d.ts +65 -0
- package/build/services/durable/workflow/continueAsNew.js +92 -0
- package/build/services/durable/workflow/didRun.d.ts +2 -2
- package/build/services/durable/workflow/didRun.js +4 -4
- package/build/services/durable/workflow/enrich.d.ts +5 -0
- package/build/services/durable/workflow/enrich.js +5 -0
- package/build/services/durable/workflow/entityMethods.d.ts +7 -0
- package/build/services/durable/workflow/entityMethods.js +7 -0
- package/build/services/durable/workflow/execHook.js +3 -3
- package/build/services/durable/workflow/execHookBatch.js +2 -2
- package/build/services/durable/workflow/{execChild.d.ts → executeChild.d.ts} +4 -40
- package/build/services/durable/workflow/{execChild.js → executeChild.js} +36 -45
- package/build/services/durable/workflow/hook.d.ts +1 -1
- package/build/services/durable/workflow/hook.js +4 -3
- package/build/services/durable/workflow/index.d.ts +45 -50
- package/build/services/durable/workflow/index.js +46 -51
- package/build/services/durable/workflow/interruption.d.ts +7 -6
- package/build/services/durable/workflow/interruption.js +11 -7
- package/build/services/durable/workflow/patched.d.ts +72 -0
- package/build/services/durable/workflow/patched.js +110 -0
- package/build/services/durable/workflow/proxyActivities.d.ts +7 -7
- package/build/services/durable/workflow/proxyActivities.js +51 -15
- package/build/services/durable/workflow/searchMethods.d.ts +7 -0
- package/build/services/durable/workflow/searchMethods.js +7 -0
- package/build/services/durable/workflow/signal.d.ts +4 -4
- package/build/services/durable/workflow/signal.js +4 -4
- package/build/services/durable/workflow/{sleepFor.d.ts → sleep.d.ts} +7 -7
- package/build/services/durable/workflow/{sleepFor.js → sleep.js} +39 -10
- package/build/services/durable/workflow/terminate.d.ts +55 -0
- package/build/services/durable/workflow/{interrupt.js → terminate.js} +21 -21
- package/build/services/durable/workflow/trace.js +2 -2
- package/build/services/durable/workflow/uuid4.d.ts +14 -0
- package/build/services/durable/workflow/uuid4.js +39 -0
- package/build/services/durable/workflow/{context.d.ts → workflowInfo.d.ts} +5 -5
- package/build/services/durable/workflow/{context.js → workflowInfo.js} +7 -7
- package/build/services/engine/compiler.d.ts +19 -0
- package/build/services/engine/compiler.js +20 -0
- package/build/services/engine/completion.d.ts +46 -0
- package/build/services/engine/completion.js +145 -0
- package/build/services/engine/dispatch.d.ts +24 -0
- package/build/services/engine/dispatch.js +98 -0
- package/build/services/engine/index.d.ts +49 -81
- package/build/services/engine/index.js +175 -573
- package/build/services/engine/init.d.ts +42 -0
- package/build/services/engine/init.js +74 -0
- package/build/services/engine/pubsub.d.ts +50 -0
- package/build/services/engine/pubsub.js +118 -0
- package/build/services/engine/reporting.d.ts +20 -0
- package/build/services/engine/reporting.js +38 -0
- package/build/services/engine/schema.d.ts +23 -0
- package/build/services/engine/schema.js +62 -0
- package/build/services/engine/signal.d.ts +57 -0
- package/build/services/engine/signal.js +117 -0
- package/build/services/engine/state.d.ts +35 -0
- package/build/services/engine/state.js +61 -0
- package/build/services/engine/version.d.ts +31 -0
- package/build/services/engine/version.js +73 -0
- package/build/services/hotmesh/deployment.d.ts +21 -0
- package/build/services/hotmesh/deployment.js +25 -0
- package/build/services/hotmesh/index.d.ts +142 -533
- package/build/services/hotmesh/index.js +223 -674
- package/build/services/hotmesh/init.d.ts +42 -0
- package/build/services/hotmesh/init.js +93 -0
- package/build/services/hotmesh/jobs.d.ts +67 -0
- package/build/services/hotmesh/jobs.js +99 -0
- package/build/services/hotmesh/pubsub.d.ts +38 -0
- package/build/services/hotmesh/pubsub.js +54 -0
- package/build/services/hotmesh/quorum.d.ts +30 -0
- package/build/services/hotmesh/quorum.js +62 -0
- package/build/services/hotmesh/validation.d.ts +6 -0
- package/build/services/hotmesh/validation.js +28 -0
- package/build/services/quorum/index.js +1 -0
- package/build/services/router/consumption/index.d.ts +11 -5
- package/build/services/router/consumption/index.js +24 -17
- package/build/services/router/error-handling/index.d.ts +2 -2
- package/build/services/router/error-handling/index.js +14 -14
- package/build/services/router/index.d.ts +1 -1
- package/build/services/router/index.js +2 -2
- package/build/services/serializer/index.d.ts +22 -0
- package/build/services/serializer/index.js +39 -1
- package/build/services/store/index.d.ts +1 -0
- package/build/services/store/providers/postgres/exporter-sql.d.ts +2 -2
- package/build/services/store/providers/postgres/exporter-sql.js +4 -4
- package/build/services/store/providers/postgres/kvtables.js +7 -6
- package/build/services/store/providers/postgres/kvtypes/hash/basic.js +67 -52
- package/build/services/store/providers/postgres/kvtypes/hash/jsonb.js +87 -72
- package/build/services/store/providers/postgres/kvtypes/hash/udata.js +106 -79
- package/build/services/store/providers/postgres/kvtypes/hash/utils.d.ts +16 -0
- package/build/services/store/providers/postgres/kvtypes/hash/utils.js +29 -16
- package/build/services/store/providers/postgres/postgres.d.ts +1 -0
- package/build/services/store/providers/postgres/postgres.js +14 -4
- package/build/services/stream/factory.d.ts +3 -1
- package/build/services/stream/factory.js +2 -2
- package/build/services/stream/index.d.ts +1 -0
- package/build/services/stream/providers/nats/nats.d.ts +1 -0
- package/build/services/stream/providers/nats/nats.js +1 -0
- package/build/services/stream/providers/postgres/credentials.d.ts +56 -0
- package/build/services/stream/providers/postgres/credentials.js +129 -0
- package/build/services/stream/providers/postgres/kvtables.js +18 -0
- package/build/services/stream/providers/postgres/messages.js +7 -7
- package/build/services/stream/providers/postgres/notifications.js +16 -2
- package/build/services/stream/providers/postgres/postgres.d.ts +7 -0
- package/build/services/stream/providers/postgres/postgres.js +35 -4
- package/build/services/stream/providers/postgres/procedures.d.ts +21 -0
- package/build/services/stream/providers/postgres/procedures.js +213 -0
- package/build/services/stream/providers/postgres/secured.d.ts +34 -0
- package/build/services/stream/providers/postgres/secured.js +146 -0
- package/build/services/stream/providers/postgres/stats.d.ts +1 -0
- package/build/services/stream/providers/postgres/stats.js +1 -0
- package/build/services/stream/registry.d.ts +1 -1
- package/build/services/stream/registry.js +5 -2
- package/build/services/telemetry/index.d.ts +10 -1
- package/build/services/telemetry/index.js +40 -7
- package/build/services/worker/credentials.d.ts +51 -0
- package/build/services/worker/credentials.js +87 -0
- package/build/services/worker/index.d.ts +2 -2
- package/build/services/worker/index.js +7 -6
- package/build/types/codec.d.ts +84 -0
- package/build/types/codec.js +2 -0
- package/build/types/dba.d.ts +39 -3
- package/build/types/durable.d.ts +123 -25
- package/build/types/error.d.ts +10 -0
- package/build/types/exporter.d.ts +1 -1
- package/build/types/hotmesh.d.ts +67 -4
- package/build/types/index.d.ts +2 -1
- package/build/types/provider.d.ts +2 -2
- package/build/types/quorum.d.ts +35 -1
- package/build/types/stream.d.ts +12 -6
- package/package.json +8 -2
- package/build/services/activities/activity.d.ts +0 -192
- package/build/services/activities/activity.js +0 -786
- package/build/services/durable/workflow/interrupt.d.ts +0 -55
|
@@ -1,66 +1,61 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.WorkflowService = void 0;
|
|
4
|
-
const
|
|
4
|
+
const workflowInfo_1 = require("./workflowInfo");
|
|
5
5
|
const didRun_1 = require("./didRun");
|
|
6
6
|
const isSideEffectAllowed_1 = require("./isSideEffectAllowed");
|
|
7
7
|
const trace_1 = require("./trace");
|
|
8
8
|
const enrich_1 = require("./enrich");
|
|
9
9
|
const emit_1 = require("./emit");
|
|
10
|
-
const
|
|
10
|
+
const executeChild_1 = require("./executeChild");
|
|
11
11
|
const execHook_1 = require("./execHook");
|
|
12
12
|
const execHookBatch_1 = require("./execHookBatch");
|
|
13
13
|
const proxyActivities_1 = require("./proxyActivities");
|
|
14
14
|
const searchMethods_1 = require("./searchMethods");
|
|
15
15
|
const random_1 = require("./random");
|
|
16
|
+
const uuid4_1 = require("./uuid4");
|
|
16
17
|
const signal_1 = require("./signal");
|
|
17
18
|
const hook_1 = require("./hook");
|
|
18
|
-
const
|
|
19
|
+
const terminate_1 = require("./terminate");
|
|
19
20
|
const interruption_1 = require("./interruption");
|
|
20
21
|
const all_1 = require("./all");
|
|
21
|
-
const
|
|
22
|
-
const
|
|
22
|
+
const sleep_1 = require("./sleep");
|
|
23
|
+
const condition_1 = require("./condition");
|
|
24
|
+
const continueAsNew_1 = require("./continueAsNew");
|
|
25
|
+
const patched_1 = require("./patched");
|
|
26
|
+
const cancellationScope_1 = require("./cancellationScope");
|
|
23
27
|
const common_1 = require("./common");
|
|
24
28
|
const entityMethods_1 = require("./entityMethods");
|
|
25
29
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
+
* In-workflow API surface, exposed as `Durable.workflow`. Every method
|
|
31
|
+
* is called **inside** a workflow function and participates in
|
|
32
|
+
* deterministic replay — results are persisted and returned instantly
|
|
33
|
+
* on recovery without re-executing side effects.
|
|
30
34
|
*
|
|
31
|
-
* ##
|
|
35
|
+
* ## Primitives
|
|
32
36
|
*
|
|
33
37
|
* | Method | Purpose |
|
|
34
38
|
* |--------|---------|
|
|
35
|
-
* | {@link proxyActivities} |
|
|
36
|
-
* | {@link
|
|
37
|
-
* | {@link
|
|
38
|
-
* | {@link signal} |
|
|
39
|
-
* | {@link
|
|
40
|
-
* | {@link startChild} |
|
|
41
|
-
* | {@link
|
|
42
|
-
* | {@link
|
|
43
|
-
* | {@link
|
|
44
|
-
* | {@link
|
|
45
|
-
*
|
|
46
|
-
* ## Data & Observability
|
|
47
|
-
*
|
|
48
|
-
* | Method | Purpose |
|
|
49
|
-
* |--------|---------|
|
|
50
|
-
* | {@link search} | Read/write flat HASH key-value data |
|
|
51
|
-
* | {@link enrich} | One-shot HASH enrichment |
|
|
52
|
-
* | {@link entity} | Structured JSONB document storage |
|
|
53
|
-
* | {@link emit} | Publish events to the event bus |
|
|
54
|
-
* | {@link trace} | Emit OpenTelemetry trace spans |
|
|
39
|
+
* | {@link proxyActivities} | Execute activities with automatic retry |
|
|
40
|
+
* | {@link sleep} | Durable timer (survives restarts) |
|
|
41
|
+
* | {@link condition} | Pause until a named signal arrives (optional timeout) |
|
|
42
|
+
* | {@link signal} | Deliver data to a waiting `condition` |
|
|
43
|
+
* | {@link executeChild} | Spawn a child workflow and await its result |
|
|
44
|
+
* | {@link startChild} | Fire-and-forget child workflow |
|
|
45
|
+
* | {@link continueAsNew} | Restart with new args (resets history) |
|
|
46
|
+
* | {@link patched} / {@link deprecatePatch} | Safe versioning for in-flight code changes |
|
|
47
|
+
* | {@link CancellationScope} | Shield cleanup code from cancellation |
|
|
48
|
+
* | {@link isCancellation} | Detect `CancelledFailure` errors |
|
|
55
49
|
*
|
|
56
50
|
* ## Utilities
|
|
57
51
|
*
|
|
58
52
|
* | Method | Purpose |
|
|
59
53
|
* |--------|---------|
|
|
60
|
-
* | {@link
|
|
54
|
+
* | {@link workflowInfo} | Access workflow ID, namespace, replay state |
|
|
61
55
|
* | {@link random} | Deterministic pseudo-random numbers |
|
|
56
|
+
* | {@link uuid4} | Deterministic UUID v4 generation |
|
|
62
57
|
* | {@link all} | Workflow-safe `Promise.all` |
|
|
63
|
-
* | {@link didInterrupt} |
|
|
58
|
+
* | {@link didInterrupt} | Detect engine control-flow errors |
|
|
64
59
|
*
|
|
65
60
|
* ## Example
|
|
66
61
|
*
|
|
@@ -69,26 +64,20 @@ const entityMethods_1 = require("./entityMethods");
|
|
|
69
64
|
* import * as activities from './activities';
|
|
70
65
|
*
|
|
71
66
|
* export async function orderWorkflow(orderId: string): Promise<string> {
|
|
72
|
-
* // Proxy activities for durable execution
|
|
73
67
|
* const { validateOrder, processPayment, sendReceipt } =
|
|
74
68
|
* Durable.workflow.proxyActivities<typeof activities>({
|
|
75
69
|
* activities,
|
|
76
|
-
*
|
|
70
|
+
* retry: { maximumAttempts: 3 },
|
|
77
71
|
* });
|
|
78
72
|
*
|
|
79
73
|
* await validateOrder(orderId);
|
|
80
|
-
*
|
|
81
|
-
* // Durable sleep (survives restarts)
|
|
82
|
-
* await Durable.workflow.sleepFor('5 seconds');
|
|
83
|
-
*
|
|
74
|
+
* await Durable.workflow.sleep('5 seconds');
|
|
84
75
|
* const receipt = await processPayment(orderId);
|
|
85
76
|
*
|
|
86
|
-
* //
|
|
87
|
-
* await Durable.workflow.
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* const approval = await Durable.workflow.waitFor<{ ok: boolean }>('approve');
|
|
91
|
-
* if (!approval.ok) return 'cancelled';
|
|
77
|
+
* // Wait for external approval signal (with 1-hour timeout)
|
|
78
|
+
* const approval = await Durable.workflow.condition<{ ok: boolean }>('approve', '1 hour');
|
|
79
|
+
* if (!approval) return 'timed-out';
|
|
80
|
+
* if (!approval.ok) return 'rejected';
|
|
92
81
|
*
|
|
93
82
|
* await sendReceipt(orderId, receipt);
|
|
94
83
|
* return receipt;
|
|
@@ -117,26 +106,32 @@ class WorkflowService {
|
|
|
117
106
|
});
|
|
118
107
|
}
|
|
119
108
|
}
|
|
120
|
-
WorkflowService.
|
|
109
|
+
WorkflowService.workflowInfo = workflowInfo_1.workflowInfo;
|
|
121
110
|
WorkflowService.didRun = didRun_1.didRun;
|
|
122
111
|
WorkflowService.isSideEffectAllowed = isSideEffectAllowed_1.isSideEffectAllowed;
|
|
123
112
|
WorkflowService.trace = trace_1.trace;
|
|
124
113
|
WorkflowService.enrich = enrich_1.enrich;
|
|
125
114
|
WorkflowService.emit = emit_1.emit;
|
|
126
|
-
WorkflowService.
|
|
127
|
-
WorkflowService.
|
|
128
|
-
WorkflowService.startChild = execChild_1.startChild;
|
|
115
|
+
WorkflowService.executeChild = executeChild_1.executeChild;
|
|
116
|
+
WorkflowService.startChild = executeChild_1.startChild;
|
|
129
117
|
WorkflowService.execHook = execHook_1.execHook;
|
|
130
118
|
WorkflowService.execHookBatch = execHookBatch_1.execHookBatch;
|
|
131
119
|
WorkflowService.proxyActivities = proxyActivities_1.proxyActivities;
|
|
132
120
|
WorkflowService.search = searchMethods_1.search;
|
|
133
121
|
WorkflowService.entity = entityMethods_1.entity;
|
|
134
122
|
WorkflowService.random = random_1.random;
|
|
123
|
+
WorkflowService.uuid4 = uuid4_1.uuid4;
|
|
135
124
|
WorkflowService.signal = signal_1.signal;
|
|
136
125
|
WorkflowService.hook = hook_1.hook;
|
|
137
126
|
WorkflowService.didInterrupt = interruption_1.didInterrupt;
|
|
138
|
-
WorkflowService.
|
|
127
|
+
WorkflowService.terminate = terminate_1.terminate;
|
|
139
128
|
WorkflowService.all = all_1.all;
|
|
140
|
-
WorkflowService.
|
|
141
|
-
WorkflowService.
|
|
129
|
+
WorkflowService.sleep = sleep_1.sleep;
|
|
130
|
+
WorkflowService.condition = condition_1.condition;
|
|
131
|
+
WorkflowService.continueAsNew = continueAsNew_1.continueAsNew;
|
|
132
|
+
WorkflowService.patched = patched_1.patched;
|
|
133
|
+
WorkflowService.deprecatePatch = patched_1.deprecatePatch;
|
|
134
|
+
WorkflowService.CancellationScope = cancellationScope_1.CancellationScope;
|
|
135
|
+
WorkflowService.CancelledFailure = cancellationScope_1.CancelledFailure;
|
|
136
|
+
WorkflowService.isCancellation = cancellationScope_1.isCancellation;
|
|
142
137
|
exports.WorkflowService = WorkflowService;
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* control-flow signal rather than a genuine application error.
|
|
4
4
|
*
|
|
5
5
|
* Durable uses thrown errors internally to suspend workflow execution
|
|
6
|
-
* for durable operations like `
|
|
7
|
-
* and `
|
|
6
|
+
* for durable operations like `sleep`, `condition`, `proxyActivities`,
|
|
7
|
+
* and `executeChild`. These errors must be re-thrown (not swallowed) so
|
|
8
8
|
* the engine can persist state and schedule the next step.
|
|
9
9
|
*
|
|
10
10
|
* **Always use `didInterrupt` in `catch` blocks inside workflow
|
|
@@ -12,9 +12,10 @@
|
|
|
12
12
|
*
|
|
13
13
|
* ## Recognized Error Types
|
|
14
14
|
*
|
|
15
|
-
* `DurableChildError`, `
|
|
16
|
-
* `
|
|
17
|
-
* `DurableTimeoutError`, `DurableWaitForError`,
|
|
15
|
+
* `DurableChildError`, `DurableContinueAsNewError`, `DurableFatalError`,
|
|
16
|
+
* `DurableMaxedError`, `DurableProxyError`, `DurableRetryError`,
|
|
17
|
+
* `DurableSleepError`, `DurableTimeoutError`, `DurableWaitForError`,
|
|
18
|
+
* `DurableWaitForAllError`, `CancelledFailure`
|
|
18
19
|
*
|
|
19
20
|
* ## Examples
|
|
20
21
|
*
|
|
@@ -39,7 +40,7 @@
|
|
|
39
40
|
*
|
|
40
41
|
* ```typescript
|
|
41
42
|
* // Common pattern in interceptors
|
|
42
|
-
* const interceptor:
|
|
43
|
+
* const interceptor: WorkflowInboundCallsInterceptor = {
|
|
43
44
|
* async execute(ctx, next) {
|
|
44
45
|
* try {
|
|
45
46
|
* return await next();
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.didInterrupt = void 0;
|
|
4
4
|
const errors_1 = require("../../../modules/errors");
|
|
5
|
+
const cancellationScope_1 = require("./cancellationScope");
|
|
5
6
|
/**
|
|
6
7
|
* Type guard that returns `true` if an error is a Durable engine
|
|
7
8
|
* control-flow signal rather than a genuine application error.
|
|
8
9
|
*
|
|
9
10
|
* Durable uses thrown errors internally to suspend workflow execution
|
|
10
|
-
* for durable operations like `
|
|
11
|
-
* and `
|
|
11
|
+
* for durable operations like `sleep`, `condition`, `proxyActivities`,
|
|
12
|
+
* and `executeChild`. These errors must be re-thrown (not swallowed) so
|
|
12
13
|
* the engine can persist state and schedule the next step.
|
|
13
14
|
*
|
|
14
15
|
* **Always use `didInterrupt` in `catch` blocks inside workflow
|
|
@@ -16,9 +17,10 @@ const errors_1 = require("../../../modules/errors");
|
|
|
16
17
|
*
|
|
17
18
|
* ## Recognized Error Types
|
|
18
19
|
*
|
|
19
|
-
* `DurableChildError`, `
|
|
20
|
-
* `
|
|
21
|
-
* `DurableTimeoutError`, `DurableWaitForError`,
|
|
20
|
+
* `DurableChildError`, `DurableContinueAsNewError`, `DurableFatalError`,
|
|
21
|
+
* `DurableMaxedError`, `DurableProxyError`, `DurableRetryError`,
|
|
22
|
+
* `DurableSleepError`, `DurableTimeoutError`, `DurableWaitForError`,
|
|
23
|
+
* `DurableWaitForAllError`, `CancelledFailure`
|
|
22
24
|
*
|
|
23
25
|
* ## Examples
|
|
24
26
|
*
|
|
@@ -43,7 +45,7 @@ const errors_1 = require("../../../modules/errors");
|
|
|
43
45
|
*
|
|
44
46
|
* ```typescript
|
|
45
47
|
* // Common pattern in interceptors
|
|
46
|
-
* const interceptor:
|
|
48
|
+
* const interceptor: WorkflowInboundCallsInterceptor = {
|
|
47
49
|
* async execute(ctx, next) {
|
|
48
50
|
* try {
|
|
49
51
|
* return await next();
|
|
@@ -64,6 +66,7 @@ const errors_1 = require("../../../modules/errors");
|
|
|
64
66
|
*/
|
|
65
67
|
function didInterrupt(error) {
|
|
66
68
|
return (error instanceof errors_1.DurableChildError ||
|
|
69
|
+
error instanceof errors_1.DurableContinueAsNewError ||
|
|
67
70
|
error instanceof errors_1.DurableFatalError ||
|
|
68
71
|
error instanceof errors_1.DurableMaxedError ||
|
|
69
72
|
error instanceof errors_1.DurableProxyError ||
|
|
@@ -71,6 +74,7 @@ function didInterrupt(error) {
|
|
|
71
74
|
error instanceof errors_1.DurableSleepError ||
|
|
72
75
|
error instanceof errors_1.DurableTimeoutError ||
|
|
73
76
|
error instanceof errors_1.DurableWaitForError ||
|
|
74
|
-
error instanceof errors_1.DurableWaitForAllError
|
|
77
|
+
error instanceof errors_1.DurableWaitForAllError ||
|
|
78
|
+
error instanceof cancellationScope_1.CancelledFailure);
|
|
75
79
|
}
|
|
76
80
|
exports.didInterrupt = didInterrupt;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enables safe code changes to running workflows by branching on a named
|
|
3
|
+
* change marker. On first execution of a new workflow, `patched` records
|
|
4
|
+
* the marker and returns `true` — the workflow takes the new code path.
|
|
5
|
+
* On replay of a workflow that was started **before** the patch existed,
|
|
6
|
+
* no marker is found and `patched` returns `false` — the old code path
|
|
7
|
+
* is followed.
|
|
8
|
+
*
|
|
9
|
+
* Markers are accumulated in the workflow context and written to the job
|
|
10
|
+
* hash by the engine (via the YAML schema's `job.maps`) when the worker
|
|
11
|
+
* responds — no direct hash writes from the worker.
|
|
12
|
+
*
|
|
13
|
+
* `patched` does **not** increment the execution counter, so it can be
|
|
14
|
+
* inserted into existing workflow code without shifting the replay
|
|
15
|
+
* positions of other durable operations.
|
|
16
|
+
*
|
|
17
|
+
* ## Lifecycle
|
|
18
|
+
*
|
|
19
|
+
* 1. **Add the patch:** wrap the new behavior with `if (await patched('id'))`.
|
|
20
|
+
* Keep the old behavior in the `else` branch.
|
|
21
|
+
* 2. **Wait for drain:** once all workflows started before the patch have
|
|
22
|
+
* completed, the `else` branch is dead code.
|
|
23
|
+
* 3. **Deprecate:** replace `patched` with `deprecatePatch` and remove the
|
|
24
|
+
* `else` branch.
|
|
25
|
+
* 4. **Clean up:** remove both `deprecatePatch` and the `if` wrapper,
|
|
26
|
+
* leaving only the new code.
|
|
27
|
+
*
|
|
28
|
+
* ## Examples
|
|
29
|
+
*
|
|
30
|
+
* ```typescript
|
|
31
|
+
* import { Durable } from '@hotmeshio/hotmesh';
|
|
32
|
+
*
|
|
33
|
+
* export async function orderWorkflow(orderId: string): Promise<string> {
|
|
34
|
+
* const acts = Durable.workflow.proxyActivities<typeof activities>({
|
|
35
|
+
* activities,
|
|
36
|
+
* retry: { maximumAttempts: 3 },
|
|
37
|
+
* });
|
|
38
|
+
*
|
|
39
|
+
* if (await Durable.workflow.patched('v2-validation')) {
|
|
40
|
+
* // New path: stricter validation
|
|
41
|
+
* await acts.validateOrderV2(orderId);
|
|
42
|
+
* } else {
|
|
43
|
+
* // Old path: legacy validation (for in-flight workflows)
|
|
44
|
+
* await acts.validateOrder(orderId);
|
|
45
|
+
* }
|
|
46
|
+
*
|
|
47
|
+
* return await acts.processOrder(orderId);
|
|
48
|
+
* }
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* @param {string} changeId - A unique, stable identifier for this code change.
|
|
52
|
+
* Must not be reused across different changes.
|
|
53
|
+
* @returns {Promise<boolean>} `true` for new workflows (take new path),
|
|
54
|
+
* `false` for pre-patch workflows being replayed (take old path).
|
|
55
|
+
*/
|
|
56
|
+
export declare function patched(changeId: string): Promise<boolean>;
|
|
57
|
+
/**
|
|
58
|
+
* Declares that all workflows started before a given patch have drained
|
|
59
|
+
* and the old code path can be removed. This is a **no-op** at runtime —
|
|
60
|
+
* it exists purely as a migration signal in source code.
|
|
61
|
+
*
|
|
62
|
+
* ## Migration Steps
|
|
63
|
+
*
|
|
64
|
+
* 1. Replace `if (await patched('id')) { new } else { old }` with
|
|
65
|
+
* `deprecatePatch('id'); new`.
|
|
66
|
+
* 2. Deploy and verify.
|
|
67
|
+
* 3. In a subsequent release, remove both `deprecatePatch('id')` and
|
|
68
|
+
* the surrounding wrapper, leaving only the new code.
|
|
69
|
+
*
|
|
70
|
+
* @param {string} _changeId - The change ID being deprecated (unused at runtime).
|
|
71
|
+
*/
|
|
72
|
+
export declare function deprecatePatch(_changeId: string): void;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deprecatePatch = exports.patched = void 0;
|
|
4
|
+
const common_1 = require("./common");
|
|
5
|
+
/**
|
|
6
|
+
* Enables safe code changes to running workflows by branching on a named
|
|
7
|
+
* change marker. On first execution of a new workflow, `patched` records
|
|
8
|
+
* the marker and returns `true` — the workflow takes the new code path.
|
|
9
|
+
* On replay of a workflow that was started **before** the patch existed,
|
|
10
|
+
* no marker is found and `patched` returns `false` — the old code path
|
|
11
|
+
* is followed.
|
|
12
|
+
*
|
|
13
|
+
* Markers are accumulated in the workflow context and written to the job
|
|
14
|
+
* hash by the engine (via the YAML schema's `job.maps`) when the worker
|
|
15
|
+
* responds — no direct hash writes from the worker.
|
|
16
|
+
*
|
|
17
|
+
* `patched` does **not** increment the execution counter, so it can be
|
|
18
|
+
* inserted into existing workflow code without shifting the replay
|
|
19
|
+
* positions of other durable operations.
|
|
20
|
+
*
|
|
21
|
+
* ## Lifecycle
|
|
22
|
+
*
|
|
23
|
+
* 1. **Add the patch:** wrap the new behavior with `if (await patched('id'))`.
|
|
24
|
+
* Keep the old behavior in the `else` branch.
|
|
25
|
+
* 2. **Wait for drain:** once all workflows started before the patch have
|
|
26
|
+
* completed, the `else` branch is dead code.
|
|
27
|
+
* 3. **Deprecate:** replace `patched` with `deprecatePatch` and remove the
|
|
28
|
+
* `else` branch.
|
|
29
|
+
* 4. **Clean up:** remove both `deprecatePatch` and the `if` wrapper,
|
|
30
|
+
* leaving only the new code.
|
|
31
|
+
*
|
|
32
|
+
* ## Examples
|
|
33
|
+
*
|
|
34
|
+
* ```typescript
|
|
35
|
+
* import { Durable } from '@hotmeshio/hotmesh';
|
|
36
|
+
*
|
|
37
|
+
* export async function orderWorkflow(orderId: string): Promise<string> {
|
|
38
|
+
* const acts = Durable.workflow.proxyActivities<typeof activities>({
|
|
39
|
+
* activities,
|
|
40
|
+
* retry: { maximumAttempts: 3 },
|
|
41
|
+
* });
|
|
42
|
+
*
|
|
43
|
+
* if (await Durable.workflow.patched('v2-validation')) {
|
|
44
|
+
* // New path: stricter validation
|
|
45
|
+
* await acts.validateOrderV2(orderId);
|
|
46
|
+
* } else {
|
|
47
|
+
* // Old path: legacy validation (for in-flight workflows)
|
|
48
|
+
* await acts.validateOrder(orderId);
|
|
49
|
+
* }
|
|
50
|
+
*
|
|
51
|
+
* return await acts.processOrder(orderId);
|
|
52
|
+
* }
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* @param {string} changeId - A unique, stable identifier for this code change.
|
|
56
|
+
* Must not be reused across different changes.
|
|
57
|
+
* @returns {Promise<boolean>} `true` for new workflows (take new path),
|
|
58
|
+
* `false` for pre-patch workflows being replayed (take old path).
|
|
59
|
+
*/
|
|
60
|
+
async function patched(changeId) {
|
|
61
|
+
const store = common_1.asyncLocalStorage.getStore();
|
|
62
|
+
const replay = store.get('replay');
|
|
63
|
+
const workflowDimension = store.get('workflowDimension') ?? '';
|
|
64
|
+
const patchKey = `-patch${workflowDimension}-${changeId}-`;
|
|
65
|
+
// Marker exists from a previous execution — take new path
|
|
66
|
+
if (patchKey in replay) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
// Marker not found. Distinguish first execution from pre-patch replay
|
|
70
|
+
// by checking for non-patch replay entries. On first execution, no
|
|
71
|
+
// durable operations have completed yet, so only patch markers (from
|
|
72
|
+
// earlier patched() calls in this same execution) can exist.
|
|
73
|
+
const patchPrefix = `-patch${workflowDimension}-`;
|
|
74
|
+
const hasNonPatchEntries = Object.keys(replay).some((key) => !key.startsWith(patchPrefix));
|
|
75
|
+
if (hasNonPatchEntries) {
|
|
76
|
+
// Pre-patch workflow: replay has entries from prior operations but
|
|
77
|
+
// no marker for this change — follow the old code path
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
// First execution of a new workflow: accumulate the marker in context.
|
|
81
|
+
// The engine writes it to the job hash via the YAML schema's job.maps
|
|
82
|
+
// when the worker responds (for any response code).
|
|
83
|
+
const patchMarkers = store.get('patchMarkers');
|
|
84
|
+
patchMarkers[patchKey] = common_1.SerializerService.toString(true);
|
|
85
|
+
// Update in-memory replay so subsequent patched() calls in this
|
|
86
|
+
// execution see the marker without waiting for the engine round-trip
|
|
87
|
+
replay[patchKey] = patchMarkers[patchKey];
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
exports.patched = patched;
|
|
91
|
+
/**
|
|
92
|
+
* Declares that all workflows started before a given patch have drained
|
|
93
|
+
* and the old code path can be removed. This is a **no-op** at runtime —
|
|
94
|
+
* it exists purely as a migration signal in source code.
|
|
95
|
+
*
|
|
96
|
+
* ## Migration Steps
|
|
97
|
+
*
|
|
98
|
+
* 1. Replace `if (await patched('id')) { new } else { old }` with
|
|
99
|
+
* `deprecatePatch('id'); new`.
|
|
100
|
+
* 2. Deploy and verify.
|
|
101
|
+
* 3. In a subsequent release, remove both `deprecatePatch('id')` and
|
|
102
|
+
* the surrounding wrapper, leaving only the new code.
|
|
103
|
+
*
|
|
104
|
+
* @param {string} _changeId - The change ID being deprecated (unused at runtime).
|
|
105
|
+
*/
|
|
106
|
+
function deprecatePatch(_changeId) {
|
|
107
|
+
// No-op: all pre-patch workflows have completed.
|
|
108
|
+
// Safe to remove the old code path.
|
|
109
|
+
}
|
|
110
|
+
exports.deprecatePatch = deprecatePatch;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { ActivityConfig, ProxyType, DurableProxyErrorType } from './common';
|
|
2
|
-
import {
|
|
2
|
+
import { workflowInfo } from './workflowInfo';
|
|
3
3
|
/**
|
|
4
4
|
* Constructs payload for spawning a proxyActivity job.
|
|
5
5
|
* @private
|
|
6
6
|
*/
|
|
7
|
-
declare function getProxyInterruptPayload(context: ReturnType<typeof
|
|
7
|
+
declare function getProxyInterruptPayload(context: ReturnType<typeof workflowInfo>, activityName: string, execIndex: number, args: any[], options?: ActivityConfig): DurableProxyErrorType;
|
|
8
8
|
/**
|
|
9
9
|
* Wraps a single activity in a proxy, orchestrating its execution and replay.
|
|
10
10
|
* @private
|
|
@@ -47,7 +47,7 @@ declare function wrapActivity<T>(activityName: string, options?: ActivityConfig)
|
|
|
47
47
|
* const { validateOrder, chargePayment, sendConfirmation } =
|
|
48
48
|
* Durable.workflow.proxyActivities<typeof activities>({
|
|
49
49
|
* activities,
|
|
50
|
-
*
|
|
50
|
+
* retry: {
|
|
51
51
|
* maximumAttempts: 3,
|
|
52
52
|
* backoffCoefficient: 2,
|
|
53
53
|
* maximumInterval: '30s',
|
|
@@ -72,7 +72,7 @@ declare function wrapActivity<T>(activityName: string, options?: ActivityConfig)
|
|
|
72
72
|
* const { refundPayment } =
|
|
73
73
|
* Durable.workflow.proxyActivities<PaymentActivities>({
|
|
74
74
|
* taskQueue: 'payments',
|
|
75
|
-
*
|
|
75
|
+
* retry: { maximumAttempts: 5 },
|
|
76
76
|
* });
|
|
77
77
|
*
|
|
78
78
|
* await refundPayment(txId);
|
|
@@ -81,13 +81,13 @@ declare function wrapActivity<T>(activityName: string, options?: ActivityConfig)
|
|
|
81
81
|
*
|
|
82
82
|
* ```typescript
|
|
83
83
|
* // Interceptor with shared activity pool
|
|
84
|
-
* const auditInterceptor:
|
|
84
|
+
* const auditInterceptor: WorkflowInboundCallsInterceptor = {
|
|
85
85
|
* async execute(ctx, next) {
|
|
86
86
|
* const { auditLog } = Durable.workflow.proxyActivities<{
|
|
87
87
|
* auditLog: (id: string, action: string) => Promise<void>;
|
|
88
88
|
* }>({
|
|
89
89
|
* taskQueue: 'shared-audit',
|
|
90
|
-
*
|
|
90
|
+
* retry: { maximumAttempts: 3 },
|
|
91
91
|
* });
|
|
92
92
|
*
|
|
93
93
|
* await auditLog(ctx.get('workflowId'), 'started');
|
|
@@ -102,7 +102,7 @@ declare function wrapActivity<T>(activityName: string, options?: ActivityConfig)
|
|
|
102
102
|
* // Graceful error handling (no throw)
|
|
103
103
|
* const { riskyOperation } = Durable.workflow.proxyActivities<typeof activities>({
|
|
104
104
|
* activities,
|
|
105
|
-
*
|
|
105
|
+
* retry: { maximumAttempts: 1, throwOnError: false },
|
|
106
106
|
* });
|
|
107
107
|
*
|
|
108
108
|
* const result = await riskyOperation();
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getProxyInterruptPayload = exports.wrapActivity = exports.proxyActivities = void 0;
|
|
4
4
|
const common_1 = require("./common");
|
|
5
|
-
const
|
|
5
|
+
const cancellationScope_1 = require("./cancellationScope");
|
|
6
|
+
const workflowInfo_1 = require("./workflowInfo");
|
|
6
7
|
const didRun_1 = require("./didRun");
|
|
7
8
|
/**
|
|
8
9
|
* Constructs payload for spawning a proxyActivity job.
|
|
@@ -16,11 +17,20 @@ function getProxyInterruptPayload(context, activityName, execIndex, args, option
|
|
|
16
17
|
: `${taskQueue}-activity`;
|
|
17
18
|
const activityJobId = `-${workflowId}-$${activityName}${workflowDimension}-${execIndex}`;
|
|
18
19
|
let maximumInterval;
|
|
19
|
-
if (options?.
|
|
20
|
-
maximumInterval = (0, common_1.s)(options.
|
|
20
|
+
if (options?.retry?.maximumInterval) {
|
|
21
|
+
maximumInterval = (0, common_1.s)(options.retry.maximumInterval);
|
|
22
|
+
}
|
|
23
|
+
let initialInterval;
|
|
24
|
+
if (options?.retry?.initialInterval) {
|
|
25
|
+
initialInterval = (0, common_1.s)(options.retry.initialInterval);
|
|
26
|
+
}
|
|
27
|
+
let startToCloseTimeout;
|
|
28
|
+
if (options?.startToCloseTimeout) {
|
|
29
|
+
startToCloseTimeout = (0, common_1.s)(options.startToCloseTimeout);
|
|
21
30
|
}
|
|
22
31
|
return {
|
|
23
32
|
arguments: args,
|
|
33
|
+
headers: options?.headers ?? undefined,
|
|
24
34
|
workflowDimension,
|
|
25
35
|
index: execIndex,
|
|
26
36
|
originJobId: originJobId || workflowId,
|
|
@@ -29,9 +39,11 @@ function getProxyInterruptPayload(context, activityName, execIndex, args, option
|
|
|
29
39
|
workflowTopic: activityTopic,
|
|
30
40
|
activityName,
|
|
31
41
|
expire: options?.expire ?? expire,
|
|
32
|
-
backoffCoefficient: options?.
|
|
33
|
-
|
|
42
|
+
backoffCoefficient: options?.retry?.backoffCoefficient ?? undefined,
|
|
43
|
+
initialInterval: initialInterval ?? undefined,
|
|
44
|
+
maximumAttempts: options?.retry?.maximumAttempts ?? undefined,
|
|
34
45
|
maximumInterval: maximumInterval ?? undefined,
|
|
46
|
+
startToCloseTimeout: startToCloseTimeout ?? undefined,
|
|
35
47
|
};
|
|
36
48
|
}
|
|
37
49
|
exports.getProxyInterruptPayload = getProxyInterruptPayload;
|
|
@@ -43,7 +55,9 @@ function wrapActivity(activityName, options) {
|
|
|
43
55
|
return async function (...args) {
|
|
44
56
|
// Increment counter first for deterministic replay ordering
|
|
45
57
|
const [didRunAlready, execIndex, result] = await (0, didRun_1.didRun)('proxy');
|
|
46
|
-
|
|
58
|
+
// Check cancellation AFTER counter increment to preserve replay positions
|
|
59
|
+
(0, cancellationScope_1.checkCancellation)();
|
|
60
|
+
const context = (0, workflowInfo_1.workflowInfo)();
|
|
47
61
|
const { interruptionRegistry } = context;
|
|
48
62
|
// Build activityCtx so interceptors can inspect/modify args
|
|
49
63
|
const activityCtx = { activityName, args, options };
|
|
@@ -52,8 +66,19 @@ function wrapActivity(activityName, options) {
|
|
|
52
66
|
// from activityCtx so "before" interceptors can modify them.
|
|
53
67
|
const coreFunction = async () => {
|
|
54
68
|
if (didRunAlready) {
|
|
69
|
+
// Emit RETURN span in debug mode
|
|
70
|
+
if (common_1.DurableTelemetryService.isVerbose() && result) {
|
|
71
|
+
const { workflowTrace, workflowSpan } = context;
|
|
72
|
+
if (workflowTrace && workflowSpan && result.ac && result.au) {
|
|
73
|
+
common_1.DurableTelemetryService.emitDurationSpan(workflowTrace, workflowSpan, `RETURN/proxy/${activityName}/${execIndex}`, common_1.DurableTelemetryService.parseTimestamp(result.ac), common_1.DurableTelemetryService.parseTimestamp(result.au), {
|
|
74
|
+
'durable.operation.type': 'proxy',
|
|
75
|
+
'durable.activity.name': activityName,
|
|
76
|
+
'durable.exec.index': execIndex,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
55
80
|
if (result?.$error) {
|
|
56
|
-
if (options?.
|
|
81
|
+
if (activityCtx.options?.retry?.throwOnError !== false) {
|
|
57
82
|
const code = result.$error.code;
|
|
58
83
|
const message = result.$error.message;
|
|
59
84
|
const stack = result.$error.stack;
|
|
@@ -74,7 +99,18 @@ function wrapActivity(activityName, options) {
|
|
|
74
99
|
}
|
|
75
100
|
return result.data;
|
|
76
101
|
}
|
|
77
|
-
|
|
102
|
+
// Emit DISPATCH span in debug mode
|
|
103
|
+
if (common_1.DurableTelemetryService.isVerbose()) {
|
|
104
|
+
const { workflowTrace, workflowSpan } = context;
|
|
105
|
+
if (workflowTrace && workflowSpan) {
|
|
106
|
+
common_1.DurableTelemetryService.emitPointSpan(workflowTrace, workflowSpan, `DISPATCH/proxy/${activityName}/${execIndex}`, {
|
|
107
|
+
'durable.operation.type': 'proxy',
|
|
108
|
+
'durable.activity.name': activityName,
|
|
109
|
+
'durable.exec.index': execIndex,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const interruptionMessage = getProxyInterruptPayload(context, activityName, execIndex, activityCtx.args, activityCtx.options);
|
|
78
114
|
interruptionRegistry.push({
|
|
79
115
|
code: common_1.HMSH_CODE_DURABLE_PROXY,
|
|
80
116
|
type: 'DurableProxyError',
|
|
@@ -86,8 +122,8 @@ function wrapActivity(activityName, options) {
|
|
|
86
122
|
// Run through interceptor chain if interceptors exist
|
|
87
123
|
const store = common_1.asyncLocalStorage.getStore();
|
|
88
124
|
const interceptorService = store?.get('activityInterceptorService');
|
|
89
|
-
if (interceptorService?.
|
|
90
|
-
return await interceptorService.
|
|
125
|
+
if (interceptorService?.outbound?.length > 0) {
|
|
126
|
+
return await interceptorService.executeOutboundChain(activityCtx, store, coreFunction);
|
|
91
127
|
}
|
|
92
128
|
return await coreFunction();
|
|
93
129
|
};
|
|
@@ -130,7 +166,7 @@ exports.wrapActivity = wrapActivity;
|
|
|
130
166
|
* const { validateOrder, chargePayment, sendConfirmation } =
|
|
131
167
|
* Durable.workflow.proxyActivities<typeof activities>({
|
|
132
168
|
* activities,
|
|
133
|
-
*
|
|
169
|
+
* retry: {
|
|
134
170
|
* maximumAttempts: 3,
|
|
135
171
|
* backoffCoefficient: 2,
|
|
136
172
|
* maximumInterval: '30s',
|
|
@@ -155,7 +191,7 @@ exports.wrapActivity = wrapActivity;
|
|
|
155
191
|
* const { refundPayment } =
|
|
156
192
|
* Durable.workflow.proxyActivities<PaymentActivities>({
|
|
157
193
|
* taskQueue: 'payments',
|
|
158
|
-
*
|
|
194
|
+
* retry: { maximumAttempts: 5 },
|
|
159
195
|
* });
|
|
160
196
|
*
|
|
161
197
|
* await refundPayment(txId);
|
|
@@ -164,13 +200,13 @@ exports.wrapActivity = wrapActivity;
|
|
|
164
200
|
*
|
|
165
201
|
* ```typescript
|
|
166
202
|
* // Interceptor with shared activity pool
|
|
167
|
-
* const auditInterceptor:
|
|
203
|
+
* const auditInterceptor: WorkflowInboundCallsInterceptor = {
|
|
168
204
|
* async execute(ctx, next) {
|
|
169
205
|
* const { auditLog } = Durable.workflow.proxyActivities<{
|
|
170
206
|
* auditLog: (id: string, action: string) => Promise<void>;
|
|
171
207
|
* }>({
|
|
172
208
|
* taskQueue: 'shared-audit',
|
|
173
|
-
*
|
|
209
|
+
* retry: { maximumAttempts: 3 },
|
|
174
210
|
* });
|
|
175
211
|
*
|
|
176
212
|
* await auditLog(ctx.get('workflowId'), 'started');
|
|
@@ -185,7 +221,7 @@ exports.wrapActivity = wrapActivity;
|
|
|
185
221
|
* // Graceful error handling (no throw)
|
|
186
222
|
* const { riskyOperation } = Durable.workflow.proxyActivities<typeof activities>({
|
|
187
223
|
* activities,
|
|
188
|
-
*
|
|
224
|
+
* retry: { maximumAttempts: 1, throwOnError: false },
|
|
189
225
|
* });
|
|
190
226
|
*
|
|
191
227
|
* const result = await riskyOperation();
|
|
@@ -48,6 +48,13 @@ import { Search } from './common';
|
|
|
48
48
|
* }
|
|
49
49
|
* ```
|
|
50
50
|
*
|
|
51
|
+
* **Not available with `workerCredentials`.** This method writes directly
|
|
52
|
+
* to the `jobs` and `jobs_attributes` tables, bypassing the SECURITY
|
|
53
|
+
* DEFINER stored procedures that scoped worker roles are restricted to.
|
|
54
|
+
* Workers connecting with `workerCredentials` will receive a permission
|
|
55
|
+
* error. Use `search()` only in workflows running with full database
|
|
56
|
+
* credentials.
|
|
57
|
+
*
|
|
51
58
|
* @returns {Promise<Search>} A search session scoped to the current workflow job.
|
|
52
59
|
*/
|
|
53
60
|
export declare function search(): Promise<Search>;
|