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