@hotmeshio/hotmesh 0.0.19 → 0.0.21
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 +4 -4
- package/build/modules/errors.d.ts +2 -1
- package/build/modules/errors.js +2 -1
- package/build/package.json +2 -1
- package/build/services/activities/activity.d.ts +2 -2
- package/build/services/activities/activity.js +10 -8
- package/build/services/activities/hook.d.ts +2 -1
- package/build/services/activities/hook.js +12 -9
- package/build/services/activities/signal.d.ts +4 -0
- package/build/services/activities/signal.js +16 -2
- package/build/services/durable/client.d.ts +15 -5
- package/build/services/durable/client.js +37 -14
- package/build/services/durable/factory.d.ts +2 -16
- package/build/services/durable/factory.js +276 -46
- package/build/services/durable/handle.d.ts +1 -1
- package/build/services/durable/handle.js +18 -5
- package/build/services/durable/search.d.ts +8 -1
- package/build/services/durable/search.js +36 -10
- package/build/services/durable/worker.d.ts +7 -9
- package/build/services/durable/worker.js +29 -23
- package/build/services/durable/workflow.d.ts +23 -2
- package/build/services/durable/workflow.js +143 -37
- package/build/services/engine/index.d.ts +2 -2
- package/build/services/engine/index.js +7 -12
- package/build/services/hotmesh/index.d.ts +2 -2
- package/build/services/hotmesh/index.js +2 -2
- package/build/services/signaler/store.d.ts +2 -2
- package/build/services/signaler/store.js +17 -7
- package/build/services/signaler/stream.js +1 -0
- package/build/services/store/clients/redis.js +1 -1
- package/build/services/store/index.js +3 -0
- package/build/services/telemetry/index.js +7 -1
- package/build/types/activity.d.ts +5 -3
- package/build/types/durable.d.ts +13 -2
- package/build/types/hook.d.ts +0 -1
- package/build/types/index.d.ts +1 -1
- package/modules/errors.ts +4 -2
- package/package.json +2 -1
- package/services/activities/activity.ts +10 -8
- package/services/activities/hook.ts +13 -10
- package/services/activities/signal.ts +17 -3
- package/services/durable/client.ts +40 -15
- package/services/durable/factory.ts +274 -46
- package/services/durable/handle.ts +18 -5
- package/services/durable/search.ts +38 -10
- package/services/durable/worker.ts +30 -24
- package/services/durable/workflow.ts +158 -40
- package/services/engine/index.ts +8 -12
- package/services/hotmesh/index.ts +3 -3
- package/services/signaler/store.ts +18 -8
- package/services/signaler/stream.ts +1 -0
- package/services/store/clients/redis.ts +1 -1
- package/services/store/index.ts +2 -0
- package/services/telemetry/index.ts +6 -1
- package/types/activity.ts +10 -8
- package/types/durable.ts +14 -1
- package/types/hook.ts +0 -1
- package/types/index.ts +1 -0
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_COEFFICIENT = exports.APP_ID = exports.APP_VERSION = exports.getWorkflowYAML = void 0;
|
|
2
4
|
/**
|
|
3
5
|
* NOTE: Using `maxSystemRetries = 3` and `backoffCoefficient = 10`, errant
|
|
4
6
|
* workflows will be retried on the following schedule (8 times in 27 hours):
|
|
5
7
|
* => 10ms, 100ms, 1000ms, 10s, 100s, 1_000s, 10_000s, 100_000s
|
|
6
|
-
*
|
|
8
|
+
*
|
|
7
9
|
* 594: waitforsignal
|
|
8
10
|
* 595: sleep
|
|
9
11
|
* 596, 597, 598: fatal
|
|
10
12
|
* 599: retry
|
|
11
13
|
*/
|
|
12
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.WFS_HOOK_ID = exports.WFSC_PUBLISHES_TOPIC = exports.WFSC_SUBSCRIBES_TOPIC = exports.WFS_PUBLISHES_TOPIC = exports.WFS_SUBSCRIBES_TOPIC = exports.DEFAULT_COEFFICIENT = exports.SLEEP_HOOK_ID = exports.ACTIVITY_HOOK_ID = exports.HOOK_ID = exports.PUBLISHES_TOPIC = exports.SUBSCRIBES_TOPIC = exports.SLEEP_PUBLISHES_TOPIC = exports.SLEEP_SUBSCRIBES_TOPIC = exports.ACTIVITY_PUBLISHES_TOPIC = exports.ACTIVITY_SUBSCRIBES_TOPIC = exports.APP_ID = exports.APP_VERSION = exports.getWorkflowYAML = void 0;
|
|
14
|
-
//todo: getChildWorkflowYAML (includes key, so flow will cleanup)
|
|
15
|
-
//todo: if an activity throws an error, it should self-clean its index
|
|
16
14
|
const getWorkflowYAML = (app, version) => {
|
|
17
15
|
return `app:
|
|
18
16
|
id: ${app}
|
|
@@ -46,6 +44,7 @@ const getWorkflowYAML = (app, version) => {
|
|
|
46
44
|
|
|
47
45
|
activities:
|
|
48
46
|
t1:
|
|
47
|
+
title: Main Flow Trigger
|
|
49
48
|
type: trigger
|
|
50
49
|
stats:
|
|
51
50
|
id: '{$self.input.data.workflowId}'
|
|
@@ -59,6 +58,7 @@ const getWorkflowYAML = (app, version) => {
|
|
|
59
58
|
done: false
|
|
60
59
|
|
|
61
60
|
a1:
|
|
61
|
+
title: Main Flow Pivot - All Cycling Descendants Point Here
|
|
62
62
|
type: hook
|
|
63
63
|
cycle: true
|
|
64
64
|
output:
|
|
@@ -71,6 +71,7 @@ const getWorkflowYAML = (app, version) => {
|
|
|
71
71
|
duration: '{t1.output.data.backoffCoefficient}'
|
|
72
72
|
|
|
73
73
|
w1:
|
|
74
|
+
title: Main Worker - Calls Workflow Functions
|
|
74
75
|
type: worker
|
|
75
76
|
topic: '{t1.output.data.workflowTopic}'
|
|
76
77
|
emit: '{$job.data.done}'
|
|
@@ -132,8 +133,8 @@ const getWorkflowYAML = (app, version) => {
|
|
|
132
133
|
done: '{$self.output.data.done}'
|
|
133
134
|
|
|
134
135
|
a2:
|
|
135
|
-
type: hook
|
|
136
136
|
title: Wait for cleanup signal
|
|
137
|
+
type: hook
|
|
137
138
|
hook:
|
|
138
139
|
type: object
|
|
139
140
|
properties:
|
|
@@ -143,6 +144,209 @@ const getWorkflowYAML = (app, version) => {
|
|
|
143
144
|
maps:
|
|
144
145
|
workflowId: '{t1.output.data.workflowId}'
|
|
145
146
|
|
|
147
|
+
sig:
|
|
148
|
+
title: Signal In - Receive signals
|
|
149
|
+
type: hook
|
|
150
|
+
hook:
|
|
151
|
+
type: object
|
|
152
|
+
properties:
|
|
153
|
+
id:
|
|
154
|
+
type: string
|
|
155
|
+
arguments:
|
|
156
|
+
type: array
|
|
157
|
+
workflowTopic:
|
|
158
|
+
type: string
|
|
159
|
+
job:
|
|
160
|
+
maps:
|
|
161
|
+
workflowId: '{t1.output.data.workflowId}'
|
|
162
|
+
|
|
163
|
+
siga1:
|
|
164
|
+
title: Signal In Flow Pivot - Cycling Descendants Point Here
|
|
165
|
+
type: hook
|
|
166
|
+
cycle: true
|
|
167
|
+
output:
|
|
168
|
+
schema:
|
|
169
|
+
type: object
|
|
170
|
+
properties:
|
|
171
|
+
duration:
|
|
172
|
+
type: number
|
|
173
|
+
maps:
|
|
174
|
+
duration: '{t1.output.data.backoffCoefficient}'
|
|
175
|
+
|
|
176
|
+
sigw1:
|
|
177
|
+
title: Signal In - Worker
|
|
178
|
+
type: worker
|
|
179
|
+
topic: '{sig.hook.data.workflowTopic}'
|
|
180
|
+
retry:
|
|
181
|
+
'599': [2]
|
|
182
|
+
input:
|
|
183
|
+
schema:
|
|
184
|
+
type: object
|
|
185
|
+
properties:
|
|
186
|
+
workflowId:
|
|
187
|
+
type: string
|
|
188
|
+
workflowDimension:
|
|
189
|
+
type: string
|
|
190
|
+
arguments:
|
|
191
|
+
type: array
|
|
192
|
+
maps:
|
|
193
|
+
workflowId: '{t1.output.data.workflowId}'
|
|
194
|
+
workflowDimension: '{sig.output.metadata.dad}'
|
|
195
|
+
arguments: '{sig.hook.data.arguments}'
|
|
196
|
+
output:
|
|
197
|
+
schema:
|
|
198
|
+
type: object
|
|
199
|
+
594:
|
|
200
|
+
schema:
|
|
201
|
+
type: object
|
|
202
|
+
properties:
|
|
203
|
+
index:
|
|
204
|
+
type: number
|
|
205
|
+
description: the index of the first signal in the array
|
|
206
|
+
signals:
|
|
207
|
+
type: array
|
|
208
|
+
description: remaining signal ids
|
|
209
|
+
items:
|
|
210
|
+
type: object
|
|
211
|
+
properties:
|
|
212
|
+
signal:
|
|
213
|
+
type: string
|
|
214
|
+
index:
|
|
215
|
+
type: number
|
|
216
|
+
maps:
|
|
217
|
+
index: '{$self.output.data.index}'
|
|
218
|
+
signals: '{$self.output.data.signals}'
|
|
219
|
+
595:
|
|
220
|
+
schema:
|
|
221
|
+
type: object
|
|
222
|
+
properties:
|
|
223
|
+
duration:
|
|
224
|
+
type: number
|
|
225
|
+
description: sleep duration in seconds
|
|
226
|
+
index:
|
|
227
|
+
type: number
|
|
228
|
+
description: the current index
|
|
229
|
+
maps:
|
|
230
|
+
duration: '{$self.output.data.duration}'
|
|
231
|
+
index: '{$self.output.data.index}'
|
|
232
|
+
|
|
233
|
+
siga594:
|
|
234
|
+
title: Signal In - Wait for signals
|
|
235
|
+
type: await
|
|
236
|
+
topic: ${app}.wfsc.execute
|
|
237
|
+
input:
|
|
238
|
+
schema:
|
|
239
|
+
type: object
|
|
240
|
+
properties:
|
|
241
|
+
index:
|
|
242
|
+
type: number
|
|
243
|
+
signals:
|
|
244
|
+
type: array
|
|
245
|
+
description: signal ids
|
|
246
|
+
items:
|
|
247
|
+
type: object
|
|
248
|
+
properties:
|
|
249
|
+
signal:
|
|
250
|
+
type: string
|
|
251
|
+
index:
|
|
252
|
+
type: number
|
|
253
|
+
parentWorkflowId:
|
|
254
|
+
type: string
|
|
255
|
+
cycleWorkflowId:
|
|
256
|
+
type: string
|
|
257
|
+
baseWorkflowId:
|
|
258
|
+
type: string
|
|
259
|
+
description: index will be appended later
|
|
260
|
+
maps:
|
|
261
|
+
signals: '{sigw1.output.data.signals}'
|
|
262
|
+
parentWorkflowId:
|
|
263
|
+
'@pipe':
|
|
264
|
+
- ['{$job.metadata.jid}', '-w']
|
|
265
|
+
- ['{@string.concat}']
|
|
266
|
+
cycleWorkflowId:
|
|
267
|
+
'@pipe':
|
|
268
|
+
- ['{$job.metadata.jid}', '-$wfc', '{sig.output.metadata.dad}', '-', '{sigw1.output.data.index}']
|
|
269
|
+
- ['{@string.concat}']
|
|
270
|
+
baseWorkflowId:
|
|
271
|
+
'@pipe':
|
|
272
|
+
- ['{$job.metadata.jid}', '-$wfs', '{sig.output.metadata.dad}', '-']
|
|
273
|
+
- ['{@string.concat}']
|
|
274
|
+
output:
|
|
275
|
+
schema:
|
|
276
|
+
type: object
|
|
277
|
+
properties:
|
|
278
|
+
done:
|
|
279
|
+
type: boolean
|
|
280
|
+
maps:
|
|
281
|
+
done: '{sigw1.output.data.done}'
|
|
282
|
+
|
|
283
|
+
sigc594:
|
|
284
|
+
title: Signal In - Goto Activity siga1
|
|
285
|
+
type: cycle
|
|
286
|
+
ancestor: siga1
|
|
287
|
+
input:
|
|
288
|
+
maps:
|
|
289
|
+
duration: '{siga1.output.data.duration}'
|
|
290
|
+
|
|
291
|
+
siga595:
|
|
292
|
+
title: Signal In - Sleep before trying again
|
|
293
|
+
type: await
|
|
294
|
+
topic: ${app}.sleep.execute
|
|
295
|
+
input:
|
|
296
|
+
schema:
|
|
297
|
+
type: object
|
|
298
|
+
properties:
|
|
299
|
+
duration:
|
|
300
|
+
type: number
|
|
301
|
+
index:
|
|
302
|
+
type: number
|
|
303
|
+
workflowId:
|
|
304
|
+
type: string
|
|
305
|
+
parentWorkflowId:
|
|
306
|
+
type: string
|
|
307
|
+
maps:
|
|
308
|
+
duration: '{sigw1.output.data.duration}'
|
|
309
|
+
index: '{sigw1.output.data.index}'
|
|
310
|
+
parentWorkflowId:
|
|
311
|
+
'@pipe':
|
|
312
|
+
- ['{$job.metadata.jid}', '-s']
|
|
313
|
+
- ['{@string.concat}']
|
|
314
|
+
workflowId:
|
|
315
|
+
'@pipe':
|
|
316
|
+
- ['{$job.metadata.jid}', '-$sleep', '{sig.output.metadata.dad}', '-', '{sigw1.output.data.index}']
|
|
317
|
+
- ['{@string.concat}']
|
|
318
|
+
output:
|
|
319
|
+
schema:
|
|
320
|
+
type: object
|
|
321
|
+
properties:
|
|
322
|
+
done:
|
|
323
|
+
type: boolean
|
|
324
|
+
maps:
|
|
325
|
+
done: '{sigw1.output.data.done}'
|
|
326
|
+
|
|
327
|
+
sigc595:
|
|
328
|
+
title: Signal In - Goto Activity siga1
|
|
329
|
+
type: cycle
|
|
330
|
+
ancestor: siga1
|
|
331
|
+
input:
|
|
332
|
+
maps:
|
|
333
|
+
duration: '{siga1.output.data.duration}'
|
|
334
|
+
|
|
335
|
+
siga599:
|
|
336
|
+
title: Signal In - Sleep exponentially longer and retry
|
|
337
|
+
type: hook
|
|
338
|
+
sleep: '{siga1.output.data.duration}'
|
|
339
|
+
|
|
340
|
+
sigc599:
|
|
341
|
+
title: Signal In - Goto Activity siga1
|
|
342
|
+
type: cycle
|
|
343
|
+
ancestor: siga1
|
|
344
|
+
input:
|
|
345
|
+
maps:
|
|
346
|
+
duration:
|
|
347
|
+
'@pipe':
|
|
348
|
+
- ['{siga1.output.data.duration}', '{t1.output.data.backoffCoefficient}']
|
|
349
|
+
- ['{@math.multiply}']
|
|
146
350
|
|
|
147
351
|
a594:
|
|
148
352
|
title: Wait for signals
|
|
@@ -375,7 +579,7 @@ const getWorkflowYAML = (app, version) => {
|
|
|
375
579
|
done: true
|
|
376
580
|
|
|
377
581
|
s4:
|
|
378
|
-
title: Awaken child
|
|
582
|
+
title: Awaken child flows so they end and self-clean
|
|
379
583
|
type: signal
|
|
380
584
|
subtype: all
|
|
381
585
|
key_name: parentWorkflowId
|
|
@@ -410,6 +614,19 @@ const getWorkflowYAML = (app, version) => {
|
|
|
410
614
|
type: boolean
|
|
411
615
|
maps:
|
|
412
616
|
done: true
|
|
617
|
+
s5:
|
|
618
|
+
title: Close Signal In Channel
|
|
619
|
+
type: signal
|
|
620
|
+
subtype: one
|
|
621
|
+
topic: ${app}.flow.signal
|
|
622
|
+
signal:
|
|
623
|
+
schema:
|
|
624
|
+
type: object
|
|
625
|
+
properties:
|
|
626
|
+
id:
|
|
627
|
+
type: string
|
|
628
|
+
maps:
|
|
629
|
+
id: '{$job.metadata.jid}'
|
|
413
630
|
|
|
414
631
|
transitions:
|
|
415
632
|
t1:
|
|
@@ -422,6 +639,33 @@ const getWorkflowYAML = (app, version) => {
|
|
|
422
639
|
'@pipe':
|
|
423
640
|
- ['{$job.metadata.key}', true, false]
|
|
424
641
|
- ['{@conditional.ternary}']
|
|
642
|
+
- to: sig
|
|
643
|
+
sig:
|
|
644
|
+
- to: siga1
|
|
645
|
+
conditions:
|
|
646
|
+
code: 202
|
|
647
|
+
siga1:
|
|
648
|
+
- to: sigw1
|
|
649
|
+
sigw1:
|
|
650
|
+
- to: siga594
|
|
651
|
+
conditions:
|
|
652
|
+
code: 594
|
|
653
|
+
- to: siga595
|
|
654
|
+
conditions:
|
|
655
|
+
code: 595
|
|
656
|
+
- to: siga599
|
|
657
|
+
conditions:
|
|
658
|
+
code: 599
|
|
659
|
+
siga594:
|
|
660
|
+
- to: sigc594
|
|
661
|
+
conditions:
|
|
662
|
+
code: 202
|
|
663
|
+
siga595:
|
|
664
|
+
- to: sigc595
|
|
665
|
+
conditions:
|
|
666
|
+
code: 202
|
|
667
|
+
siga599:
|
|
668
|
+
- to: sigc599
|
|
425
669
|
a1:
|
|
426
670
|
- to: w1
|
|
427
671
|
w1:
|
|
@@ -434,16 +678,19 @@ const getWorkflowYAML = (app, version) => {
|
|
|
434
678
|
- to: a599
|
|
435
679
|
conditions:
|
|
436
680
|
code: 599
|
|
681
|
+
- to: s3
|
|
682
|
+
conditions:
|
|
683
|
+
code: [200, 598, 597, 596]
|
|
437
684
|
- to: s1
|
|
438
685
|
conditions:
|
|
439
686
|
code: [200, 598, 597, 596]
|
|
440
687
|
- to: s2
|
|
441
688
|
conditions:
|
|
442
689
|
code: [200, 598, 597, 596]
|
|
443
|
-
- to:
|
|
690
|
+
- to: s4
|
|
444
691
|
conditions:
|
|
445
692
|
code: [200, 598, 597, 596]
|
|
446
|
-
- to:
|
|
693
|
+
- to: s5
|
|
447
694
|
conditions:
|
|
448
695
|
code: [200, 598, 597, 596]
|
|
449
696
|
a594:
|
|
@@ -464,7 +711,14 @@ const getWorkflowYAML = (app, version) => {
|
|
|
464
711
|
match:
|
|
465
712
|
- expected: '{t1.output.data.workflowId}'
|
|
466
713
|
actual: '{$self.hook.data.id}'
|
|
467
|
-
|
|
714
|
+
|
|
715
|
+
${app}.flow.signal:
|
|
716
|
+
- to: sig
|
|
717
|
+
conditions:
|
|
718
|
+
match:
|
|
719
|
+
- expected: '{t1.output.data.workflowId}'
|
|
720
|
+
actual: '{$self.hook.data.id}'
|
|
721
|
+
|
|
468
722
|
- subscribes: ${app}.activity.execute
|
|
469
723
|
publishes: ${app}.activity.executed
|
|
470
724
|
|
|
@@ -495,6 +749,7 @@ const getWorkflowYAML = (app, version) => {
|
|
|
495
749
|
|
|
496
750
|
activities:
|
|
497
751
|
t1a:
|
|
752
|
+
title: Activity Flow Trigger
|
|
498
753
|
type: trigger
|
|
499
754
|
stats:
|
|
500
755
|
id: '{$self.input.data.workflowId}'
|
|
@@ -505,6 +760,7 @@ const getWorkflowYAML = (app, version) => {
|
|
|
505
760
|
target: '{$self.input.data.parentWorkflowId}'
|
|
506
761
|
|
|
507
762
|
w1a:
|
|
763
|
+
title: Activity Worker - Calls Activity Functions
|
|
508
764
|
type: worker
|
|
509
765
|
topic: '{t1a.output.data.workflowTopic}'
|
|
510
766
|
emit: true
|
|
@@ -540,8 +796,8 @@ const getWorkflowYAML = (app, version) => {
|
|
|
540
796
|
done: true
|
|
541
797
|
|
|
542
798
|
s1a:
|
|
799
|
+
title: Awaken activity flows so they end and self-clean
|
|
543
800
|
type: hook
|
|
544
|
-
title: Wait for cleanup signal
|
|
545
801
|
hook:
|
|
546
802
|
type: object
|
|
547
803
|
properties:
|
|
@@ -560,7 +816,6 @@ const getWorkflowYAML = (app, version) => {
|
|
|
560
816
|
hooks:
|
|
561
817
|
${app}.activity.awaken:
|
|
562
818
|
- to: s1a
|
|
563
|
-
keep_alive: true
|
|
564
819
|
conditions:
|
|
565
820
|
match:
|
|
566
821
|
- expected: '{t1a.output.data.workflowId}'
|
|
@@ -597,6 +852,7 @@ const getWorkflowYAML = (app, version) => {
|
|
|
597
852
|
|
|
598
853
|
activities:
|
|
599
854
|
t1s:
|
|
855
|
+
title: Sleep Flow Trigger
|
|
600
856
|
type: trigger
|
|
601
857
|
stats:
|
|
602
858
|
id: '{$self.input.data.workflowId}'
|
|
@@ -607,14 +863,14 @@ const getWorkflowYAML = (app, version) => {
|
|
|
607
863
|
target: '{$self.input.data.parentWorkflowId}'
|
|
608
864
|
|
|
609
865
|
a1s:
|
|
610
|
-
type: hook
|
|
611
866
|
title: Sleep for a duration
|
|
867
|
+
type: hook
|
|
612
868
|
sleep: '{t1s.output.data.duration}'
|
|
613
869
|
emit: true
|
|
614
870
|
|
|
615
871
|
a2s:
|
|
872
|
+
title: Awaken sleep flows so they end and self-clean
|
|
616
873
|
type: hook
|
|
617
|
-
title: Wait for cleanup signal
|
|
618
874
|
hook:
|
|
619
875
|
type: object
|
|
620
876
|
properties:
|
|
@@ -684,7 +940,7 @@ const getWorkflowYAML = (app, version) => {
|
|
|
684
940
|
id: '{$self.input.data.cycleWorkflowId}'
|
|
685
941
|
|
|
686
942
|
a1wc:
|
|
687
|
-
title:
|
|
943
|
+
title: Pivot - All Cycling Descendants Point Here
|
|
688
944
|
type: hook
|
|
689
945
|
cycle: true
|
|
690
946
|
output:
|
|
@@ -723,6 +979,7 @@ const getWorkflowYAML = (app, version) => {
|
|
|
723
979
|
- ['{t1wc.output.data.signals}', 1]
|
|
724
980
|
- ['{@array.slice}']
|
|
725
981
|
a2wc:
|
|
982
|
+
title: Precalculate targetLength
|
|
726
983
|
type: hook
|
|
727
984
|
output:
|
|
728
985
|
schema:
|
|
@@ -734,7 +991,7 @@ const getWorkflowYAML = (app, version) => {
|
|
|
734
991
|
targetLength: '{a1wc.output.data.targetLength}'
|
|
735
992
|
|
|
736
993
|
c1wc:
|
|
737
|
-
title: Goto Activity a1wc
|
|
994
|
+
title: Goto Activity a1wc - Spawn Signal children
|
|
738
995
|
type: cycle
|
|
739
996
|
ancestor: a1wc
|
|
740
997
|
input:
|
|
@@ -840,6 +1097,7 @@ const getWorkflowYAML = (app, version) => {
|
|
|
840
1097
|
|
|
841
1098
|
activities:
|
|
842
1099
|
t1ww:
|
|
1100
|
+
title: WFS - Wait For Signal Trigger
|
|
843
1101
|
type: trigger
|
|
844
1102
|
stats:
|
|
845
1103
|
id: '{$self.input.data.workflowId}'
|
|
@@ -850,8 +1108,8 @@ const getWorkflowYAML = (app, version) => {
|
|
|
850
1108
|
target: '{$self.input.data.parentWorkflowId}'
|
|
851
1109
|
|
|
852
1110
|
a1ww:
|
|
1111
|
+
title: WFS - signal entry point
|
|
853
1112
|
type: hook
|
|
854
|
-
title: Wait for custom signal
|
|
855
1113
|
emit: true
|
|
856
1114
|
hook:
|
|
857
1115
|
type: object
|
|
@@ -865,8 +1123,8 @@ const getWorkflowYAML = (app, version) => {
|
|
|
865
1123
|
signalId: '{t1ww.output.data.signalId}'
|
|
866
1124
|
|
|
867
1125
|
a2ww:
|
|
1126
|
+
title: WFS - cleanup signal entry point
|
|
868
1127
|
type: hook
|
|
869
|
-
title: Wait for cleanup signal
|
|
870
1128
|
hook:
|
|
871
1129
|
type: object
|
|
872
1130
|
properties:
|
|
@@ -903,33 +1161,5 @@ const APP_VERSION = '1';
|
|
|
903
1161
|
exports.APP_VERSION = APP_VERSION;
|
|
904
1162
|
const APP_ID = 'durable';
|
|
905
1163
|
exports.APP_ID = APP_ID;
|
|
906
|
-
const ACTIVITY_SUBSCRIBES_TOPIC = 'durable.activity.execute';
|
|
907
|
-
exports.ACTIVITY_SUBSCRIBES_TOPIC = ACTIVITY_SUBSCRIBES_TOPIC;
|
|
908
|
-
const ACTIVITY_PUBLISHES_TOPIC = 'durable.activity.executed';
|
|
909
|
-
exports.ACTIVITY_PUBLISHES_TOPIC = ACTIVITY_PUBLISHES_TOPIC;
|
|
910
|
-
const SLEEP_SUBSCRIBES_TOPIC = 'durable.sleep.execute';
|
|
911
|
-
exports.SLEEP_SUBSCRIBES_TOPIC = SLEEP_SUBSCRIBES_TOPIC;
|
|
912
|
-
const SLEEP_PUBLISHES_TOPIC = 'durable.sleep.executed';
|
|
913
|
-
exports.SLEEP_PUBLISHES_TOPIC = SLEEP_PUBLISHES_TOPIC;
|
|
914
|
-
const WFS_SUBSCRIBES_TOPIC = 'durable.wfs.execute';
|
|
915
|
-
exports.WFS_SUBSCRIBES_TOPIC = WFS_SUBSCRIBES_TOPIC;
|
|
916
|
-
const WFS_PUBLISHES_TOPIC = 'durable.wfs.executed';
|
|
917
|
-
exports.WFS_PUBLISHES_TOPIC = WFS_PUBLISHES_TOPIC;
|
|
918
|
-
const WFSC_SUBSCRIBES_TOPIC = 'durable.wfsc.execute';
|
|
919
|
-
exports.WFSC_SUBSCRIBES_TOPIC = WFSC_SUBSCRIBES_TOPIC;
|
|
920
|
-
const WFSC_PUBLISHES_TOPIC = 'durable.wfsc.executed';
|
|
921
|
-
exports.WFSC_PUBLISHES_TOPIC = WFSC_PUBLISHES_TOPIC;
|
|
922
|
-
const SUBSCRIBES_TOPIC = 'durable.execute';
|
|
923
|
-
exports.SUBSCRIBES_TOPIC = SUBSCRIBES_TOPIC;
|
|
924
|
-
const PUBLISHES_TOPIC = 'durable.executed';
|
|
925
|
-
exports.PUBLISHES_TOPIC = PUBLISHES_TOPIC;
|
|
926
|
-
const HOOK_ID = 'durable.awaken';
|
|
927
|
-
exports.HOOK_ID = HOOK_ID;
|
|
928
|
-
const ACTIVITY_HOOK_ID = 'durable.activity.awaken';
|
|
929
|
-
exports.ACTIVITY_HOOK_ID = ACTIVITY_HOOK_ID;
|
|
930
|
-
const SLEEP_HOOK_ID = 'durable.sleep.awaken';
|
|
931
|
-
exports.SLEEP_HOOK_ID = SLEEP_HOOK_ID;
|
|
932
|
-
const WFS_HOOK_ID = 'durable.wfs.awaken';
|
|
933
|
-
exports.WFS_HOOK_ID = WFS_HOOK_ID;
|
|
934
1164
|
const DEFAULT_COEFFICIENT = 10;
|
|
935
1165
|
exports.DEFAULT_COEFFICIENT = DEFAULT_COEFFICIENT;
|
|
@@ -5,5 +5,5 @@ export declare class WorkflowHandleService {
|
|
|
5
5
|
workflowId: string;
|
|
6
6
|
constructor(hotMesh: HotMesh, workflowTopic: string, workflowId: string);
|
|
7
7
|
signal(signalId: string, data: Record<any, any>): Promise<void>;
|
|
8
|
-
result(): Promise<any>;
|
|
8
|
+
result(loadState?: boolean): Promise<any>;
|
|
9
9
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.WorkflowHandleService = void 0;
|
|
4
|
-
const factory_1 = require("./factory");
|
|
5
4
|
class WorkflowHandleService {
|
|
6
5
|
constructor(hotMesh, workflowTopic, workflowId) {
|
|
7
6
|
this.workflowTopic = workflowTopic;
|
|
@@ -9,11 +8,25 @@ class WorkflowHandleService {
|
|
|
9
8
|
this.hotMesh = hotMesh;
|
|
10
9
|
}
|
|
11
10
|
async signal(signalId, data) {
|
|
12
|
-
await this.hotMesh.hook(
|
|
11
|
+
await this.hotMesh.hook(`${this.hotMesh.appId}.wfs.signal`, { id: signalId, data });
|
|
13
12
|
}
|
|
14
|
-
async result() {
|
|
13
|
+
async result(loadState) {
|
|
14
|
+
if (loadState) {
|
|
15
|
+
const state = await this.hotMesh.getState(`${this.hotMesh.appId}.execute`, this.workflowId);
|
|
16
|
+
if (!state.data && state.metadata.err) {
|
|
17
|
+
throw new Error(JSON.parse(state.metadata.err));
|
|
18
|
+
}
|
|
19
|
+
if (state?.data?.done) {
|
|
20
|
+
//child flows are never technically 'done' as they have an open hook
|
|
21
|
+
//that is tied to the parent flow's completion. so, we need to check
|
|
22
|
+
//the 'done' flag on the child flow's payload (not the 'js' metadata field
|
|
23
|
+
//which is typically used); the loadState parameter ensures this
|
|
24
|
+
//check happens early
|
|
25
|
+
return state.data.response;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
15
28
|
let status = await this.hotMesh.getStatus(this.workflowId);
|
|
16
|
-
const topic = `${
|
|
29
|
+
const topic = `${this.hotMesh.appId}.executed.${this.workflowId}`;
|
|
17
30
|
return new Promise((resolve, reject) => {
|
|
18
31
|
let isResolved = false;
|
|
19
32
|
//common fulfill/unsubscribe
|
|
@@ -26,7 +39,7 @@ class WorkflowHandleService {
|
|
|
26
39
|
return reject(JSON.parse(err));
|
|
27
40
|
}
|
|
28
41
|
else if (!response) {
|
|
29
|
-
const state = await this.hotMesh.getState(this.
|
|
42
|
+
const state = await this.hotMesh.getState(`${this.hotMesh.appId}.execute`, this.workflowId);
|
|
30
43
|
if (!state.data && state.metadata.err) {
|
|
31
44
|
return reject(JSON.parse(state.metadata.err));
|
|
32
45
|
}
|
|
@@ -3,10 +3,17 @@ import { RedisClient, RedisMulti } from '../../types/redis';
|
|
|
3
3
|
import { StoreService } from '../store';
|
|
4
4
|
export declare class Search {
|
|
5
5
|
jobId: string;
|
|
6
|
+
searchSessionId: string;
|
|
7
|
+
searchSessionIndex: number;
|
|
6
8
|
hotMeshClient: HotMesh;
|
|
7
9
|
store: StoreService<RedisClient, RedisMulti> | null;
|
|
8
10
|
safeKey(key: string): string;
|
|
9
|
-
constructor(workflowId: string, hotMeshClient: HotMesh);
|
|
11
|
+
constructor(workflowId: string, hotMeshClient: HotMesh, searchSessionId: string);
|
|
12
|
+
/**
|
|
13
|
+
* increments the index to return a unique search session guid when
|
|
14
|
+
* calling any method that produces side effects (changes the value)
|
|
15
|
+
*/
|
|
16
|
+
getSearchSessionGuid(): string;
|
|
10
17
|
set(key: string, value: string): Promise<void>;
|
|
11
18
|
get(key: string): Promise<string>;
|
|
12
19
|
del(key: string): Promise<void>;
|
|
@@ -8,18 +8,32 @@ class Search {
|
|
|
8
8
|
//so its design never conflicts with the hotmesh keyspace
|
|
9
9
|
return `_${key}`;
|
|
10
10
|
}
|
|
11
|
-
constructor(workflowId, hotMeshClient) {
|
|
11
|
+
constructor(workflowId, hotMeshClient, searchSessionId) {
|
|
12
|
+
this.searchSessionIndex = 0;
|
|
12
13
|
const keyParams = {
|
|
13
14
|
appId: hotMeshClient.appId,
|
|
14
|
-
jobId:
|
|
15
|
+
jobId: workflowId
|
|
15
16
|
};
|
|
16
|
-
|
|
17
|
-
this.
|
|
17
|
+
this.jobId = key_1.KeyService.mintKey(hotMeshClient.namespace, key_1.KeyType.JOB_STATE, keyParams);
|
|
18
|
+
this.searchSessionId = searchSessionId;
|
|
18
19
|
this.hotMeshClient = hotMeshClient;
|
|
19
20
|
this.store = hotMeshClient.engine.store;
|
|
20
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* increments the index to return a unique search session guid when
|
|
24
|
+
* calling any method that produces side effects (changes the value)
|
|
25
|
+
*/
|
|
26
|
+
getSearchSessionGuid() {
|
|
27
|
+
//return the search session as it would exist in the search session index
|
|
28
|
+
return `${this.searchSessionId}-${this.searchSessionIndex++}-`;
|
|
29
|
+
}
|
|
21
30
|
async set(key, value) {
|
|
22
|
-
|
|
31
|
+
const ssGuid = this.getSearchSessionGuid();
|
|
32
|
+
const ssGuidValue = Number(await this.store.exec('HINCRBYFLOAT', this.jobId, ssGuid, '1'));
|
|
33
|
+
if (ssGuidValue === 1) {
|
|
34
|
+
//only allowed to set a value the first time
|
|
35
|
+
await this.store.exec('HSET', this.jobId, this.safeKey(key), value.toString());
|
|
36
|
+
}
|
|
23
37
|
}
|
|
24
38
|
async get(key) {
|
|
25
39
|
try {
|
|
@@ -31,15 +45,27 @@ class Search {
|
|
|
31
45
|
}
|
|
32
46
|
}
|
|
33
47
|
async del(key) {
|
|
34
|
-
|
|
48
|
+
const ssGuid = this.getSearchSessionGuid();
|
|
49
|
+
const ssGuidValue = Number(await this.store.exec('HINCRBYFLOAT', this.jobId, ssGuid, '1'));
|
|
50
|
+
if (ssGuidValue === 1) {
|
|
51
|
+
await this.store.exec('HDEL', this.jobId, this.safeKey(key));
|
|
52
|
+
}
|
|
35
53
|
}
|
|
36
54
|
async incr(key, val) {
|
|
37
|
-
|
|
55
|
+
const ssGuid = this.getSearchSessionGuid();
|
|
56
|
+
const ssGuidValue = Number(await this.store.exec('HINCRBYFLOAT', this.jobId, ssGuid, '1'));
|
|
57
|
+
if (ssGuidValue === 1) {
|
|
58
|
+
return Number(await this.store.exec('HINCRBYFLOAT', this.jobId, this.safeKey(key), val.toString()));
|
|
59
|
+
}
|
|
38
60
|
}
|
|
39
61
|
async mult(key, val) {
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
|
|
62
|
+
const ssGuid = this.getSearchSessionGuid();
|
|
63
|
+
const ssGuidValue = Number(await this.store.exec('HINCRBYFLOAT', this.jobId, ssGuid, '1'));
|
|
64
|
+
if (ssGuidValue === 1) {
|
|
65
|
+
const log = Math.log(val);
|
|
66
|
+
const logTotal = Number(await this.store.exec('HINCRBYFLOAT', this.jobId, this.safeKey(key), log.toString()));
|
|
67
|
+
return Math.exp(logTotal);
|
|
68
|
+
}
|
|
43
69
|
}
|
|
44
70
|
}
|
|
45
71
|
exports.Search = Search;
|
|
@@ -1,22 +1,20 @@
|
|
|
1
1
|
import { HotMeshService as HotMesh } from '../hotmesh';
|
|
2
|
-
import { Connection, Registry, WorkerConfig, WorkerOptions, WorkflowSearchOptions } from
|
|
2
|
+
import { Connection, Registry, WorkerConfig, WorkerOptions, WorkflowSearchOptions } from '../../types/durable';
|
|
3
3
|
export declare class WorkerService {
|
|
4
4
|
static activityRegistry: Registry;
|
|
5
5
|
static connection: Connection;
|
|
6
6
|
static instances: Map<string, HotMesh | Promise<HotMesh>>;
|
|
7
7
|
workflowRunner: HotMesh;
|
|
8
8
|
activityRunner: HotMesh;
|
|
9
|
-
static getHotMesh: (
|
|
9
|
+
static getHotMesh: (workflowTopic: string, config?: Partial<WorkerConfig>, options?: WorkerOptions) => Promise<HotMesh>;
|
|
10
10
|
static activateWorkflow(hotMesh: HotMesh): Promise<void>;
|
|
11
|
-
/**
|
|
12
|
-
* NOTE: Because the worker imports the workflows dynamically AFTER
|
|
13
|
-
* the activities are loaded, there will be items in the registry,
|
|
14
|
-
* allowing proxyActivities to succeed.
|
|
15
|
-
*/
|
|
16
11
|
static registerActivities<ACT>(activities: ACT): Registry;
|
|
17
12
|
/**
|
|
18
13
|
* For those deployments with a redis stack backend (with the FT module),
|
|
19
|
-
* this method will configure the search index for the workflow.
|
|
14
|
+
* this method will configure the search index for the workflow. For all
|
|
15
|
+
* others, this method will fail gracefully. In all cases, the values
|
|
16
|
+
* will be stored in the workflow's central HASH data structure, allowing
|
|
17
|
+
* for manual traversal and inspection as well.
|
|
20
18
|
*/
|
|
21
19
|
static configureSearchIndex(hotMeshClient: HotMesh, search?: WorkflowSearchOptions): Promise<void>;
|
|
22
20
|
static create(config: WorkerConfig): Promise<WorkerService>;
|
|
@@ -31,6 +29,6 @@ export declare class WorkerService {
|
|
|
31
29
|
workflowTopic: string;
|
|
32
30
|
};
|
|
33
31
|
};
|
|
34
|
-
wrapWorkflowFunction(workflowFunction: Function, workflowTopic: string): Function;
|
|
32
|
+
wrapWorkflowFunction(workflowFunction: Function, workflowTopic: string, config: WorkerConfig): Function;
|
|
35
33
|
static shutdown(): Promise<void>;
|
|
36
34
|
}
|