@hotmeshio/hotmesh 0.0.54 → 0.0.56

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 (182) hide show
  1. package/README.md +0 -3
  2. package/build/modules/enums.js +1 -10
  3. package/build/modules/key.d.ts +0 -38
  4. package/build/modules/key.js +4 -46
  5. package/build/modules/utils.d.ts +0 -8
  6. package/build/modules/utils.js +0 -14
  7. package/build/package.json +11 -4
  8. package/build/services/activities/activity.d.ts +0 -28
  9. package/build/services/activities/activity.js +1 -46
  10. package/build/services/activities/await.js +0 -4
  11. package/build/services/activities/cycle.d.ts +0 -7
  12. package/build/services/activities/cycle.js +1 -16
  13. package/build/services/activities/hook.d.ts +0 -6
  14. package/build/services/activities/hook.js +2 -12
  15. package/build/services/activities/interrupt.js +0 -8
  16. package/build/services/activities/signal.d.ts +0 -6
  17. package/build/services/activities/signal.js +0 -15
  18. package/build/services/activities/trigger.d.ts +0 -4
  19. package/build/services/activities/trigger.js +1 -7
  20. package/build/services/activities/worker.js +0 -4
  21. package/build/services/collator/index.d.ts +0 -70
  22. package/build/services/collator/index.js +1 -91
  23. package/build/services/compiler/deployer.js +6 -38
  24. package/build/services/compiler/index.d.ts +0 -15
  25. package/build/services/compiler/index.js +0 -20
  26. package/build/services/compiler/validator.d.ts +0 -3
  27. package/build/services/compiler/validator.js +0 -25
  28. package/build/services/connector/clients/ioredis.d.ts +2 -2
  29. package/build/services/connector/clients/ioredis.js +0 -2
  30. package/build/services/connector/clients/redis.d.ts +4 -4
  31. package/build/services/connector/clients/redis.js +1 -3
  32. package/build/services/connector/index.d.ts +1 -1
  33. package/build/services/connector/index.js +0 -2
  34. package/build/services/durable/client.d.ts +1 -26
  35. package/build/services/durable/client.js +0 -56
  36. package/build/services/durable/exporter.d.ts +0 -22
  37. package/build/services/durable/exporter.js +1 -30
  38. package/build/services/durable/handle.d.ts +0 -36
  39. package/build/services/durable/handle.js +0 -46
  40. package/build/services/durable/index.d.ts +0 -4
  41. package/build/services/durable/index.js +0 -4
  42. package/build/services/durable/schemas/factory.d.ts +0 -29
  43. package/build/services/durable/schemas/factory.js +0 -29
  44. package/build/services/durable/search.d.ts +1 -36
  45. package/build/services/durable/search.js +57 -56
  46. package/build/services/durable/worker.js +2 -22
  47. package/build/services/durable/workflow.d.ts +0 -114
  48. package/build/services/durable/workflow.js +4 -144
  49. package/build/services/engine/index.d.ts +1 -6
  50. package/build/services/engine/index.js +1 -43
  51. package/build/services/exporter/index.d.ts +0 -27
  52. package/build/services/exporter/index.js +0 -33
  53. package/build/services/hotmesh/index.d.ts +2 -2
  54. package/build/services/hotmesh/index.js +1 -9
  55. package/build/services/logger/index.js +0 -2
  56. package/build/services/mapper/index.d.ts +0 -14
  57. package/build/services/mapper/index.js +0 -14
  58. package/build/services/pipe/functions/date.d.ts +0 -7
  59. package/build/services/pipe/functions/date.js +0 -7
  60. package/build/services/pipe/functions/math.js +0 -2
  61. package/build/services/pipe/index.d.ts +0 -15
  62. package/build/services/pipe/index.js +2 -23
  63. package/build/services/quorum/index.d.ts +0 -7
  64. package/build/services/quorum/index.js +0 -21
  65. package/build/services/reporter/index.d.ts +0 -5
  66. package/build/services/reporter/index.js +0 -9
  67. package/build/services/router/index.d.ts +0 -9
  68. package/build/services/router/index.js +2 -38
  69. package/build/services/serializer/index.js +7 -26
  70. package/build/services/store/cache.d.ts +0 -18
  71. package/build/services/store/cache.js +0 -18
  72. package/build/services/store/clients/ioredis.d.ts +1 -1
  73. package/build/services/store/clients/ioredis.js +0 -1
  74. package/build/services/store/clients/redis.d.ts +1 -1
  75. package/build/services/store/index.d.ts +0 -55
  76. package/build/services/store/index.js +5 -81
  77. package/build/services/stream/clients/ioredis.d.ts +1 -1
  78. package/build/services/stream/clients/ioredis.js +1 -4
  79. package/build/services/stream/clients/redis.d.ts +1 -1
  80. package/build/services/sub/clients/ioredis.d.ts +1 -1
  81. package/build/services/sub/clients/redis.d.ts +1 -1
  82. package/build/services/task/index.d.ts +0 -9
  83. package/build/services/task/index.js +0 -31
  84. package/build/services/telemetry/index.d.ts +0 -7
  85. package/build/services/telemetry/index.js +1 -13
  86. package/build/services/worker/index.d.ts +0 -4
  87. package/build/services/worker/index.js +2 -6
  88. package/build/types/activity.d.ts +0 -81
  89. package/build/types/durable.d.ts +25 -177
  90. package/build/types/exporter.d.ts +0 -13
  91. package/build/types/hotmesh.d.ts +4 -16
  92. package/build/types/hotmesh.js +0 -3
  93. package/build/types/index.d.ts +4 -6
  94. package/build/types/index.js +4 -3
  95. package/build/types/job.d.ts +1 -86
  96. package/build/types/pipe.d.ts +0 -65
  97. package/build/types/quorum.d.ts +15 -10
  98. package/build/types/redis.d.ts +225 -7
  99. package/build/types/redis.js +9 -0
  100. package/build/types/stream.d.ts +0 -58
  101. package/build/types/stream.js +0 -4
  102. package/package.json +11 -4
  103. package/types/durable.ts +121 -3
  104. package/types/hotmesh.ts +3 -6
  105. package/types/index.ts +23 -10
  106. package/types/job.ts +1 -1
  107. package/types/quorum.ts +22 -0
  108. package/types/redis.ts +267 -18
  109. package/build/types/ioredisclient.d.ts +0 -5
  110. package/build/types/ioredisclient.js +0 -5
  111. package/build/types/redisclient.d.ts +0 -26
  112. package/build/types/redisclient.js +0 -2
  113. package/modules/enums.ts +0 -62
  114. package/modules/errors.ts +0 -280
  115. package/modules/key.ts +0 -101
  116. package/modules/storage.ts +0 -3
  117. package/modules/utils.ts +0 -242
  118. package/services/activities/activity.ts +0 -589
  119. package/services/activities/await.ts +0 -113
  120. package/services/activities/cycle.ts +0 -115
  121. package/services/activities/hook.ts +0 -197
  122. package/services/activities/index.ts +0 -19
  123. package/services/activities/interrupt.ts +0 -172
  124. package/services/activities/signal.ts +0 -148
  125. package/services/activities/trigger.ts +0 -295
  126. package/services/activities/worker.ts +0 -107
  127. package/services/collator/README.md +0 -102
  128. package/services/collator/index.ts +0 -291
  129. package/services/compiler/deployer.ts +0 -504
  130. package/services/compiler/index.ts +0 -98
  131. package/services/compiler/validator.ts +0 -158
  132. package/services/connector/clients/ioredis.ts +0 -57
  133. package/services/connector/clients/redis.ts +0 -72
  134. package/services/connector/index.ts +0 -42
  135. package/services/durable/client.ts +0 -266
  136. package/services/durable/connection.ts +0 -10
  137. package/services/durable/exporter.ts +0 -232
  138. package/services/durable/handle.ts +0 -160
  139. package/services/durable/index.ts +0 -27
  140. package/services/durable/schemas/factory.ts +0 -2358
  141. package/services/durable/search.ts +0 -196
  142. package/services/durable/worker.ts +0 -401
  143. package/services/durable/workflow.ts +0 -557
  144. package/services/engine/index.ts +0 -761
  145. package/services/exporter/index.ts +0 -146
  146. package/services/hotmesh/index.ts +0 -237
  147. package/services/logger/index.ts +0 -79
  148. package/services/mapper/index.ts +0 -89
  149. package/services/pipe/functions/array.ts +0 -78
  150. package/services/pipe/functions/bitwise.ts +0 -27
  151. package/services/pipe/functions/conditional.ts +0 -35
  152. package/services/pipe/functions/date.ts +0 -220
  153. package/services/pipe/functions/index.ts +0 -27
  154. package/services/pipe/functions/json.ts +0 -11
  155. package/services/pipe/functions/logical.ts +0 -11
  156. package/services/pipe/functions/math.ts +0 -217
  157. package/services/pipe/functions/number.ts +0 -75
  158. package/services/pipe/functions/object.ts +0 -98
  159. package/services/pipe/functions/string.ts +0 -86
  160. package/services/pipe/functions/symbol.ts +0 -39
  161. package/services/pipe/functions/unary.ts +0 -19
  162. package/services/pipe/index.ts +0 -216
  163. package/services/quorum/index.ts +0 -319
  164. package/services/reporter/index.ts +0 -387
  165. package/services/router/index.ts +0 -426
  166. package/services/serializer/README.md +0 -10
  167. package/services/serializer/index.ts +0 -285
  168. package/services/store/cache.ts +0 -172
  169. package/services/store/clients/ioredis.ts +0 -145
  170. package/services/store/clients/redis.ts +0 -191
  171. package/services/store/index.ts +0 -1091
  172. package/services/stream/clients/ioredis.ts +0 -157
  173. package/services/stream/clients/redis.ts +0 -158
  174. package/services/stream/index.ts +0 -58
  175. package/services/sub/clients/ioredis.ts +0 -83
  176. package/services/sub/clients/redis.ts +0 -74
  177. package/services/sub/index.ts +0 -25
  178. package/services/task/index.ts +0 -250
  179. package/services/telemetry/index.ts +0 -273
  180. package/services/worker/index.ts +0 -248
  181. package/types/ioredisclient.ts +0 -10
  182. package/types/redisclient.ts +0 -30
