@hotmeshio/hotmesh 0.2.3 → 0.3.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.
Files changed (53) hide show
  1. package/README.md +14 -14
  2. package/build/modules/enums.d.ts +1 -0
  3. package/build/modules/enums.js +2 -1
  4. package/build/modules/errors.d.ts +1 -0
  5. package/build/modules/errors.js +1 -0
  6. package/build/modules/utils.d.ts +1 -0
  7. package/build/modules/utils.js +6 -10
  8. package/build/package.json +1 -1
  9. package/build/services/activities/activity.d.ts +3 -0
  10. package/build/services/activities/activity.js +24 -7
  11. package/build/services/activities/hook.js +3 -2
  12. package/build/services/activities/trigger.js +15 -5
  13. package/build/services/collator/index.d.ts +2 -0
  14. package/build/services/collator/index.js +12 -0
  15. package/build/services/compiler/deployer.js +1 -0
  16. package/build/services/engine/index.js +1 -0
  17. package/build/services/exporter/index.js +1 -1
  18. package/build/services/meshcall/index.d.ts +5 -5
  19. package/build/services/meshcall/index.js +45 -32
  20. package/build/services/meshcall/schemas/factory.js +2 -2
  21. package/build/services/meshdata/index.d.ts +2 -2
  22. package/build/services/meshdata/index.js +25 -20
  23. package/build/services/meshflow/client.js +3 -8
  24. package/build/services/meshflow/schemas/factory.d.ts +1 -1
  25. package/build/services/meshflow/schemas/factory.js +56 -10
  26. package/build/services/meshflow/worker.js +3 -5
  27. package/build/services/meshflow/workflow.js +10 -12
  28. package/build/services/router/index.js +3 -1
  29. package/build/services/store/clients/ioredis.d.ts +1 -0
  30. package/build/services/store/clients/ioredis.js +4 -0
  31. package/build/services/store/clients/redis.d.ts +1 -0
  32. package/build/services/store/clients/redis.js +5 -0
  33. package/build/services/store/index.d.ts +2 -3
  34. package/build/services/store/index.js +5 -36
  35. package/build/services/task/index.d.ts +1 -1
  36. package/build/services/task/index.js +3 -6
  37. package/build/types/activity.d.ts +2 -0
  38. package/build/types/error.d.ts +1 -0
  39. package/build/types/hook.d.ts +1 -0
  40. package/build/types/hotmesh.d.ts +1 -0
  41. package/build/types/job.d.ts +1 -1
  42. package/build/types/meshcall.d.ts +6 -2
  43. package/build/types/meshdata.d.ts +1 -1
  44. package/build/types/meshflow.d.ts +3 -0
  45. package/package.json +1 -1
  46. package/types/activity.ts +3 -1
  47. package/types/error.ts +1 -0
  48. package/types/hook.ts +6 -1
  49. package/types/hotmesh.ts +35 -0
  50. package/types/job.ts +4 -14
  51. package/types/meshcall.ts +19 -2
  52. package/types/meshdata.ts +9 -5
  53. package/types/meshflow.ts +12 -1
@@ -2,9 +2,11 @@
2
2
  var _a;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.MeshData = void 0;
5
+ const utils_1 = require("../../modules/utils");
5
6
  const meshflow_1 = require("../meshflow");
6
7
  const hotmesh_1 = require("../hotmesh");
7
8
  const hotmesh_2 = require("../../types/hotmesh");
