@hotmeshio/hotmesh 0.1.10 → 0.1.11
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/build/modules/errors.d.ts +3 -0
- package/build/modules/errors.js +3 -0
- package/build/package.json +1 -1
- package/build/services/durable/client.d.ts +6 -1
- package/build/services/durable/client.js +18 -7
- package/build/services/durable/schemas/factory.js +51 -0
- package/build/services/durable/worker.js +3 -0
- package/build/services/durable/workflow.js +3 -0
- package/build/types/durable.d.ts +2 -0
- package/build/types/error.d.ts +3 -0
- package/package.json +1 -1
- package/types/durable.ts +3 -0
- package/types/error.ts +3 -0
|
@@ -27,6 +27,7 @@ declare class DurableProxyError extends Error {
|
|
|
27
27
|
maximumInterval: number;
|
|
28
28
|
originJobId: string | null;
|
|
29
29
|
parentWorkflowId: string;
|
|
30
|
+
expire: number;
|
|
30
31
|
workflowDimension: string;
|
|
31
32
|
workflowId: string;
|
|
32
33
|
workflowTopic: string;
|
|
@@ -37,6 +38,8 @@ declare class DurableChildError extends Error {
|
|
|
37
38
|
arguments: string[];
|
|
38
39
|
backoffCoefficient: number;
|
|
39
40
|
code: number;
|
|
41
|
+
expire: number;
|
|
42
|
+
signalIn: boolean;
|
|
40
43
|
workflowDimension: string;
|
|
41
44
|
index: number;
|
|
42
45
|
maximumAttempts: number;
|
package/build/modules/errors.js
CHANGED
|
@@ -33,6 +33,7 @@ class DurableProxyError extends Error {
|
|
|
33
33
|
this.workflowId = params.workflowId;
|
|
34
34
|
this.workflowTopic = params.workflowTopic;
|
|
35
35
|
this.parentWorkflowId = params.parentWorkflowId;
|
|
36
|
+
this.expire = params.expire;
|
|
36
37
|
this.originJobId = params.originJobId;
|
|
37
38
|
this.index = params.index;
|
|
38
39
|
this.activityName = params.activityName;
|
|
@@ -51,6 +52,8 @@ class DurableChildError extends Error {
|
|
|
51
52
|
this.workflowId = params.workflowId;
|
|
52
53
|
this.workflowTopic = params.workflowTopic;
|
|
53
54
|
this.parentWorkflowId = params.parentWorkflowId;
|
|
55
|
+
this.expire = params.expire;
|
|
56
|
+
this.signalIn = params.signalIn;
|
|
54
57
|
this.originJobId = params.originJobId;
|
|
55
58
|
this.index = params.index;
|
|
56
59
|
this.workflowDimension = params.workflowDimension;
|
package/build/package.json
CHANGED
|
@@ -7,7 +7,7 @@ export declare class ClientService {
|
|
|
7
7
|
static topics: string[];
|
|
8
8
|
static instances: Map<string, HotMesh | Promise<HotMesh>>;
|
|
9
9
|
constructor(config: ClientConfig);
|
|
10
|
-
getHotMeshClient: (workflowTopic: string, namespace?: string) => Promise<HotMesh>;
|
|
10
|
+
getHotMeshClient: (workflowTopic: string | null, namespace?: string) => Promise<HotMesh>;
|
|
11
11
|
/**
|
|
12
12
|
* Creates a stream (Redis `XGROUP.CREATE`) where events can be published (XADD).
|
|
13
13
|
* It is possible that the worker that will read from this stream channel
|
|
@@ -38,6 +38,11 @@ export declare class ClientService {
|
|
|
38
38
|
getHandle: (taskQueue: string, workflowName: string, workflowId: string, namespace?: string) => Promise<WorkflowHandleService>;
|
|
39
39
|
search: (taskQueue: string, workflowName: string, namespace: null | string, index: string, ...query: string[]) => Promise<string[]>;
|
|
40
40
|
};
|
|
41
|
+
/**
|
|
42
|
+
* Any point of presence can be used to deploy and activate the HotMesh
|
|
43
|
+
* distributed executable to the active quorum.
|
|
44
|
+
*/
|
|
45
|
+
deployAndActivate(namespace?: string, version?: string): Promise<void>;
|
|
41
46
|
verifyWorkflowActive(hotMesh: HotMesh, appId?: string, count?: number): Promise<boolean>;
|
|
42
47
|
activateWorkflow(hotMesh: HotMesh, appId?: string, version?: string): Promise<void>;
|
|
43
48
|
static shutdown(): Promise<void>;
|
|
@@ -151,6 +151,17 @@ class ClientService {
|
|
|
151
151
|
};
|
|
152
152
|
this.connection = config.connection;
|
|
153
153
|
}
|
|
154
|
+
/**
|
|
155
|
+
* Any point of presence can be used to deploy and activate the HotMesh
|
|
156
|
+
* distributed executable to the active quorum.
|
|
157
|
+
*/
|
|
158
|
+
async deployAndActivate(namespace = factory_1.APP_ID, version = factory_1.APP_VERSION) {
|
|
159
|
+
if (isNaN(Number(version))) {
|
|
160
|
+
throw new Error('Invalid version number');
|
|
161
|
+
}
|
|
162
|
+
const hotMesh = await this.getHotMeshClient('', namespace);
|
|
163
|
+
await this.activateWorkflow(hotMesh, namespace, version);
|
|
164
|
+
}
|
|
154
165
|
async verifyWorkflowActive(hotMesh, appId = factory_1.APP_ID, count = 0) {
|
|
155
166
|
const app = await hotMesh.engine.store.getApp(appId);
|
|
156
167
|
const appVersion = app?.version;
|
|
@@ -166,24 +177,24 @@ class ClientService {
|
|
|
166
177
|
async activateWorkflow(hotMesh, appId = factory_1.APP_ID, version = factory_1.APP_VERSION) {
|
|
167
178
|
const app = await hotMesh.engine.store.getApp(appId);
|
|
168
179
|
const appVersion = app?.version;
|
|
169
|
-
if (
|
|
180
|
+
if (appVersion === version && !app.active) {
|
|
170
181
|
try {
|
|
171
|
-
await hotMesh.deploy((0, factory_1.getWorkflowYAML)(appId, version));
|
|
172
182
|
await hotMesh.activate(version);
|
|
173
183
|
}
|
|
174
184
|
catch (error) {
|
|
175
|
-
hotMesh.engine.logger.error('durable-client-
|
|
176
|
-
...error,
|
|
177
|
-
});
|
|
185
|
+
hotMesh.engine.logger.error('durable-client-activate-err', { error });
|
|
178
186
|
throw error;
|
|
179
187
|
}
|
|
180
188
|
}
|
|
181
|
-
else if (
|
|
189
|
+
else if (isNaN(Number(appVersion)) || appVersion <= version) {
|
|
182
190
|
try {
|
|
191
|
+
await hotMesh.deploy((0, factory_1.getWorkflowYAML)(appId, version));
|
|
183
192
|
await hotMesh.activate(version);
|
|
184
193
|
}
|
|
185
194
|
catch (error) {
|
|
186
|
-
hotMesh.engine.logger.error('durable-client-activate-err', {
|
|
195
|
+
hotMesh.engine.logger.error('durable-client-deploy-activate-err', {
|
|
196
|
+
...error,
|
|
197
|
+
});
|
|
187
198
|
throw error;
|
|
188
199
|
}
|
|
189
200
|
}
|
|
@@ -235,6 +235,10 @@ const getWorkflowYAML = (app, version) => {
|
|
|
235
235
|
type: number
|
|
236
236
|
maximumInterval:
|
|
237
237
|
type: number
|
|
238
|
+
expire:
|
|
239
|
+
type: number
|
|
240
|
+
signalIn:
|
|
241
|
+
type: boolean
|
|
238
242
|
await:
|
|
239
243
|
type: string
|
|
240
244
|
description: when set to false, do not await the child flow's completion
|
|
@@ -338,6 +342,8 @@ const getWorkflowYAML = (app, version) => {
|
|
|
338
342
|
type: number
|
|
339
343
|
expire:
|
|
340
344
|
type: number
|
|
345
|
+
signalIn:
|
|
346
|
+
type: boolean
|
|
341
347
|
parentWorkflowId:
|
|
342
348
|
type: string
|
|
343
349
|
description: used to forge the cleanup key
|
|
@@ -358,6 +364,8 @@ const getWorkflowYAML = (app, version) => {
|
|
|
358
364
|
index: '{worker.output.data.index}'
|
|
359
365
|
originJobId: '{worker.output.data.originJobId}'
|
|
360
366
|
parentWorkflowId: '{worker.output.data.parentWorkflowId}'
|
|
367
|
+
expire: '{worker.output.data.expire}'
|
|
368
|
+
signalIn: '{worker.output.data.signalIn}'
|
|
361
369
|
workflowId: '{worker.output.data.workflowId}'
|
|
362
370
|
workflowName: '{worker.output.data.workflowName}'
|
|
363
371
|
workflowTopic: '{worker.output.data.workflowTopic}'
|
|
@@ -515,6 +523,8 @@ const getWorkflowYAML = (app, version) => {
|
|
|
515
523
|
description: the arguments to pass to the activity
|
|
516
524
|
items:
|
|
517
525
|
type: string
|
|
526
|
+
expire:
|
|
527
|
+
type: number
|
|
518
528
|
backoffCoefficient:
|
|
519
529
|
type: number
|
|
520
530
|
maximumAttempts:
|
|
@@ -530,6 +540,7 @@ const getWorkflowYAML = (app, version) => {
|
|
|
530
540
|
parentWorkflowId: '{worker.output.data.workflowId}'
|
|
531
541
|
workflowId: '{worker.output.data.workflowId}'
|
|
532
542
|
workflowTopic: '{worker.output.data.workflowTopic}'
|
|
543
|
+
expire: '{worker.output.data.expire}'
|
|
533
544
|
backoffCoefficient:
|
|
534
545
|
'@pipe':
|
|
535
546
|
- ['{worker.output.data.backoffCoefficient}','{trigger.output.data.backoffCoefficient}']
|
|
@@ -757,6 +768,17 @@ const getWorkflowYAML = (app, version) => {
|
|
|
757
768
|
- ['{trigger.output.data.maximumInterval}', 120]
|
|
758
769
|
- ['{@logical.or}']
|
|
759
770
|
- ['{@math.min}']
|
|
771
|
+
ender:
|
|
772
|
+
title: Sets job data; ignores the \`Signal In\` Hook Channel which was suppressed
|
|
773
|
+
type: hook
|
|
774
|
+
job:
|
|
775
|
+
maps:
|
|
776
|
+
done: true
|
|
777
|
+
$error: '{worker.output.data.$error}'
|
|
778
|
+
jc: '{$job.metadata.jc}'
|
|
779
|
+
ju:
|
|
780
|
+
'@pipe':
|
|
781
|
+
- ['{@date.toISOXString}']
|
|
760
782
|
|
|
761
783
|
closer:
|
|
762
784
|
title: Closes the \`Signal In\` Hook Channel, so the workflow can exit
|
|
@@ -942,6 +964,11 @@ const getWorkflowYAML = (app, version) => {
|
|
|
942
964
|
maximumInterval:
|
|
943
965
|
type: number
|
|
944
966
|
description: the maximum time in seconds to wait between retries; provides a fixed limit to exponential backoff growth
|
|
967
|
+
expire:
|
|
968
|
+
type: number
|
|
969
|
+
signalIn:
|
|
970
|
+
type: boolean
|
|
971
|
+
description: if false, the spawned child will not support subordinated hooks
|
|
945
972
|
await:
|
|
946
973
|
type: string
|
|
947
974
|
description: when set to false, do not await the child flow's completion
|
|
@@ -969,6 +996,8 @@ const getWorkflowYAML = (app, version) => {
|
|
|
969
996
|
type: string
|
|
970
997
|
originJobId:
|
|
971
998
|
type: string
|
|
999
|
+
expire:
|
|
1000
|
+
type: number
|
|
972
1001
|
backoffCoefficient:
|
|
973
1002
|
type: number
|
|
974
1003
|
maximumAttempts:
|
|
@@ -1042,6 +1071,8 @@ const getWorkflowYAML = (app, version) => {
|
|
|
1042
1071
|
type: number
|
|
1043
1072
|
expire:
|
|
1044
1073
|
type: number
|
|
1074
|
+
signalIn:
|
|
1075
|
+
type: boolean
|
|
1045
1076
|
parentWorkflowId:
|
|
1046
1077
|
type: string
|
|
1047
1078
|
description: used to forge the cleanup key
|
|
@@ -1062,6 +1093,8 @@ const getWorkflowYAML = (app, version) => {
|
|
|
1062
1093
|
index: '{signaler_worker.output.data.index}'
|
|
1063
1094
|
originJobId: '{signaler_worker.output.data.originJobId}'
|
|
1064
1095
|
parentWorkflowId: '{signaler_worker.output.data.parentWorkflowId}'
|
|
1096
|
+
expire: '{signaler_worker.output.data.expire}'
|
|
1097
|
+
signalIn: '{signaler_worker.output.data.signalIn}'
|
|
1065
1098
|
workflowId: '{signaler_worker.output.data.workflowId}'
|
|
1066
1099
|
workflowName: '{signaler_worker.output.data.workflowName}'
|
|
1067
1100
|
workflowTopic: '{signaler_worker.output.data.workflowTopic}'
|
|
@@ -1219,6 +1252,8 @@ const getWorkflowYAML = (app, version) => {
|
|
|
1219
1252
|
description: the arguments to pass to the activity
|
|
1220
1253
|
items:
|
|
1221
1254
|
type: string
|
|
1255
|
+
expire:
|
|
1256
|
+
type: number
|
|
1222
1257
|
backoffCoefficient:
|
|
1223
1258
|
type: number
|
|
1224
1259
|
maximumAttempts:
|
|
@@ -1234,6 +1269,7 @@ const getWorkflowYAML = (app, version) => {
|
|
|
1234
1269
|
parentWorkflowId: '{signaler_worker.output.data.workflowId}'
|
|
1235
1270
|
workflowId: '{signaler_worker.output.data.workflowId}'
|
|
1236
1271
|
workflowTopic: '{signaler_worker.output.data.workflowTopic}'
|
|
1272
|
+
expire: '{signaler_worker.output.data.expire}'
|
|
1237
1273
|
backoffCoefficient:
|
|
1238
1274
|
'@pipe':
|
|
1239
1275
|
- ['{signaler_worker.output.data.backoffCoefficient}','{trigger.output.data.backoffCoefficient}']
|
|
@@ -1479,9 +1515,24 @@ const getWorkflowYAML = (app, version) => {
|
|
|
1479
1515
|
throttler:
|
|
1480
1516
|
- to: worker
|
|
1481
1517
|
worker:
|
|
1518
|
+
- to: ender
|
|
1519
|
+
conditions:
|
|
1520
|
+
code: [200, 596, 597, 598]
|
|
1521
|
+
match:
|
|
1522
|
+
- expected: false
|
|
1523
|
+
actual:
|
|
1524
|
+
'@pipe':
|
|
1525
|
+
- ['{trigger.output.data.signalIn}', true]
|
|
1526
|
+
- ['{@conditional.nullish}']
|
|
1482
1527
|
- to: closer
|
|
1483
1528
|
conditions:
|
|
1484
1529
|
code: [200, 596, 597, 598]
|
|
1530
|
+
match:
|
|
1531
|
+
- expected: true
|
|
1532
|
+
actual:
|
|
1533
|
+
'@pipe':
|
|
1534
|
+
- ['{trigger.output.data.signalIn}', true]
|
|
1535
|
+
- ['{@conditional.nullish}']
|
|
1485
1536
|
- to: sleeper
|
|
1486
1537
|
conditions:
|
|
1487
1538
|
code: 588
|
|
@@ -310,6 +310,7 @@ class WorkerService {
|
|
|
310
310
|
index: err.index,
|
|
311
311
|
originJobId: err.originJobId,
|
|
312
312
|
parentWorkflowId: err.parentWorkflowId,
|
|
313
|
+
expire: err.expire,
|
|
313
314
|
workflowId: err.workflowId,
|
|
314
315
|
workflowTopic: err.workflowTopic,
|
|
315
316
|
activityName: err.activityName,
|
|
@@ -342,6 +343,8 @@ class WorkerService {
|
|
|
342
343
|
maximumInterval: err.maximumInterval || (0, ms_1.default)(enums_1.HMSH_DURABLE_MAX_INTERVAL) / 1000,
|
|
343
344
|
originJobId: err.originJobId,
|
|
344
345
|
parentWorkflowId: err.parentWorkflowId,
|
|
346
|
+
expire: err.expire,
|
|
347
|
+
signalIn: err.signalIn,
|
|
345
348
|
workflowDimension: err.workflowDimension,
|
|
346
349
|
workflowId: err.workflowId,
|
|
347
350
|
workflowTopic: err.workflowTopic,
|
|
@@ -190,6 +190,8 @@ class WorkflowService {
|
|
|
190
190
|
maximumInterval: (0, ms_1.default)(options?.config?.maximumInterval ?? enums_1.HMSH_DURABLE_MAX_INTERVAL) /
|
|
191
191
|
1000,
|
|
192
192
|
originJobId: originJobId ?? workflowId,
|
|
193
|
+
expire: options.expire,
|
|
194
|
+
signalIn: options.signalIn,
|
|
193
195
|
parentWorkflowId,
|
|
194
196
|
workflowDimension: workflowDimension,
|
|
195
197
|
workflowId: childJobId,
|
|
@@ -303,6 +305,7 @@ class WorkflowService {
|
|
|
303
305
|
workflowId: activityJobId,
|
|
304
306
|
workflowTopic: activityTopic,
|
|
305
307
|
activityName,
|
|
308
|
+
expire: options.expire,
|
|
306
309
|
backoffCoefficient: options?.retryPolicy?.backoffCoefficient ?? undefined,
|
|
307
310
|
maximumAttempts: options?.retryPolicy?.maximumAttempts ?? undefined,
|
|
308
311
|
maximumInterval: maximumInterval ?? undefined,
|
package/build/types/durable.d.ts
CHANGED
|
@@ -426,6 +426,8 @@ type ProxyType<ACT> = {
|
|
|
426
426
|
* Configuration settings for activities within a workflow.
|
|
427
427
|
*/
|
|
428
428
|
type ActivityConfig = {
|
|
429
|
+
/** place holder setting; unused at this time (re: activity workflow expire configuration) */
|
|
430
|
+
expire?: number;
|
|
429
431
|
/** Start to close timeout for the activity; not yet implemented */
|
|
430
432
|
startToCloseTimeout?: string;
|
|
431
433
|
/** Configuration for specific activities, type not yet specified */
|
package/build/types/error.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ export type DurableChildErrorType = {
|
|
|
3
3
|
await?: boolean;
|
|
4
4
|
backoffCoefficient?: number;
|
|
5
5
|
index: number;
|
|
6
|
+
expire?: number;
|
|
7
|
+
signalIn?: boolean;
|
|
6
8
|
maximumAttempts?: number;
|
|
7
9
|
maximumInterval?: number;
|
|
8
10
|
originJobId: string | null;
|
|
@@ -26,6 +28,7 @@ export type DurableProxyErrorType = {
|
|
|
26
28
|
activityName: string;
|
|
27
29
|
backoffCoefficient?: number;
|
|
28
30
|
index: number;
|
|
31
|
+
expire?: number;
|
|
29
32
|
maximumAttempts?: number;
|
|
30
33
|
maximumInterval?: number;
|
|
31
34
|
originJobId: string | null;
|
package/package.json
CHANGED
package/types/durable.ts
CHANGED
|
@@ -521,6 +521,9 @@ type ProxyType<ACT> = {
|
|
|
521
521
|
* Configuration settings for activities within a workflow.
|
|
522
522
|
*/
|
|
523
523
|
type ActivityConfig = {
|
|
524
|
+
/** place holder setting; unused at this time (re: activity workflow expire configuration) */
|
|
525
|
+
expire?: number;
|
|
526
|
+
|
|
524
527
|
/** Start to close timeout for the activity; not yet implemented */
|
|
525
528
|
startToCloseTimeout?: string;
|
|
526
529
|
|
package/types/error.ts
CHANGED
|
@@ -3,6 +3,8 @@ export type DurableChildErrorType = {
|
|
|
3
3
|
await?: boolean;
|
|
4
4
|
backoffCoefficient?: number;
|
|
5
5
|
index: number;
|
|
6
|
+
expire?: number;
|
|
7
|
+
signalIn?: boolean;
|
|
6
8
|
maximumAttempts?: number;
|
|
7
9
|
maximumInterval?: number;
|
|
8
10
|
originJobId: string | null;
|
|
@@ -28,6 +30,7 @@ export type DurableProxyErrorType = {
|
|
|
28
30
|
activityName: string;
|
|
29
31
|
backoffCoefficient?: number;
|
|
30
32
|
index: number;
|
|
33
|
+
expire?: number;
|
|
31
34
|
maximumAttempts?: number;
|
|
32
35
|
maximumInterval?: number;
|
|
33
36
|
originJobId: string | null;
|