@@ -26,12 +26,9 @@ class QuorumService {
26
26
  instance.guid = guid;
27
27
  instance.logger = logger;
28
28
  instance.engine = engine;
29
- //note: `quorum` shares/re-uses the engine's `store`/`sub` Redis clients
30
29
  await instance.initStoreChannel(config.engine.store);
31
30
  await instance.initSubChannel(config.engine.sub);
32
- //general quorum subscription
33
31
  await instance.subscribe.subscribe(hotmesh_1.KeyType.QUORUM, instance.subscriptionHandler(), appId);
34
- //app-specific quorum subscription (used for pubsub one-time request/response)
35
32
  await instance.subscribe.subscribe(hotmesh_1.KeyType.QUORUM, instance.subscriptionHandler(), appId, instance.guid);
36
33
  instance.engine.processWebHooks();
37
34
  instance.engine.processTimeHooks();
@@ -93,7 +90,6 @@ class QuorumService {
93
90
  else if (message.type === 'rollcall') {
94
91
  self.doRollCall(message);
95
92
  }
96
- //if there are any callbacks, call them
97
93
  if (self.callbacks.length > 0) {
98
94
  self.callbacks.forEach(cb => cb(topic, message));
99
95
  }
@@ -135,10 +131,6 @@ class QuorumService {
135
131
  await (0, utils_1.sleepFor)(delay);
136
132
  return quorum;
137
133
  }
138
- /**
139
- * A quorum-wide command to broadcaset system details.
140
- *
141
- */
142
134
  async doRollCall(message) {
143
135
  let iteration = 0;
144
136
  let max = !isNaN(message.max) ? message.max : enums_1.HMSH_QUORUM_ROLLCALL_CYCLES;
@@ -165,22 +157,15 @@ class QuorumService {
165
157
  stop() {
166
158
  this.cancelRollCall();
167
159
  }
168
- // ************* PUB/SUB METHODS *************
169
- //publish a message to the quorum
170
160
  async pub(quorumMessage) {
171
161
  return await this.store.publish(hotmesh_1.KeyType.QUORUM, quorumMessage, this.appId, quorumMessage.topic || quorumMessage.guid);
172
162
  }
173
- //subscribe user to quorum messages
174
163
  async sub(callback) {
175
- //the quorum is always subscribed to the `quorum` topic; just register the fn
176
164
  this.callbacks.push(callback);
177
165
  }
178
- //unsubscribe user from quorum messages
179
166
  async unsub(callback) {
180
- //the quorum is always subscribed to the `quorum` topic; just unregister the fn
181
167
  this.callbacks = this.callbacks.filter(cb => cb !== callback);
182
168
  }
183
- // ************* COMPILER METHODS *************
184
169
  async rollCall(delay = enums_1.HMSH_QUORUM_DELAY_MS) {
185
170
  await this.requestQuorum(delay, true);
186
171
  const targetStreams = [];
@@ -202,14 +187,10 @@ class QuorumService {
202
187
  });
203
188
  return this.profiles;
204
189
  }
205
- /**
206
- * request a quorum; if successful activate the app version
207
- */
208
190
  async activate(version, delay = enums_1.HMSH_QUORUM_DELAY_MS, count = 0) {
209
191
  version = version.toString();
210
192
  const canActivate = await this.store.reserveScoutRole('activate', Math.ceil(delay * 6 / 1000) + 1);
211
193
  if (!canActivate) {
212
- //another engine is already activating the app version
213
194
  this.logger.debug('quorum-activation-awaiting', { version });
214
195
  await (0, utils_1.sleepFor)(delay * 6);
215
196
  const app = await this.store.getApp(this.appId, true);
@@ -225,7 +206,6 @@ class QuorumService {
225
206
  this.store.publish(hotmesh_1.KeyType.QUORUM, { type: 'activate', cache_mode: 'nocache', until_version: version }, this.appId);
226
207
  await new Promise(resolve => setTimeout(resolve, delay));
227
208
  await this.store.releaseScoutRole('activate');
228
- //confirm we received the activation message
229
209
  if (this.engine.untilVersion === version) {
230
210
  this.logger.info('quorum-activation-succeeded', { version });
231
211
  const { id } = config;
@@ -241,7 +221,6 @@ class QuorumService {
241
221
  this.logger.warn('quorum-rollcall-error', { q1, q2, q3, count });
242
222
  this.store.releaseScoutRole('activate');
243
223
  if (count < enums_1.HMSH_ACTIVATION_MAX_RETRY) {
244
- //increase the delay (give the quorum time to respond) and try again
245
224
  return await this.activate(version, delay * 2, count + 1);
246
225
  }
247
226
  throw new Error(`Quorum not reached. Version ${version} not activated.`);
@@ -28,11 +28,6 @@ declare class ReporterService {
28
28
  getTargetForTime(key: string): string;
29
29
  getWorkItems(options: GetStatsOptions, facets: string[]): Promise<string[]>;
30
30
  private buildWorkerLists;
31
- /**
32
- * called by `trigger` activity to generate the stats that should
33
- * be saved to the database. doesn't actually save the stats, but
34
- * just generates the info that should be saved
35
- */
36
31
  resolveTriggerStatistics({ stats: statsConfig }: TriggerActivity, context: JobState): StatsType;
37
32
  isGeneralMetric(metric: string): boolean;
38
33
  isMedianMetric(metric: string): boolean;
@@ -27,11 +27,9 @@ class ReporterService {
27
27
  }
28
28
  generateDateTimeSets(granularity, range, end, start) {
29
29
  if (granularity === 'infinity') {
30
- //if granularity is infinity, it means a date/time sequence/slice is not used to further segment the statistics
31
30
  return ['0'];
32
31
  }
33
32
  if (!range) {
34
- //pluck just a single value when no range provided
35
33
  range = '0m';
36
34
  }
37
35
  const granularitiesInMinutes = {
@@ -49,7 +47,6 @@ class ReporterService {
49
47
  if (rangeMinutes === null) {
50
48
  throw new Error('Invalid range value.');
51
49
  }
52
- // If start is provided, use it. Otherwise, calculate it from the end time and range.
53
50
  let startTime;
54
51
  let endTime;
55
52
  if (start) {
@@ -60,7 +57,6 @@ class ReporterService {
60
57
  endTime = end === 'NOW' ? new Date() : new Date(end);
61
58
  startTime = new Date(endTime.getTime() - rangeMinutes * 60 * 1000);
62
59
  }
63
- // Round the start time to the nearest granularity unit
64
60
  startTime.setUTCMinutes(Math.floor(startTime.getUTCMinutes() / granularityMinutes) * granularityMinutes);
65
61
  const dateTimeSets = [];
66
62
  for (let time = startTime; time <= endTime; time.setUTCMinutes(time.getUTCMinutes() + granularityMinutes)) {
@@ -270,11 +266,6 @@ class ReporterService {
270
266
  }
271
267
  return workerLists;
272
268
  }
273
- /**
274
- * called by `trigger` activity to generate the stats that should
275
- * be saved to the database. doesn't actually save the stats, but
276
- * just generates the info that should be saved
277
- */
278
269
  resolveTriggerStatistics({ stats: statsConfig }, context) {
279
270
  const stats = {
280
271
  general: [],
@@ -30,15 +30,6 @@ declare class Router {
30
30
  private resetThrottleState;
31
31
  createGroup(stream: string, group: string): Promise<void>;
32
32
  publishMessage(topic: string, streamData: StreamData | StreamDataResponse, multi?: RedisMulti): Promise<string | RedisMulti>;
33
- /**
34
- * An adjustable throttle that will interrupt a sleeping
35
- * router if the throttle is reduced and the sleep time
36
- * has elapsed. If the throttle is increased, or if
37
- * the sleep time has not elapsed, the router will continue
38
- * to sleep until the new termination point. This
39
- * allows for dynamic, elastic throttling with smooth
40
- * acceleration and deceleration.
41
- */
42
33
  customSleep(): Promise<void>;
43
34
  consumeMessages(stream: string, group: string, consumer: string, callback: (streamData: StreamData) => Promise<StreamDataResponse | void>): Promise<void>;
44
35
  isStreamMessage(result: any): boolean;
@@ -47,22 +47,13 @@ class Router {
47
47
  const stream = this.store.mintKey(key_1.KeyType.STREAMS, { appId: this.store.appId, topic });
48
48
  return await this.store.xadd(stream, '*', 'message', JSON.stringify(streamData), multi);
49
49
  }
50
- /**
51
- * An adjustable throttle that will interrupt a sleeping
52
- * router if the throttle is reduced and the sleep time
53
- * has elapsed. If the throttle is increased, or if
54
- * the sleep time has not elapsed, the router will continue
55
- * to sleep until the new termination point. This
56
- * allows for dynamic, elastic throttling with smooth
57
- * acceleration and deceleration.
58
- */
59
50
  async customSleep() {
60
51
  if (this.throttle === 0)
61
52
  return;
62
53
  if (this.isSleeping)
63
54
  return;
64
55
  this.isSleeping = true;
65
- let startTime = Date.now(); //anchor the origin
56
+ let startTime = Date.now();
66
57
  await new Promise(async (outerResolve) => {
67
58
  this.sleepPromiseResolve = outerResolve;
68
59
  let elapsedTime = Date.now() - startTime;
@@ -90,7 +81,6 @@ class Router {
90
81
  return;
91
82
  }
92
83
  try {
93
- //randomizer that asymptotes at 150% of `HMSH_BLOCK_TIME_MS`
94
84
  const streamDuration = enums_1.HMSH_BLOCK_TIME_MS + Math.round((enums_1.HMSH_BLOCK_TIME_MS * Math.random()));
95
85
  const result = await this.stream.xreadgroup('GROUP', group, consumer, 'BLOCK', streamDuration, 'STREAMS', stream, '>');
96
86
  if (this.isStreamMessage(result)) {
@@ -99,7 +89,6 @@ class Router {
99
89
  await this.consumeOne(stream, group, id, message, callback);
100
90
  }
101
91
  }
102
- // Check for pending messages (note: Redis 6.2 simplifies)
103
92
  const now = Date.now();
104
93
  if (now - lastCheckedPendingMessagesAt > this.reclaimDelay) {
105
94
  lastCheckedPendingMessagesAt = now;
@@ -173,7 +162,6 @@ class Router {
173
162
  await (0, utils_1.sleepFor)(timeout);
174
163
  return await this.publishMessage(input.metadata.topic, {
175
164
  data: input.data,
176
- //note: retain guid (this is a retry attempt)
177
165
  metadata: { ...input.metadata, try: (input.metadata.try || 0) + 1 },
178
166
  policies: input.policies,
179
167
  });
@@ -193,24 +181,12 @@ class Router {
193
181
  }
194
182
  }
195
183
  shouldRetry(input, output) {
196
- //const isUnhandledEngineError = output.code === 500;
197
184
  const policies = input.policies?.retry;
198
185
  const errorCode = output.code.toString();
199
186
  const policy = policies?.[errorCode];
200
187
  const maxRetries = policy?.[0];
201
- // if (isUnhandledEngineError && !policy) {
202
- // //if main goes down, replicas take over within 5s
203
- // //if this is not system/platform related, the exponential
204
- // //backoff will be applied and eventually slow to a crawl while
205
- // //the root cause is identified
206
- // input.policies = { retry: { [errorCode]: [10] } };
207
- // return [true, 0];
208
- // }
209
188
  const tryCount = Math.min(input.metadata.try || 0, enums_1.HMSH_MAX_RETRIES);
210
- //only possible values for maxRetries are 1, 2, 3
211
- //only possible values for tryCount are 0, 1, 2
212
189
  if (maxRetries > tryCount) {
213
- // 10ms, 100ms, or 1000ms delays between system retries
214
190
  return [true, Math.pow(10, tryCount + 1)];
215
191
  }
216
192
  return [false, 0];
@@ -246,7 +222,6 @@ class Router {
246
222
  code,
247
223
  data,
248
224
  };
249
- //send unacknowleded errors to the engine (it has no topic)
250
225
  delete output.metadata.topic;
251
226
  return output;
252
227
  }
@@ -290,7 +265,6 @@ class Router {
290
265
  }
291
266
  const wasDecreased = delayInMillis < this.throttle;
292
267
  this.throttle = delayInMillis;
293
- // If the throttle was decreased, and we're in the middle of a sleep cycle, adjust immediately
294
268
  if (wasDecreased) {
295
269
  if (this.sleepTimout) {
296
270
  clearTimeout(this.sleepTimout);
@@ -302,7 +276,7 @@ class Router {
302
276
  }
303
277
  async claimUnacknowledged(stream, group, consumer, idleTimeMs = this.reclaimDelay, limit = enums_1.HMSH_XPENDING_COUNT) {
304
278
  let pendingMessages = [];
305
- const pendingMessagesInfo = await this.stream.xpending(stream, group, '-', '+', limit); //[[ '1688768134881-0', 'testConsumer1', 1017, 1 ]]
279
+ const pendingMessagesInfo = await this.stream.xpending(stream, group, '-', '+', limit);
306
280
  for (const pendingMessageInfo of pendingMessagesInfo) {
307
281
  if (Array.isArray(pendingMessageInfo)) {
308
282
  const [id, , elapsedTimeMs, deliveryCount] = pendingMessageInfo;
@@ -322,16 +296,8 @@ class Router {
322
296
  return pendingMessages;
323
297
  }
324
298
  async expireUnacknowledged(reclaimedMessage, stream, group, consumer, id, count) {
325
- //The stream activity was not processed within established limits. Possibilities Include:
326
- // 1) user error: the workers were not properly configured and are timing out
327
- // 2a) system error: JSON is corrupt
328
- // i) unwitting actor
329
- // ii) corrupt hardware/network/transport/etc
330
- // 3b) system error: Redis unable to accept `xadd` request
331
- // 4c) system error: Redis unable to accept `xdel`/`xack` request
332
299
  this.logger.error('stream-message-max-delivery-count-exceeded', { id, stream, group, consumer, code: enums_1.HMSH_CODE_UNACKED, count });
333
300
  const streamData = reclaimedMessage[0]?.[1]?.[1];
334
- //fatal risk point 1 of 3): json is corrupt
335
301
  const [err, input] = this.parseStreamData(streamData);
336
302
  if (err) {
337
303
  return this.logger.error('expire-unacknowledged-parse-fatal-error', { id, err });
@@ -345,11 +311,9 @@ class Router {
345
311
  telemetry = new telemetry_1.TelemetryService(this.appId);
346
312
  telemetry.startStreamSpan(input, stream_1.StreamRole.SYSTEM);
347
313
  telemetry.setStreamError(`Stream Message Max Delivery Count Exceeded`);
348
- //fatal risk point 2 of 3): unable to publish error message (to notify the parent job)
349
314
  const output = this.structureUnacknowledgedError(input);
350
315
  messageId = await this.publishResponse(input, output);
351
316
  telemetry.setStreamAttributes({ 'app.worker.mid': messageId });
352
- //fatal risk point 3 of 3): unable to ack and delete stream message
353
317
  await this.ackAndDelete(stream, group, id);
354
318
  }
355
319
  catch (err) {
@@ -49,7 +49,6 @@ class SerializerService {
49
49
  return this.dIds[activityId];
50
50
  }
51
51
  else if ('$ADJACENT' in this.dIds) {
52
- //else=> pre-authorizing adjacent activity entry
53
52
  return this.dIds['$ADJACENT'];
54
53
  }
55
54
  return ',0';
@@ -118,7 +117,6 @@ class SerializerService {
118
117
  result[shortDimensionalKey] = source[key];
119
118
  }
120
119
  else if (!(key in result) && this.isLiteralKeyType(key)) {
121
- //mark (-) and search (_)
122
120
  result[key] = source[key];
123
121
  }
124
122
  }
@@ -142,7 +140,6 @@ class SerializerService {
142
140
  const inflateWithMap = (abbreviationMap, id) => {
143
141
  const reversedAbbreviationMap = this.getReverseKeyMap(abbreviationMap, id);
144
142
  for (let key in result) {
145
- //strip dimensional index from key
146
143
  const shortKey = key.split(',')[0];
147
144
  let longKey = reversedAbbreviationMap.get(shortKey);
148
145
  if (longKey) {
@@ -159,38 +156,22 @@ class SerializerService {
159
156
  }
160
157
  return result;
161
158
  }
162
- //stringify: convert a multi-dimensional document to a 2-d hash
163
159
  stringify(document) {
164
160
  let result = {};
165
161
  for (let key in document) {
166
162
  let value = SerializerService.toString(document[key]);
167
163
  if (value) {
168
- if (/^:*[a-zA-Z]{2}$/.test(value)) {
169
- value = ':' + value;
170
- }
171
- else if (this.symValReverseMaps.has(value)) {
172
- value = this.symValReverseMaps.get(value);
173
- }
174
164
  result[key] = value;
175
165
  }
176
166
  }
177
167
  return result;
178
168
  }
179
- //parse: convert a 2-d hash to a multi-dimensional document
180
169
  parse(document) {
181
170
  let result = {};
182
171
  for (let [key, value] of Object.entries(document)) {
183
172
  if (value === undefined || value === null)
184
173
  continue;
185
- if (/^:+[a-zA-Z]{2}$/.test(value)) {
186
- result[key] = value.slice(1);
187
- }
188
- else {
189
- if (value?.length === 2 && this.symValMaps.has(value)) {
190
- value = this.symValMaps.get(value);
191
- }
192
- result[key] = SerializerService.fromString(value);
193
- }
174
+ result[key] = SerializerService.fromString(value);
194
175
  }
195
176
  return result;
196
177
  }
@@ -223,20 +204,20 @@ class SerializerService {
223
204
  const prefix = value.slice(0, 2);
224
205
  const rest = value.slice(2);
225
206
  switch (prefix) {
226
- case '/t': // boolean true
207
+ case '/t':
227
208
  return true;
228
- case '/f': // boolean false
209
+ case '/f':
229
210
  return false;
230
- case '/d': // number
211
+ case '/d':
231
212
  return Number(rest);
232
- case '/n': // null
213
+ case '/n':
233
214
  return null;
234
- case '/s': // object (JSON string)
215
+ case '/s':
235
216
  if (dateReg.exec(rest)) {
236
217
  return new Date(JSON.parse(rest));
237
218
  }
238
219
  return JSON.parse(rest);
239
- default: // string
220
+ default:
240
221
  return value;
241
222
  }
242
223
  }
@@ -1,9 +1,3 @@
1
- /**
2
- * The Cache is a key/value store and used to store commonly accessed Redis metadata
3
- * (mainly the execution rules for the app) to save time accessing them as they
4
- * are immutable per verison. The only time the rules are ejected are when
5
- * a new version is deployed to the quorum and the cache is invalidated/cleared.
6
- */
7
1
  import { ActivityType } from "../../types/activity";
8
2
  import { HookRule } from "../../types/hook";
9
3
  import { HotMeshApp, HotMeshSettings } from "../../types/hotmesh";
@@ -20,19 +14,7 @@ declare class Cache {
20
14
  transitions: Record<string, Record<string, unknown>>;
21
15
  hookRules: Record<string, Record<string, HookRule[]>>;
22
16
  workItems: Record<string, string>;
23
- /**
24
- * The cache is ALWAYS initialized with HotMeshSettings. The other parameters are optional.
25
- * @param settings
26
- * @param apps
27
- * @param schemas
28
- * @param subscriptions
29
- * @param transitions
30
- * @param hookRules
31
- */
32
17
  constructor(appId: string, settings: HotMeshSettings, apps?: Record<string, HotMeshApp>, schemas?: Record<string, ActivityType>, subscriptions?: Record<string, Record<string, string>>, symbols?: Record<string, Symbols>, symvals?: Record<string, Symbols>, transitions?: Record<string, Record<string, unknown>>, hookRules?: Record<string, Record<string, HookRule[]>>, workItems?: Record<string, string>);
33
- /**
34
- * invalidate the cache; settings are not invalidated!
35
- */
36
18
  invalidate(): void;
37
19
  getSettings(): HotMeshSettings;
38
20
  setSettings(settings: HotMeshSettings): void;
@@ -1,22 +1,7 @@
1
1
  "use strict";
2
- /**
3
- * The Cache is a key/value store and used to store commonly accessed Redis metadata
4
- * (mainly the execution rules for the app) to save time accessing them as they
5
- * are immutable per verison. The only time the rules are ejected are when
6
- * a new version is deployed to the quorum and the cache is invalidated/cleared.
7
- */
8
2
  Object.defineProperty(exports, "__esModule", { value: true });
9
3
  exports.Cache = void 0;
10
4
  class Cache {
11
- /**
12
- * The cache is ALWAYS initialized with HotMeshSettings. The other parameters are optional.
13
- * @param settings
14
- * @param apps
15
- * @param schemas
16
- * @param subscriptions
17
- * @param transitions
18
- * @param hookRules
19
- */
20
5
  constructor(appId, settings, apps = {}, schemas = {}, subscriptions = {}, symbols = {}, symvals = {}, transitions = {}, hookRules = {}, workItems = {}) {
21
6
  this.appId = appId;
22
7
  this.settings = settings;
@@ -29,9 +14,6 @@ class Cache {
29
14
  this.hookRules = hookRules;
30
15
  this.workItems = workItems;
31
16
  }
32
- /**
33
- * invalidate the cache; settings are not invalidated!
34
- */
35
17
  invalidate() {
36
18
  this.apps = {};
37
19
  this.schemas = {};
@@ -3,7 +3,7 @@ import { ILogger } from '../../logger';
3
3
  import { SerializerService as Serializer } from '../../serializer';
4
4
  import { Cache } from '../cache';
5
5
  import { StoreService } from '../index';
6
- import { RedisClientType, RedisMultiType } from '../../../types/ioredisclient';
6
+ import { IORedisClientType as RedisClientType, IORedisMultiType as RedisMultiType } from '../../../types/redis';
7
7
  import { ReclaimedMessageType } from '../../../types/stream';
8
8
  declare class IORedisStoreService extends StoreService<RedisClientType, RedisMultiType> {
9
9
  redisClient: RedisClientType;
@@ -24,7 +24,6 @@ class IORedisStoreService extends index_1.StoreService {
24
24
  return response;
25
25
  }
26
26
  hGetAllResult(result) {
27
- //ioredis response signature is [null, {}] or [null, null]
28
27
  return result[1];
29
28
  }
30
29
  async addTaskQueues(keys) {
@@ -3,7 +3,7 @@ import { ILogger } from '../../logger';
3
3
  import { SerializerService as Serializer } from '../../serializer';
4
4
  import { Cache } from '../cache';
5
5
  import { StoreService } from '../index';
6
- import { RedisClientType, RedisMultiType } from '../../../types/redisclient';
6
+ import { RedisRedisClientType as RedisClientType, RedisRedisMultiType as RedisMultiType } from '../../../types/redis';
7
7
  import { ReclaimedMessageType } from '../../../types/stream';
8
8
  declare class RedisStoreService extends StoreService<RedisClientType, RedisMultiType> {
9
9
  redisClient: RedisClientType;
@@ -41,11 +41,6 @@ declare abstract class StoreService<T, U extends AbstractRedisClient> {
41
41
  zRangeByScore(key: string, score: number | string, value: string | number): Promise<string | null>;
42
42
  mintKey(type: KeyType, params: KeyStoreParams): string;
43
43
  invalidateCache(): void;
44
- /**
45
- * At any given time only a single engine will
46
- * check for and process work items in the
47
- * time and signal task queues.
48
- */
49
44
  reserveScoutRole(scoutType: 'time' | 'signal' | 'activate', delay?: number): Promise<boolean>;
50
45
  releaseScoutRole(scoutType: 'time' | 'signal' | 'activate'): Promise<boolean>;
51
46
  getSettings(bCreate?: boolean): Promise<HotMeshSettings>;
@@ -64,16 +59,7 @@ declare abstract class StoreService<T, U extends AbstractRedisClient> {
64
59
  setApp(id: string, version: string): Promise<HotMeshApp>;
65
60
  activateAppVersion(id: string, version: string): Promise<boolean>;
66
61
  registerAppVersion(appId: string, version: string): Promise<any>;
67
- /**
68
- * Registers the job, `jobId`, with `originJobId`. In the future,
69
- * when `originJobId` is interrupted/expired, the items in the
70
- * list (added via RPUSH) will be interrupted/expired (removed via LPOPed).
71
- */
72
62
  registerJobDependency(depType: WorkListTaskType, originJobId: string, topic: string, jobId: string, gId: string, pd?: string, multi?: U): Promise<any>;
73
- /**
74
- * Ensures a `hook signal` is delisted when its parent activity/job
75
- * is interrupted/expired.
76
- */
77
63
  registerSignalDependency(jobId: string, signalKey: string, dad: string, multi?: U): Promise<any>;
78
64
  setStats(jobKey: string, jobId: string, dateTime: string, stats: StatsType, appVersion: AppVID, multi?: U): Promise<any>;
79
65
  hGetAllResult(result: any): any;
@@ -82,24 +68,10 @@ declare abstract class StoreService<T, U extends AbstractRedisClient> {
82
68
  setStatus(collationKeyStatus: number, jobId: string, appId: string, multi?: U): Promise<any>;
83
69
  getStatus(jobId: string, appId: string): Promise<number>;
84
70
  setState({ ...state }: StringAnyType, status: number | null, jobId: string, symbolNames: string[], dIds: StringStringType, multi?: U): Promise<string>;
85
- /**
86
- * Returns custom search fields and values.
87
- * NOTE: The `fields` param should NOT prefix items with an underscore.
88
- */
89
71
  getQueryState(jobId: string, fields: string[]): Promise<StringAnyType>;
90
72
  getState(jobId: string, consumes: Consumes, dIds: StringStringType): Promise<[StringAnyType, number] | undefined>;
91
73
  getRaw(jobId: string): Promise<StringStringType>;
92
- /**
93
- * collate is a generic method for incrementing a value in a hash
94
- * in order to track their progress during processing.
95
- */
96
74
  collate(jobId: string, activityId: string, amount: number, dIds: StringStringType, multi?: U): Promise<number>;
97
- /**
98
- * synthentic collation affects those activities in the graph
99
- * that represent the synthetic DAG that was materialized during compilation;
100
- * Synthetic targeting ensures that re-entry due to failure can be distinguished from
101
- * purposeful re-entry.
102
- */
103
75
  collateSynthetic(jobId: string, guid: string, amount: number, multi?: U): Promise<number>;
104
76
  setStateNX(jobId: string, appId: string): Promise<boolean>;
105
77
  getSchema(activityId: string, appVersion: AppVID): Promise<ActivityType>;
@@ -120,38 +92,11 @@ declare abstract class StoreService<T, U extends AbstractRedisClient> {
120
92
  deleteProcessedTaskQueue(workItemKey: string, key: string, processedKey: string, scrub?: boolean): Promise<void>;
121
93
  processTaskQueue(sourceKey: string, destinationKey: string): Promise<any>;
122
94
  expireJob(jobId: string, inSeconds: number): Promise<void>;
123
- /**
124
- * register the descendants of an expired origin flow to be
125
- * expired at a future date; options indicate whether this
126
- * is a standard `expire` or an `interrupt`
127
- */
128
95
  registerDependenciesForCleanup(jobId: string, deletionTime: number, options: JobCompletionOptions): Promise<void>;
129
96
  getDependencies(jobId: string): Promise<string[]>;
130
- /**
131
- * registers a hook activity to be awakened (uses ZSET to
132
- * store the 'sleep group' and LIST to store the events
133
- * for the given sleep group. Sleep groups are
134
- * organized into 'n'-second blocks (LISTS))
135
- */
136
97
  registerTimeHook(jobId: string, gId: string, activityId: string, type: WorkListTaskType, deletionTime: number, dad: string, multi?: U): Promise<void>;
137
98
  getNextTask(listKey?: string): Promise<[listKey: string, jobId: string, gId: string, activityId: string, type: WorkListTaskType] | boolean>;
138
- /**
139
- * when processing time jobs, the target LIST ID returned
140
- * from the ZSET query can be prefixed to denote what to
141
- * do with the work list. (not everything is known in advance,
142
- * so the ZSET key defines HOW to approach the work in the
143
- * generic LIST (lists typically contain target job ids)
144
- * @param {string} listKey - composite key
145
- */
146
99
  resolveTaskKeyContext(listKey: string): [WorkListTaskType, string];
147
- /**
148
- * Interrupts a job and sets sets a job error (410), if 'throw'!=false.
149
- * This method is called by the engine and not by an activity and is
150
- * followed by a call to execute job completion/cleanup tasks
151
- * associated with a job completion event.
152
- *
153
- * Todo: move most of this logic to the engine (too much logic for the store)
154
- */
155
100
  interrupt(topic: string, jobId: string, options?: JobInterruptOptions): Promise<void>;
156
101
  scrub(jobId: string): Promise<void>;
157
102
  findJobs(queryString?: string, limit?: number, batchSize?: number, cursor?: string): Promise<[string, string[]]>;