9
+ const enums_1 = require("../../modules/enums");
8
10
  class MeshData {
9
11
  constructor(redisClass, redisOptions, search) {
10
12
  this.connectionSignatures = {};
@@ -161,7 +163,7 @@ class MeshData {
161
163
  this.connectionSignatures[entity] = target.toString();
162
164
  const targetFunction = {
163
165
  [entity]: async (...args) => {
164
- const { callOptions } = this.bindCallOptions(args, options);
166
+ const { callOptions } = this.bindCallOptions(args);
165
167
  const result = (await target.apply(target, args));
166
168
  await this.pauseForTTL(result, callOptions);
167
169
  return result;
@@ -177,19 +179,11 @@ class MeshData {
177
179
  });
178
180
  return true;
179
181
  }
180
- bindCallOptions(args, options, callOptions = {}) {
182
+ bindCallOptions(args, callOptions = {}) {
181
183
  if (args.length) {
182
184
  const lastArg = args[args.length - 1];
183
185
  if (lastArg instanceof Object && lastArg?.$type === 'exec') {
184
186
  callOptions = args.pop();
185
- if (options.ttl === 'infinity') {
186
- if (!callOptions) {
187
- callOptions = { ttl: 'infinity' };
188
- }
189
- else {
190
- callOptions.ttl = 'infinity';
191
- }
192
- }
193
187
  }
194
188
  else if (lastArg instanceof Object && lastArg.$type === 'hook') {
195
189
  callOptions = args.pop();
@@ -215,13 +209,6 @@ class MeshData {
215
209
  });
216
210
  const jobResponse = ['aAa', '/t', 'aBa', this.toString(result)];
217
211
  await store?.exec('HSET', jobKey, ...jobResponse);
218
- await this.publishDone(result, hotMesh, options);
219
- if (options.ttl === 'infinity') {
220
- await MeshData.workflow.waitFor(`flush-${options.$guid}`);
221
- }
222
- else {
223
- await MeshData.workflow.sleepFor(options.ttl);
224
- }
225
212
  }
226
213
  }
227
214
  async publishDone(result, hotMesh, options) {
@@ -278,9 +265,13 @@ class MeshData {
278
265
  async hook({ entity, id, hookEntity, hookArgs, options = {}, }) {
279
266
  const workflowId = MeshData.mintGuid(entity, id);
280
267
  this.validate(workflowId);
268
+ const args = [
269
+ ...hookArgs,
270
+ { ...options, $guid: workflowId, $type: 'hook' },
271
+ ];
281
272
  return await this.getClient().workflow.hook({
282
273
  namespace: options.namespace,
283
- args: [...hookArgs, { ...options, $guid: workflowId, $type: 'hook' }],
274
+ args,
284
275
  taskQueue: options.taskQueue ?? hookEntity,
285
276
  workflowName: hookEntity,
286
277
  workflowId: options.workflowId ?? workflowId,
@@ -301,6 +292,19 @@ class MeshData {
301
292
  }
302
293
  catch (e) {
303
294
  const optionsClone = { ...options };
295
+ let seconds;
296
+ if (optionsClone.ttl) {
297
+ if (optionsClone.signalIn !== false) {
298
+ optionsClone.signalIn = true;
299
+ }
300
+ if (optionsClone.ttl === 'infinity') {
301
+ delete optionsClone.ttl;
302
+ seconds = enums_1.MAX_DELAY;
303
+ }
304
+ else {
305
+ seconds = (0, utils_1.s)(optionsClone.ttl);
306
+ }
307
+ }
304
308
  delete optionsClone.search;
305
309
  delete optionsClone.config;
306
310
  const handle = await client.workflow.start({
@@ -316,8 +320,9 @@ class MeshData {
316
320
  await: options.await,
317
321
  marker: options.marker,
318
322
  pending: options.pending,
319
- expire: options.expire,
320
- signalIn: options.signalIn,
323
+ expire: seconds ?? options.expire,
324
+ persistent: options.signalIn == false ? undefined : seconds && true,
325
+ signalIn: optionsClone.signalIn,
321
326
  });
322
327
  if (options.await === false) {
323
328
  return handle.workflowId;
@@ -1,11 +1,7 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  var _a;
6
3
  Object.defineProperty(exports, "__esModule", { value: true });
7
4
  exports.ClientService = void 0;
8
- const ms_1 = __importDefault(require("ms"));
9
5
  const enums_1 = require("../../modules/enums");
10
6
  const utils_1 = require("../../modules/utils");
11
7
  const hotmesh_1 = require("../hotmesh");
@@ -68,14 +64,14 @@ class ClientService {
68
64
  arguments: [...options.args],
69
65
  originJobId: options.originJobId,
70
66
  expire: options.expire ?? enums_1.HMSH_EXPIRE_JOB_SECONDS,
67
+ persistent: options.persistent,
71
68
  signalIn: options.signalIn,
72
69
  parentWorkflowId: options.parentWorkflowId,
73
70
  workflowId: options.workflowId || hotmesh_1.HotMesh.guid(),
74
71
  workflowTopic: workflowTopic,
75
72
  backoffCoefficient: options.config?.backoffCoefficient || enums_1.HMSH_MESHFLOW_EXP_BACKOFF,
76
73
  maximumAttempts: options.config?.maximumAttempts || enums_1.HMSH_MESHFLOW_MAX_ATTEMPTS,
77
- maximumInterval: (0, ms_1.default)(options.config?.maximumInterval || enums_1.HMSH_MESHFLOW_MAX_INTERVAL) /
78
- 1000,
74
+ maximumInterval: (0, utils_1.s)(options.config?.maximumInterval || enums_1.HMSH_MESHFLOW_MAX_INTERVAL),
79
75
  };
80
76
  const context = { metadata: { trc, spn }, data: {} };
81
77
  const jobId = await hotMeshClient.pub(`${options.namespace ?? factory_1.APP_ID}.execute`, payload, context, {
@@ -97,8 +93,7 @@ class ClientService {
97
93
  workflowTopic,
98
94
  backoffCoefficient: options.config?.backoffCoefficient || enums_1.HMSH_MESHFLOW_EXP_BACKOFF,
99
95
  maximumAttempts: options.config?.maximumAttempts || enums_1.HMSH_MESHFLOW_MAX_ATTEMPTS,
100
- maximumInterval: (0, ms_1.default)(options.config?.maximumInterval || enums_1.HMSH_MESHFLOW_MAX_INTERVAL) /
101
- 1000,
96
+ maximumInterval: (0, utils_1.s)(options.config?.maximumInterval || enums_1.HMSH_MESHFLOW_MAX_INTERVAL),
102
97
  };
103
98
  const hotMeshClient = await this.getHotMeshClient(workflowTopic, options.namespace);
104
99
  const msgId = await hotMeshClient.hook(`${hotMeshClient.appId}.flow.signal`, payload, types_1.StreamStatus.PENDING, 202);
@@ -1,4 +1,4 @@
1
- declare const APP_VERSION = "3";
1
+ declare const APP_VERSION = "4";
2
2
  declare const APP_ID = "durable";
3
3
  declare const getWorkflowYAML: (app: string, version: string) => string;
4
4
  export { getWorkflowYAML, APP_VERSION, APP_ID };
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.APP_ID = exports.APP_VERSION = exports.getWorkflowYAML = void 0;
4
- const APP_VERSION = '3';
4
+ const APP_VERSION = '4';
5
5
  exports.APP_VERSION = APP_VERSION;
6
6
  const APP_ID = 'durable';
7
7
  exports.APP_ID = APP_ID;
@@ -12,14 +12,17 @@ const getWorkflowYAML = (app, version) => {
12
12
  graphs:
13
13
 
14
14
  ###################################################
15
- # THE MESHFLOW-REENTRANT-WORKFLOW #
15
+ # THE MESHFLOW-REENTRANT-WORKFLOW #
16
16
  # #
17
17
  - subscribes: ${app}.execute
18
18
  publishes: ${app}.executed
19
19
 
20
+ persistent: '{trigger.output.data.persistent}'
20
21
  expire:
21
22
  '@pipe':
22
- - ['{trigger.output.data.originJobId}', 0, '{trigger.output.data.expire}']
23
+ - ['{trigger.output.data.persistent}']
24
+ - ['{@number.isNaN}', '{trigger.output.data.originJobId}']
25
+ - ['{@logical.and}', 1,'{trigger.output.data.expire}']
23
26
  - ['{@conditional.ternary}']
24
27
 
25
28
  input:
@@ -52,6 +55,9 @@ const getWorkflowYAML = (app, version) => {
52
55
  expire:
53
56
  description: the time in seconds to expire the workflow in Redis once it completes
54
57
  type: number
58
+ persistent:
59
+ description: if true, the workflow emit the 'job completed' event while remaining open to outside signals
60
+ type: boolean
55
61
  signalIn:
56
62
  description: if false, the job will not support subordinated hooks
57
63
  type: boolean
@@ -136,11 +142,14 @@ const getWorkflowYAML = (app, version) => {
136
142
  type: string
137
143
  canRetry:
138
144
  type: boolean
145
+ expire:
146
+ type: number
139
147
  maps:
140
148
  originJobId: '{trigger.output.data.originJobId}'
141
149
  workflowId: '{trigger.output.data.workflowId}'
142
150
  arguments: '{trigger.output.data.arguments}'
143
151
  workflowTopic: '{trigger.output.data.workflowTopic}'
152
+ expire: '{trigger.output.data.expire}'
144
153
  canRetry:
145
154
  '@pipe':
146
155
  - '@pipe':
@@ -208,6 +217,8 @@ const getWorkflowYAML = (app, version) => {
208
217
  type: number
209
218
  expire:
210
219
  type: number
220
+ persistent:
221
+ type: boolean
211
222
  signalIn:
212
223
  type: boolean
213
224
  await:
@@ -313,6 +324,8 @@ const getWorkflowYAML = (app, version) => {
313
324
  type: number
314
325
  expire:
315
326
  type: number
327
+ persistent:
328
+ type: boolean
316
329
  signalIn:
317
330
  type: boolean
318
331
  parentWorkflowId:
@@ -336,6 +349,7 @@ const getWorkflowYAML = (app, version) => {
336
349
  originJobId: '{worker.output.data.originJobId}'
337
350
  parentWorkflowId: '{worker.output.data.parentWorkflowId}'
338
351
  expire: '{worker.output.data.expire}'
352
+ persistent: '{worker.output.data.persistent}'
339
353
  signalIn: '{worker.output.data.signalIn}'
340
354
  workflowId: '{worker.output.data.workflowId}'
341
355
  workflowName: '{worker.output.data.workflowName}'
@@ -643,6 +657,8 @@ const getWorkflowYAML = (app, version) => {
643
657
  type: number
644
658
  data:
645
659
  type: object
660
+ expire:
661
+ type: number
646
662
  maps:
647
663
  items: '{worker.output.data.items}'
648
664
  size: '{worker.output.data.size}'
@@ -652,6 +668,7 @@ const getWorkflowYAML = (app, version) => {
652
668
  parentWorkflowId: '{worker.output.data.workflowId}'
653
669
  workflowId: '{worker.output.data.workflowId}'
654
670
  workflowTopic: '{worker.output.data.workflowTopic}'
671
+ expire: '{worker.output.data.expire}'
655
672
  output:
656
673
  schema:
657
674
  type: object
@@ -740,8 +757,9 @@ const getWorkflowYAML = (app, version) => {
740
757
  - ['{@logical.or}']
741
758
  - ['{@math.min}']
742
759
  ender:
743
- title: Sets job data; ignores the \`Signal In\` Hook Channel which was suppressed
760
+ title: Sets job data; ignores the \`Signal In\` Hook Channel which was suppressed; sends the final response
744
761
  type: hook
762
+ persist: '{trigger.output.data.signalIn}'
745
763
  job:
746
764
  maps:
747
765
  done: true
@@ -854,11 +872,14 @@ const getWorkflowYAML = (app, version) => {
854
872
  type: array
855
873
  canRetry:
856
874
  type: boolean
875
+ expire:
876
+ type: number
857
877
  maps:
858
878
  workflowId: '{trigger.output.data.workflowId}'
859
879
  originJobId: '{trigger.output.data.originJobId}'
860
880
  workflowDimension: '{signaler.output.metadata.dad}'
861
881
  arguments: '{signaler.hook.data.arguments}'
882
+ expire: '{trigger.output.data.expire}'
862
883
  canRetry:
863
884
  '@pipe':
864
885
  - '@pipe':
@@ -938,6 +959,8 @@ const getWorkflowYAML = (app, version) => {
938
959
  description: the maximum time in seconds to wait between retries; provides a fixed limit to exponential backoff growth
939
960
  expire:
940
961
  type: number
962
+ persistent:
963
+ type: boolean
941
964
  signalIn:
942
965
  type: boolean
943
966
  description: if false, the spawned child will not support subordinated hooks
@@ -1043,6 +1066,8 @@ const getWorkflowYAML = (app, version) => {
1043
1066
  type: number
1044
1067
  expire:
1045
1068
  type: number
1069
+ persistent:
1070
+ type: boolean
1046
1071
  signalIn:
1047
1072
  type: boolean
1048
1073
  parentWorkflowId:
@@ -1066,6 +1091,7 @@ const getWorkflowYAML = (app, version) => {
1066
1091
  originJobId: '{signaler_worker.output.data.originJobId}'
1067
1092
  parentWorkflowId: '{signaler_worker.output.data.parentWorkflowId}'
1068
1093
  expire: '{signaler_worker.output.data.expire}'
1094
+ persistent: '{signaler_worker.output.data.persistent}'
1069
1095
  signalIn: '{signaler_worker.output.data.signalIn}'
1070
1096
  workflowId: '{signaler_worker.output.data.workflowId}'
1071
1097
  workflowName: '{signaler_worker.output.data.workflowName}'
@@ -1373,6 +1399,8 @@ const getWorkflowYAML = (app, version) => {
1373
1399
  type: number
1374
1400
  data:
1375
1401
  type: object
1402
+ expire:
1403
+ type: number
1376
1404
  maps:
1377
1405
  items: '{signaler_worker.output.data.items}'
1378
1406
  size: '{signaler_worker.output.data.size}'
@@ -1382,6 +1410,7 @@ const getWorkflowYAML = (app, version) => {
1382
1410
  parentWorkflowId: '{signaler_worker.output.data.workflowId}'
1383
1411
  workflowId: '{signaler_worker.output.data.workflowId}'
1384
1412
  workflowTopic: '{signaler_worker.output.data.workflowTopic}'
1413
+ expire: '{signaler_worker.output.data.expire}'
1385
1414
  output:
1386
1415
  schema:
1387
1416
  type: object
@@ -1494,8 +1523,8 @@ const getWorkflowYAML = (app, version) => {
1494
1523
  - expected: false
1495
1524
  actual:
1496
1525
  '@pipe':
1497
- - ['{trigger.output.data.signalIn}', true]
1498
- - ['{@conditional.nullish}']
1526
+ - ['{trigger.output.data.signalIn}', '{@symbol.undefined}']
1527
+ - ['{@conditional.strict_equality}']
1499
1528
  - to: closer
1500
1529
  conditions:
1501
1530
  code: [200, 596, 597, 598]
@@ -1503,8 +1532,8 @@ const getWorkflowYAML = (app, version) => {
1503
1532
  - expected: true
1504
1533
  actual:
1505
1534
  '@pipe':
1506
- - ['{trigger.output.data.signalIn}', true]
1507
- - ['{@conditional.nullish}']
1535
+ - ['{trigger.output.data.signalIn}', '{@symbol.undefined}']
1536
+ - ['{@conditional.strict_equality}']
1508
1537
  - to: sleeper
1509
1538
  conditions:
1510
1539
  code: 588
@@ -1631,7 +1660,10 @@ const getWorkflowYAML = (app, version) => {
1631
1660
  - subscribes: ${app}.collator.execute
1632
1661
  publishes: ${app}.collator.executed
1633
1662
 
1634
- expire: 0
1663
+ expire:
1664
+ '@pipe':
1665
+ - ['{collator_trigger.output.data.expire}', 1]
1666
+ - ['{@conditional.nullish}']
1635
1667
 
1636
1668
  input:
1637
1669
  schema:
@@ -1658,6 +1690,8 @@ const getWorkflowYAML = (app, version) => {
1658
1690
  type: index
1659
1691
  data:
1660
1692
  type: object
1693
+ expire:
1694
+ type: number
1661
1695
  output:
1662
1696
  schema:
1663
1697
  type: object
@@ -1799,6 +1833,8 @@ const getWorkflowYAML = (app, version) => {
1799
1833
  type: number
1800
1834
  expire:
1801
1835
  type: number
1836
+ persistent:
1837
+ type: boolean
1802
1838
  signalIn:
1803
1839
  type: boolean
1804
1840
  parentWorkflowId:
@@ -1840,6 +1876,11 @@ const getWorkflowYAML = (app, version) => {
1840
1876
  - ['{collator_trigger.output.data.items}', '{collator_cycle_hook.output.data.cur_index}']
1841
1877
  - ['{@array.get}', expire]
1842
1878
  - ['{@object.get}']
1879
+ persistent:
1880
+ '@pipe':
1881
+ - ['{collator_trigger.output.data.items}', '{collator_cycle_hook.output.data.cur_index}']
1882
+ - ['{@array.get}', persistent]
1883
+ - ['{@object.get}']
1843
1884
  signalIn:
1844
1885
  '@pipe':
1845
1886
  - ['{collator_trigger.output.data.items}', '{collator_cycle_hook.output.data.cur_index}']
@@ -2230,7 +2271,10 @@ const getWorkflowYAML = (app, version) => {
2230
2271
  - subscribes: ${app}.activity.execute
2231
2272
  publishes: ${app}.activity.executed
2232
2273
 
2233
- expire: 0
2274
+ expire:
2275
+ '@pipe':
2276
+ - ['{activity_trigger.output.data.expire}', 1]
2277
+ - ['{@conditional.nullish}']
2234
2278
 
2235
2279
  input:
2236
2280
  schema:
@@ -2254,6 +2298,8 @@ const getWorkflowYAML = (app, version) => {
2254
2298
  type: number
2255
2299
  maximumInterval:
2256
2300
  type: number
2301
+ expire:
2302
+ type: number
2257
2303
  output:
2258
2304
  schema:
2259
2305
  type: object
@@ -1,11 +1,7 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  var _a;
6
3
  Object.defineProperty(exports, "__esModule", { value: true });
7
4
  exports.WorkerService = void 0;
8
- const ms_1 = __importDefault(require("ms"));
9
5
  const enums_1 = require("../../modules/enums");
10
6
  const errors_1 = require("../../modules/errors");
11
7
  const storage_1 = require("../../modules/storage");
@@ -196,6 +192,7 @@ class WorkerService {
196
192
  const workflowInput = data.data;
197
193
  const context = new Map();
198
194
  context.set('canRetry', workflowInput.canRetry);
195
+ context.set('expire', workflowInput.expire);
199
196
  context.set('counter', counter);
200
197
  context.set('interruptionRegistry', interruptionRegistry);
201
198
  context.set('connection', config.connection);
@@ -326,10 +323,11 @@ class WorkerService {
326
323
  index: err.index,
327
324
  message: JSON.stringify(msg),
328
325
  maximumAttempts: err.maximumAttempts || enums_1.HMSH_MESHFLOW_MAX_ATTEMPTS,
329
- maximumInterval: err.maximumInterval || (0, ms_1.default)(enums_1.HMSH_MESHFLOW_MAX_INTERVAL) / 1000,
326
+ maximumInterval: err.maximumInterval || (0, utils_1.s)(enums_1.HMSH_MESHFLOW_MAX_INTERVAL),
330
327
  originJobId: err.originJobId,
331
328
  parentWorkflowId: err.parentWorkflowId,
332
329
  expire: err.expire,
330
+ persistent: err.persistent,
333
331
  signalIn: err.signalIn,
334
332
  workflowDimension: err.workflowDimension,
335
333
  workflowId: err.workflowId,
@@ -1,10 +1,6 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.WorkflowService = void 0;
7
- const ms_1 = __importDefault(require("ms"));
8
4
  const errors_1 = require("../../modules/errors");
9
5
  const key_1 = require("../../modules/key");
10
6
  const storage_1 = require("../../modules/storage");
@@ -59,6 +55,7 @@ class WorkflowService {
59
55
  const workflowTrace = store.get('workflowTrace');
60
56
  const canRetry = store.get('canRetry');
61
57
  const workflowSpan = store.get('workflowSpan');
58
+ const expire = store.get('expire');
62
59
  const COUNTER = store.get('counter');
63
60
  const raw = store.get('raw');
64
61
  return {
@@ -68,6 +65,7 @@ class WorkflowService {
68
65
  cursor,
69
66
  interruptionRegistry,
70
67
  connection,
68
+ expire,
71
69
  namespace,
72
70
  originJobId,
73
71
  raw,
@@ -131,7 +129,7 @@ class WorkflowService {
131
129
  throw new errors_1.MeshFlowChildError(interruptionMessage);
132
130
  }
133
131
  static getChildInterruptPayload(context, options, execIndex) {
134
- const { workflowId, originJobId, workflowDimension } = context;
132
+ const { workflowId, originJobId, workflowDimension, expire } = context;
135
133
  let childJobId;
136
134
  if (options.workflowId) {
137
135
  childJobId = options.workflowId;
@@ -152,10 +150,10 @@ class WorkflowService {
152
150
  backoffCoefficient: options?.config?.backoffCoefficient ?? enums_1.HMSH_MESHFLOW_EXP_BACKOFF,
153
151
  index: execIndex,
154
152
  maximumAttempts: options?.config?.maximumAttempts ?? enums_1.HMSH_MESHFLOW_MAX_ATTEMPTS,
155
- maximumInterval: (0, ms_1.default)(options?.config?.maximumInterval ?? enums_1.HMSH_MESHFLOW_MAX_INTERVAL) /
156
- 1000,
153
+ maximumInterval: (0, utils_1.s)(options?.config?.maximumInterval ?? enums_1.HMSH_MESHFLOW_MAX_INTERVAL),
157
154
  originJobId: originJobId ?? workflowId,
158
- expire: options.expire,
155
+ expire: options.expire ?? expire,
156
+ persistent: options.persistent,
159
157
  signalIn: options.signalIn,
160
158
  parentWorkflowId,
161
159
  workflowDimension: workflowDimension,
@@ -215,12 +213,12 @@ class WorkflowService {
215
213
  };
216
214
  }
217
215
  static getProxyInterruptPayload(context, activityName, execIndex, args, options) {
218
- const { workflowDimension, workflowId, originJobId, workflowTopic } = context;
216
+ const { workflowDimension, workflowId, originJobId, workflowTopic, expire, } = context;
219
217
  const activityTopic = `${workflowTopic}-activity`;
220
218
  const activityJobId = `-${workflowId}-$${activityName}${workflowDimension}-${execIndex}`;
221
219
  let maximumInterval;
222
220
  if (options.retryPolicy?.maximumInterval) {
223
- maximumInterval = (0, ms_1.default)(options.retryPolicy.maximumInterval) / 1000;
221
+ maximumInterval = (0, utils_1.s)(options.retryPolicy.maximumInterval);
224
222
  }
225
223
  return {
226
224
  arguments: args,
@@ -231,7 +229,7 @@ class WorkflowService {
231
229
  workflowId: activityJobId,
232
230
  workflowTopic: activityTopic,
233
231
  activityName,
234
- expire: options.expire,
232
+ expire: options.expire ?? expire,
235
233
  backoffCoefficient: options?.retryPolicy?.backoffCoefficient ?? undefined,
236
234
  maximumAttempts: options?.retryPolicy?.maximumAttempts ?? undefined,
237
235
  maximumInterval: maximumInterval ?? undefined,
@@ -351,7 +349,7 @@ class WorkflowService {
351
349
  const workflowDimension = store.get('workflowDimension') ?? '';
352
350
  const interruptionMessage = {
353
351
  workflowId,
354
- duration: (0, ms_1.default)(duration) / 1000,
352
+ duration: (0, utils_1.s)(duration),
355
353
  index: execIndex,
356
354
  workflowDimension,
357
355
  };
@@ -74,8 +74,10 @@ class Router {
74
74
  });
75
75
  }
76
76
  async consumeMessages(stream, group, consumer, callback) {
77
- if (this.readonly)
77
+ if (this.readonly) {
78
+ this.logger.info(`router-stream-readonly`, { group, consumer, stream });
78
79
  return;
80
+ }
79
81
  this.logger.info(`router-stream-starting`, { group, consumer, stream });
80
82
  Router.instances.add(this);
81
83
  this.shouldConsume = true;
@@ -15,6 +15,7 @@ declare class IORedisStoreService extends StoreService<RedisClientType, RedisMul
15
15
  constructor(redisClient: RedisClientType);
16
16
  getMulti(): RedisMultiType;
17
17
  exec(...args: any[]): Promise<string | string[] | string[][]>;
18
+ setnxex(key: string, value: string, expireSeconds: number): Promise<boolean>;
18
19
  hGetAllResult(result: any): any;
19
20
  addTaskQueues(keys: string[]): Promise<void>;
20
21
  publish(keyType: KeyType.QUORUM, message: Record<string, any>, appId: string, engineId?: string): Promise<boolean>;
@@ -122,6 +122,10 @@ class IORedisStoreService extends index_1.StoreService {
122
122
  }
123
123
  return response;
124
124
  }
125
+ async setnxex(key, value, expireSeconds) {
126
+ const status = await this.redisClient[this.commands.set](key, value, 'NX', 'EX', expireSeconds.toString());
127
+ return this.isSuccessful(status);
128
+ }
125
129
  hGetAllResult(result) {
126
130
  return result[1];
127
131
  }
@@ -16,6 +16,7 @@ declare class RedisStoreService extends StoreService<RedisClientType, RedisMulti
16
16
  constructor(redisClient: RedisClientType);
17
17
  getMulti(): RedisMultiType;
18
18
  exec(...args: any[]): Promise<string | string[] | string[][]>;
19
+ setnxex(key: string, value: string, expireSeconds: number): Promise<boolean>;
19
20
  publish(keyType: KeyType.QUORUM, message: Record<string, any>, appId: string, engineId?: string): Promise<boolean>;
20
21
  zAdd(key: string, score: number | string, value: string | number, redisMulti?: RedisMultiType): Promise<any>;
21
22
  zRangeByScoreWithScores(key: string, score: number | string, value: string | number): Promise<string | null>;
@@ -7,6 +7,7 @@ class RedisStoreService extends index_1.StoreService {
7
7
  constructor(redisClient) {
8
8
  super(redisClient);
9
9
  this.commands = {
10
+ get: 'GET',
10
11
  set: 'SET',
11
12
  setnx: 'SETNX',
12
13
  del: 'DEL',
@@ -172,6 +173,10 @@ class RedisStoreService extends index_1.StoreService {
172
173
  async exec(...args) {
173
174
  return await this.redisClient.sendCommand(args);
174
175
  }
176
+ async setnxex(key, value, expireSeconds) {
177
+ const status = await this.redisClient[this.commands.set](key, value, { NX: true, EX: expireSeconds });
178
+ return this.isSuccessful(status);
179
+ }
175
180
  async publish(keyType, message, appId, engineId) {
176
181
  const topic = this.mintKey(keyType, { appId, engineId });
177
182
  const status = await this.redisClient.publish(topic, JSON.stringify(message));
@@ -9,7 +9,7 @@ import { SymbolSets, StringStringType, StringAnyType, Symbols } from '../../type
9
9
  import { IdsData, JobStatsRange, StatsType } from '../../types/stats';
10
10
  import { Transitions } from '../../types/transition';
11
11
  import { ReclaimedMessageType } from '../../types/stream';
12
- import { JobCompletionOptions, JobInterruptOptions } from '../../types/job';
12
+ import { JobInterruptOptions } from '../../types/job';
13
13
  import { WorkListTaskType } from '../../types/task';
14
14
  import { ThrottleOptions } from '../../types/quorum';
15
15
  import { Cache } from './cache';
@@ -26,6 +26,7 @@ declare abstract class StoreService<T, U extends AbstractRedisClient> {
26
26
  commands: Record<string, string>;
27
27
  abstract getMulti(): U;
28
28
  abstract exec(...args: any[]): Promise<string | string[] | string[][]>;
29
+ abstract setnxex(key: string, value: string, expireSeconds: number): Promise<boolean>;
29
30
  abstract publish(keyType: KeyType.QUORUM, message: Record<string, any>, appId: string, engineId?: string): Promise<boolean>;
30
31
  abstract xgroup(command: 'CREATE', key: string, groupName: string, id: string, mkStream?: 'MKSTREAM'): Promise<boolean>;
31
32
  abstract xadd(key: string, id: string, messageId: string, messageValue: string, multi?: U): Promise<string | U>;
@@ -61,7 +62,6 @@ declare abstract class StoreService<T, U extends AbstractRedisClient> {
61
62
  activateAppVersion(id: string, version: string): Promise<boolean>;
62
63
  registerAppVersion(appId: string, version: string): Promise<any>;
63
64
  registerJobDependency(depType: WorkListTaskType, originJobId: string, topic: string, jobId: string, gId: string, pd?: string, multi?: U): Promise<any>;
64
- registerSignalDependency(jobId: string, signalKey: string, dad: string, multi?: U): Promise<any>;
65
65
  setStats(jobKey: string, jobId: string, dateTime: string, stats: StatsType, appVersion: AppVID, multi?: U): Promise<any>;
66
66
  hGetAllResult(result: any): any;
67
67
  getJobStats(jobKeys: string[]): Promise<JobStatsRange>;
@@ -93,7 +93,6 @@ declare abstract class StoreService<T, U extends AbstractRedisClient> {
93
93
  deleteProcessedTaskQueue(workItemKey: string, key: string, processedKey: string, scrub?: boolean): Promise<void>;
94
94
  processTaskQueue(sourceKey: string, destinationKey: string): Promise<any>;
95
95
  expireJob(jobId: string, inSeconds: number, redisMulti?: U): Promise<void>;
96
- registerDependenciesForCleanup(jobId: string, deletionTime: number, options: JobCompletionOptions): Promise<void>;
97
96
  getDependencies(jobId: string): Promise<string[]>;
98
97
  registerTimeHook(jobId: string, gId: string, activityId: string, type: WorkListTaskType, deletionTime: number, dad: string, multi?: U): Promise<void>;
99
98
  getNextTask(listKey?: string): Promise<[