@hotmeshio/hotmesh 0.0.12 → 0.0.14
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 +2 -2
- package/build/modules/errors.d.ts +22 -1
- package/build/modules/errors.js +28 -1
- package/build/modules/utils.d.ts +2 -1
- package/build/modules/utils.js +5 -1
- package/build/package.json +7 -2
- package/build/services/activities/activity.d.ts +2 -0
- package/build/services/activities/activity.js +16 -10
- package/build/services/activities/await.d.ts +2 -6
- package/build/services/activities/await.js +12 -75
- package/build/services/activities/cycle.js +2 -2
- package/build/services/activities/index.d.ts +2 -2
- package/build/services/activities/index.js +2 -2
- package/build/services/activities/signal.d.ts +16 -0
- package/build/services/activities/signal.js +94 -0
- package/build/services/activities/trigger.js +4 -3
- package/build/services/activities/worker.d.ts +2 -1
- package/build/services/activities/worker.js +11 -6
- package/build/services/compiler/deployer.js +3 -1
- package/build/services/durable/client.d.ts +3 -2
- package/build/services/durable/client.js +39 -21
- package/build/services/durable/factory.d.ts +22 -18
- package/build/services/durable/factory.js +722 -50
- package/build/services/durable/handle.d.ts +1 -0
- package/build/services/durable/handle.js +5 -1
- package/build/services/durable/worker.d.ts +3 -8
- package/build/services/durable/worker.js +75 -73
- package/build/services/durable/workflow.d.ts +5 -0
- package/build/services/durable/workflow.js +93 -24
- package/build/services/engine/index.d.ts +6 -6
- package/build/services/engine/index.js +25 -15
- package/build/services/hotmesh/index.d.ts +2 -1
- package/build/services/hotmesh/index.js +3 -1
- package/build/services/mapper/index.js +1 -1
- package/build/services/pipe/functions/array.d.ts +1 -0
- package/build/services/pipe/functions/array.js +3 -0
- package/build/services/reporter/index.js +9 -2
- package/build/services/signaler/store.js +8 -3
- package/build/services/signaler/stream.js +3 -3
- package/build/services/store/clients/ioredis.js +15 -15
- package/build/services/store/clients/redis.js +18 -18
- package/build/services/store/index.d.ts +1 -1
- package/build/services/store/index.js +11 -3
- package/build/services/task/index.js +3 -3
- package/build/types/activity.d.ts +15 -6
- package/build/types/durable.d.ts +15 -2
- package/build/types/index.d.ts +2 -2
- package/build/types/stats.d.ts +1 -0
- package/modules/errors.ts +35 -0
- package/modules/utils.ts +5 -1
- package/package.json +7 -2
- package/services/activities/activity.ts +19 -9
- package/services/activities/await.ts +14 -90
- package/services/activities/cycle.ts +2 -2
- package/services/activities/index.ts +2 -2
- package/services/activities/signal.ts +124 -0
- package/services/activities/trigger.ts +4 -3
- package/services/activities/worker.ts +13 -13
- package/services/compiler/deployer.ts +3 -1
- package/services/durable/client.ts +48 -23
- package/services/durable/factory.ts +723 -49
- package/services/durable/handle.ts +6 -1
- package/services/durable/worker.ts +92 -79
- package/services/durable/workflow.ts +95 -25
- package/services/engine/index.ts +33 -24
- package/services/hotmesh/index.ts +7 -4
- package/services/mapper/index.ts +1 -1
- package/services/pipe/functions/array.ts +4 -0
- package/services/reporter/index.ts +10 -2
- package/services/signaler/store.ts +8 -3
- package/services/signaler/stream.ts +3 -3
- package/services/store/clients/ioredis.ts +15 -15
- package/services/store/clients/redis.ts +18 -18
- package/services/store/index.ts +12 -3
- package/services/task/index.ts +3 -3
- package/types/activity.ts +16 -7
- package/types/durable.ts +18 -1
- package/types/index.ts +2 -1
- package/types/stats.ts +1 -0
- package/build/services/activities/emit.d.ts +0 -9
- package/build/services/activities/emit.js +0 -13
- package/services/activities/emit.ts +0 -25
|
@@ -45,12 +45,17 @@ class ReporterService {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
private validateOptions(options: GetStatsOptions): void {
|
|
48
|
-
const { start, end, range } = options;
|
|
49
|
-
if (start && end && range || !start && !end && !range) {
|
|
48
|
+
const { start, end, range, granularity } = options;
|
|
49
|
+
if (granularity !== 'infinity' && (start && end && range || !start && !end && !range)) {
|
|
50
50
|
throw new Error('Invalid combination of start, end, and range values. Provide either start+end, end+range, or start+range.');
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
|
+
|
|
53
54
|
private generateDateTimeSets(granularity: string, range: string|undefined, end: string, start?: string): string[] {
|
|
55
|
+
if (granularity === 'infinity') {
|
|
56
|
+
//if granularity is infinity, it means a date/time sequence/slice is not used to further segment the statistics
|
|
57
|
+
return ['0'];
|
|
58
|
+
}
|
|
54
59
|
if (!range) {
|
|
55
60
|
//pluck just a single value when no range provided
|
|
56
61
|
range = '0m';
|
|
@@ -190,6 +195,9 @@ class ReporterService {
|
|
|
190
195
|
}
|
|
191
196
|
|
|
192
197
|
private isoTimestampFromKeyTimestamp(hashKey: string): string {
|
|
198
|
+
if (hashKey.endsWith(':')) {
|
|
199
|
+
return '0';
|
|
200
|
+
}
|
|
193
201
|
const keyTimestamp = hashKey.slice(-12);
|
|
194
202
|
const year = keyTimestamp.slice(0, 4);
|
|
195
203
|
const month = keyTimestamp.slice(4, 6);
|
|
@@ -3,6 +3,7 @@ import { StoreService } from '../store';
|
|
|
3
3
|
import { HookRule, HookSignal } from '../../types/hook';
|
|
4
4
|
import { JobState } from '../../types/job';
|
|
5
5
|
import { RedisClient, RedisMulti } from '../../types/redis';
|
|
6
|
+
import { Pipe } from '../pipe';
|
|
6
7
|
|
|
7
8
|
class StoreSignaler {
|
|
8
9
|
store: StoreService<RedisClient, RedisMulti>;
|
|
@@ -21,10 +22,12 @@ class StoreSignaler {
|
|
|
21
22
|
async registerWebHook(topic: string, context: JobState, multi?: RedisMulti): Promise<string> {
|
|
22
23
|
const hookRule = await this.getHookRule(topic);
|
|
23
24
|
if (hookRule) {
|
|
25
|
+
const mapExpression = hookRule.conditions.match[0].expected;
|
|
26
|
+
const resolved = Pipe.resolve(mapExpression, context);
|
|
24
27
|
const jobId = context.metadata.jid;
|
|
25
28
|
const hook: HookSignal = {
|
|
26
29
|
topic,
|
|
27
|
-
resolved
|
|
30
|
+
resolved,
|
|
28
31
|
jobId,
|
|
29
32
|
}
|
|
30
33
|
await this.store.setHookSignal(hook, multi);
|
|
@@ -37,8 +40,10 @@ class StoreSignaler {
|
|
|
37
40
|
async processWebHookSignal(topic: string, data: Record<string, unknown>): Promise<string> {
|
|
38
41
|
const hookRule = await this.getHookRule(topic);
|
|
39
42
|
if (hookRule) {
|
|
40
|
-
//
|
|
41
|
-
const
|
|
43
|
+
//NOTE: both formats are supported: $self.hook.data OR $hook.data
|
|
44
|
+
const context = { $self: { hook: { data }}, $hook: { data }};
|
|
45
|
+
const mapExpression = hookRule.conditions.match[0].actual;
|
|
46
|
+
const resolved = Pipe.resolve(mapExpression, context);
|
|
42
47
|
const jobId = await this.store.getHookSignal(topic, resolved);
|
|
43
48
|
return jobId;
|
|
44
49
|
} else {
|
|
@@ -149,9 +149,9 @@ class StreamSignaler {
|
|
|
149
149
|
let output: StreamDataResponse | void;
|
|
150
150
|
try {
|
|
151
151
|
output = await callback(input);
|
|
152
|
-
} catch (
|
|
153
|
-
this.logger.error(`stream-call-function-error`, {
|
|
154
|
-
output = this.structureUnhandledError(input,
|
|
152
|
+
} catch (error) {
|
|
153
|
+
this.logger.error(`stream-call-function-error`, { error });
|
|
154
|
+
output = this.structureUnhandledError(input, error);
|
|
155
155
|
}
|
|
156
156
|
return output as StreamDataResponse;
|
|
157
157
|
}
|
|
@@ -63,9 +63,9 @@ class IORedisStoreService extends StoreService<RedisClientType, RedisMultiType>
|
|
|
63
63
|
async xadd(key: string, id: string, messageId: string, messageValue: string, multi?: RedisMultiType): Promise<string | RedisMultiType> {
|
|
64
64
|
try {
|
|
65
65
|
return await (multi || this.redisClient).xadd(key, id, messageId, messageValue);
|
|
66
|
-
} catch (
|
|
67
|
-
this.logger.error(`Error publishing 'xadd'; key: ${key}`,
|
|
68
|
-
throw
|
|
66
|
+
} catch (error) {
|
|
67
|
+
this.logger.error(`Error publishing 'xadd'; key: ${key}`, { error });
|
|
68
|
+
throw error;
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
@@ -79,9 +79,9 @@ class IORedisStoreService extends StoreService<RedisClientType, RedisMultiType>
|
|
|
79
79
|
): Promise<[string, string, number, [string, number][]][] | [string, string, number, number] | unknown[]> {
|
|
80
80
|
try {
|
|
81
81
|
return await this.redisClient.xpending(key, group, start, end, count, consumer);
|
|
82
|
-
} catch (
|
|
83
|
-
this.logger.error(`Error in retrieving pending messages for [stream ${key}], [group ${group}]`,
|
|
84
|
-
throw
|
|
82
|
+
} catch (error) {
|
|
83
|
+
this.logger.error(`Error in retrieving pending messages for [stream ${key}], [group ${group}]`, { error });
|
|
84
|
+
throw error;
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
|
|
@@ -95,27 +95,27 @@ class IORedisStoreService extends StoreService<RedisClientType, RedisMultiType>
|
|
|
95
95
|
): Promise<ReclaimedMessageType> {
|
|
96
96
|
try {
|
|
97
97
|
return await this.redisClient.xclaim(key, group, consumer, minIdleTime, id, ...args) as unknown as ReclaimedMessageType;
|
|
98
|
-
} catch (
|
|
99
|
-
this.logger.error(`Error in claiming message with id: ${id} in group: ${group} for key: ${key}`,
|
|
100
|
-
throw
|
|
98
|
+
} catch (error) {
|
|
99
|
+
this.logger.error(`Error in claiming message with id: ${id} in group: ${group} for key: ${key}`, { error });
|
|
100
|
+
throw error;
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
async xack(key: string, group: string, id: string, multi? : RedisMultiType): Promise<number|RedisMultiType> {
|
|
105
105
|
try {
|
|
106
106
|
return await (multi || this.redisClient).xack(key, group, id);
|
|
107
|
-
} catch (
|
|
108
|
-
this.logger.error(`Error in acknowledging messages in group: ${group} for key: ${key}`,
|
|
109
|
-
throw
|
|
107
|
+
} catch (error) {
|
|
108
|
+
this.logger.error(`Error in acknowledging messages in group: ${group} for key: ${key}`, { error });
|
|
109
|
+
throw error;
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
async xdel(key: string, id: string, multi? : RedisMultiType): Promise<number|RedisMultiType> {
|
|
114
114
|
try {
|
|
115
115
|
return await (multi || this.redisClient).xdel(key, id);
|
|
116
|
-
} catch (
|
|
117
|
-
this.logger.error(`Error in deleting messages with id: ${id} for key: ${key}`,
|
|
118
|
-
throw
|
|
116
|
+
} catch (error) {
|
|
117
|
+
this.logger.error(`Error in deleting messages with id: ${id} for key: ${key}`, { error });
|
|
118
|
+
throw error;
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
}
|
|
@@ -80,10 +80,10 @@ class RedisStoreService extends StoreService<RedisClientType, RedisMultiType> {
|
|
|
80
80
|
const args = mkStream === 'MKSTREAM' ? ['MKSTREAM'] : [];
|
|
81
81
|
try {
|
|
82
82
|
return (await this.redisClient.sendCommand(['XGROUP', 'CREATE', key, groupName, id, ...args])) === 1;
|
|
83
|
-
} catch (
|
|
83
|
+
} catch (error) {
|
|
84
84
|
const streamType = mkStream === 'MKSTREAM' ? 'with MKSTREAM' : 'without MKSTREAM';
|
|
85
|
-
this.logger.warn(`x-group-error ${streamType} for key: ${key} and group: ${groupName}`,
|
|
86
|
-
throw
|
|
85
|
+
this.logger.warn(`x-group-error ${streamType} for key: ${key} and group: ${groupName}`, { error });
|
|
86
|
+
throw error;
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
|
|
@@ -94,9 +94,9 @@ class RedisStoreService extends StoreService<RedisClientType, RedisMultiType> {
|
|
|
94
94
|
}
|
|
95
95
|
try {
|
|
96
96
|
return await (multi || this.redisClient).XADD(key, id, { [args[0]]: args[1] });
|
|
97
|
-
} catch (
|
|
98
|
-
this.logger.error(`Error publishing 'xadd'; key: ${key}`,
|
|
99
|
-
throw
|
|
97
|
+
} catch (error) {
|
|
98
|
+
this.logger.error(`Error publishing 'xadd'; key: ${key}`, { error });
|
|
99
|
+
throw error;
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
|
|
@@ -115,9 +115,9 @@ class RedisStoreService extends StoreService<RedisClientType, RedisMultiType> {
|
|
|
115
115
|
if (count !== undefined) args.push(count.toString());
|
|
116
116
|
if (consumer) args.push(consumer);
|
|
117
117
|
return await this.redisClient.sendCommand(['XPENDING', ...args]);
|
|
118
|
-
} catch (
|
|
119
|
-
this.logger.error(`Error in retrieving pending messages for group: ${group} in key: ${key}`,
|
|
120
|
-
throw
|
|
118
|
+
} catch (error) {
|
|
119
|
+
this.logger.error(`Error in retrieving pending messages for group: ${group} in key: ${key}`, { error });
|
|
120
|
+
throw error;
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
|
|
@@ -131,9 +131,9 @@ class RedisStoreService extends StoreService<RedisClientType, RedisMultiType> {
|
|
|
131
131
|
): Promise<ReclaimedMessageType> {
|
|
132
132
|
try {
|
|
133
133
|
return await this.redisClient.sendCommand(['XCLAIM', key, group, consumer, minIdleTime.toString(), id, ...args]) as unknown as ReclaimedMessageType;
|
|
134
|
-
} catch (
|
|
135
|
-
this.logger.error(`Error in claiming message with id: ${id} in group: ${group} for key: ${key}`,
|
|
136
|
-
throw
|
|
134
|
+
} catch (error) {
|
|
135
|
+
this.logger.error(`Error in claiming message with id: ${id} in group: ${group} for key: ${key}`, { error });
|
|
136
|
+
throw error;
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
|
|
@@ -145,9 +145,9 @@ class RedisStoreService extends StoreService<RedisClientType, RedisMultiType> {
|
|
|
145
145
|
} else {
|
|
146
146
|
return await this.redisClient[this.commands.xack](key, group, id);
|
|
147
147
|
}
|
|
148
|
-
} catch (
|
|
149
|
-
this.logger.error(`Error in acknowledging messages in group: ${group} for key: ${key}`,
|
|
150
|
-
throw
|
|
148
|
+
} catch (error) {
|
|
149
|
+
this.logger.error(`Error in acknowledging messages in group: ${group} for key: ${key}`, { error });
|
|
150
|
+
throw error;
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
153
|
|
|
@@ -159,9 +159,9 @@ class RedisStoreService extends StoreService<RedisClientType, RedisMultiType> {
|
|
|
159
159
|
} else {
|
|
160
160
|
return await this.redisClient[this.commands.xdel](key, id);
|
|
161
161
|
}
|
|
162
|
-
} catch (
|
|
163
|
-
this.logger.error(`Error in deleting messages with ids: ${id} for key: ${key}`,
|
|
164
|
-
throw
|
|
162
|
+
} catch (error) {
|
|
163
|
+
this.logger.error(`Error in deleting messages with ids: ${id} for key: ${key}`, { error });
|
|
164
|
+
throw error;
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
167
|
}
|
package/services/store/index.ts
CHANGED
|
@@ -431,7 +431,10 @@ abstract class StoreService<T, U extends AbstractRedisClient> {
|
|
|
431
431
|
const output: IdsData = {};
|
|
432
432
|
for (const [index, result] of results.entries()) {
|
|
433
433
|
const key = indexKeys[index];
|
|
434
|
-
|
|
434
|
+
|
|
435
|
+
//todo: resolve this discrepancy between redis/ioredis
|
|
436
|
+
const idsList: string[] = result[1] || result;
|
|
437
|
+
|
|
435
438
|
if (idsList && idsList.length > 0) {
|
|
436
439
|
output[key] = idsList;
|
|
437
440
|
} else {
|
|
@@ -695,11 +698,17 @@ abstract class StoreService<T, U extends AbstractRedisClient> {
|
|
|
695
698
|
return workItemKey;
|
|
696
699
|
}
|
|
697
700
|
|
|
698
|
-
async deleteProcessedTaskQueue(workItemKey: string, key: string, processedKey: string): Promise<void> {
|
|
701
|
+
async deleteProcessedTaskQueue(workItemKey: string, key: string, processedKey: string, scrub = false): Promise<void> {
|
|
699
702
|
const zsetKey = this.mintKey(KeyType.WORK_ITEMS, { appId: this.appId });
|
|
700
703
|
const didRemove = await this.redisClient[this.commands.zrem](zsetKey, workItemKey);
|
|
701
704
|
if (didRemove) {
|
|
702
|
-
|
|
705
|
+
if (scrub) {
|
|
706
|
+
//indexes can be designed to be self-cleaning; `engine.hookAll` exposes this option
|
|
707
|
+
this.redisClient[this.commands.expire](processedKey, 0);
|
|
708
|
+
this.redisClient[this.commands.expire](key.split(":").slice(0, 5).join(":"), 0);
|
|
709
|
+
} else {
|
|
710
|
+
await this.redisClient[this.commands.rename](processedKey, key);
|
|
711
|
+
}
|
|
703
712
|
}
|
|
704
713
|
this.cache.removeWorkItem(this.appId);
|
|
705
714
|
}
|
package/services/task/index.ts
CHANGED
|
@@ -25,15 +25,15 @@ class TaskService {
|
|
|
25
25
|
async processWebHooks(hookEventCallback: HookInterface): Promise<void> {
|
|
26
26
|
const workItemKey = await this.store.getActiveTaskQueue();
|
|
27
27
|
if (workItemKey) {
|
|
28
|
-
const [topic, sourceKey, ...sdata] = workItemKey.split('::');
|
|
28
|
+
const [topic, sourceKey, scrub, ...sdata] = workItemKey.split('::');
|
|
29
29
|
const data = JSON.parse(sdata.join('::'));
|
|
30
30
|
const destinationKey = `${sourceKey}:processed`;
|
|
31
31
|
const jobId = await this.store.processTaskQueue(sourceKey, destinationKey);
|
|
32
32
|
if (jobId) {
|
|
33
|
+
//todo: don't use 'id', make configurable using hook rule
|
|
33
34
|
await hookEventCallback(topic, { ...data, id: jobId });
|
|
34
|
-
//todo: do final checksum count (values are tracked in the stats hash)
|
|
35
35
|
} else {
|
|
36
|
-
await this.store.deleteProcessedTaskQueue(workItemKey, sourceKey, destinationKey);
|
|
36
|
+
await this.store.deleteProcessedTaskQueue(workItemKey, sourceKey, destinationKey, scrub === 'true');
|
|
37
37
|
}
|
|
38
38
|
setImmediate(() => this.processWebHooks(hookEventCallback));
|
|
39
39
|
}
|
package/types/activity.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MetricTypes } from "./stats";
|
|
2
2
|
import { StreamRetryPolicy } from "./stream";
|
|
3
3
|
|
|
4
|
-
type ActivityExecutionType = 'trigger' | 'await' | 'worker' | 'activity' | 'emit' | 'iterate' | 'cycle';
|
|
4
|
+
type ActivityExecutionType = 'trigger' | 'await' | 'worker' | 'activity' | 'emit' | 'iterate' | 'cycle' | 'signal';
|
|
5
5
|
|
|
6
6
|
type Consumes = Record<string, string[]>;
|
|
7
7
|
|
|
@@ -15,6 +15,7 @@ interface BaseActivity {
|
|
|
15
15
|
job?: Record<string, any>;
|
|
16
16
|
hook?: Record<string, any>;
|
|
17
17
|
telemetry?: Record<string, any>;
|
|
18
|
+
emit?: boolean; //if true, the activity will emit a message to the `publishes` topic immediately before transitioning to adjacent activities
|
|
18
19
|
sleep?: number; //@pipe /in seconds
|
|
19
20
|
expire?: number; //-1 forever (15 seconds default); todo: make globally configurable
|
|
20
21
|
retry?: StreamRetryPolicy
|
|
@@ -38,6 +39,7 @@ interface Measure {
|
|
|
38
39
|
interface TriggerActivityStats {
|
|
39
40
|
id?: { [key: string]: unknown } | string;
|
|
40
41
|
key?: { [key: string]: unknown } | string;
|
|
42
|
+
granularity?: string; //return 'infinity' to disable; default behavior is to always segment keys by time to ensure indexes (Redis LIST) never grow unbounded as a default behavior; for now, 5m is default and infinity can be set to override
|
|
41
43
|
measures?: Measure[]; //what to capture
|
|
42
44
|
}
|
|
43
45
|
|
|
@@ -58,20 +60,27 @@ interface WorkerActivity extends BaseActivity {
|
|
|
58
60
|
timeout: number;
|
|
59
61
|
}
|
|
60
62
|
|
|
61
|
-
interface EmitActivity extends BaseActivity {
|
|
62
|
-
type: 'emit';
|
|
63
|
-
}
|
|
64
|
-
|
|
65
63
|
interface CycleActivity extends BaseActivity {
|
|
66
64
|
type: 'cycle';
|
|
67
65
|
ancestor: string; //ancestor activity id
|
|
68
66
|
}
|
|
69
67
|
|
|
68
|
+
interface SignalActivity extends BaseActivity {
|
|
69
|
+
type: 'signal'; //signal activities call hook/hookAll
|
|
70
|
+
subtype: 'one' | 'all'; //trigger: hook(One) or hookAll
|
|
71
|
+
topic: string; //e.g., 'hook.resume'
|
|
72
|
+
key_name: string; //e.g., 'parent_job_id'
|
|
73
|
+
key_value: string; //e.g., '1234567890'
|
|
74
|
+
scrub: boolean; //if true, the index will be deleted after use
|
|
75
|
+
signal?: Record<string, any>; //used to define/map the signal input data
|
|
76
|
+
resolver?: Record<string, any>; //used to define/map the signal key resolver
|
|
77
|
+
}
|
|
78
|
+
|
|
70
79
|
interface IterateActivity extends BaseActivity {
|
|
71
80
|
type: 'iterate';
|
|
72
81
|
}
|
|
73
82
|
|
|
74
|
-
type ActivityType = BaseActivity | TriggerActivity | AwaitActivity | WorkerActivity |
|
|
83
|
+
type ActivityType = BaseActivity | TriggerActivity | AwaitActivity | WorkerActivity | IterateActivity;
|
|
75
84
|
|
|
76
85
|
type ActivityData = Record<string, any>;
|
|
77
86
|
type ActivityMetadata = {
|
|
@@ -115,8 +124,8 @@ export {
|
|
|
115
124
|
TriggerActivityStats,
|
|
116
125
|
AwaitActivity,
|
|
117
126
|
CycleActivity,
|
|
127
|
+
SignalActivity,
|
|
118
128
|
BaseActivity,
|
|
119
|
-
EmitActivity,
|
|
120
129
|
IterateActivity,
|
|
121
130
|
TriggerActivity,
|
|
122
131
|
WorkerActivity
|
package/types/durable.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { RedisClass, RedisOptions } from './redis';
|
|
2
2
|
|
|
3
|
+
type WorkflowConfig = {
|
|
4
|
+
backoffCoefficient?: number; //default 10
|
|
5
|
+
maximumAttempts?: number; //default 2
|
|
6
|
+
maximumInterval?: string; //default 30s
|
|
7
|
+
initialInterval?: string; //default 1s
|
|
8
|
+
}
|
|
9
|
+
|
|
3
10
|
type WorkflowOptions = {
|
|
4
11
|
taskQueue: string;
|
|
5
12
|
args: any[]; //input arguments to pass in
|
|
@@ -7,6 +14,14 @@ type WorkflowOptions = {
|
|
|
7
14
|
workflowName?: string; //the name of the user's workflow function
|
|
8
15
|
workflowTrace?: string;
|
|
9
16
|
workflowSpan?: string;
|
|
17
|
+
config?: WorkflowConfig;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type SignalOptions = {
|
|
21
|
+
taskQueue: string;
|
|
22
|
+
data: Record<string, any>; //input data (any serializable object)
|
|
23
|
+
workflowId: string; //execution id (the job id)
|
|
24
|
+
workflowName?: string; //the name of the user's workflow function
|
|
10
25
|
}
|
|
11
26
|
|
|
12
27
|
type ActivityWorkflowDataType = {
|
|
@@ -47,7 +62,7 @@ type WorkerConfig = {
|
|
|
47
62
|
|
|
48
63
|
type WorkerOptions = {
|
|
49
64
|
maxSystemRetries?: number; //1-3 (10ms, 100ms, 1_000ms)
|
|
50
|
-
|
|
65
|
+
backoffCoefficient?: number; //2-10ish
|
|
51
66
|
}
|
|
52
67
|
|
|
53
68
|
type ContextType = {
|
|
@@ -81,7 +96,9 @@ export {
|
|
|
81
96
|
NativeConnection,
|
|
82
97
|
ProxyType,
|
|
83
98
|
Registry,
|
|
99
|
+
SignalOptions,
|
|
84
100
|
WorkerConfig,
|
|
101
|
+
WorkflowConfig,
|
|
85
102
|
WorkerOptions,
|
|
86
103
|
WorkflowDataType,
|
|
87
104
|
WorkflowOptions,
|
package/types/index.ts
CHANGED
|
@@ -10,9 +10,9 @@ export {
|
|
|
10
10
|
AwaitActivity,
|
|
11
11
|
BaseActivity,
|
|
12
12
|
CycleActivity,
|
|
13
|
-
EmitActivity,
|
|
14
13
|
WorkerActivity,
|
|
15
14
|
IterateActivity,
|
|
15
|
+
SignalActivity,
|
|
16
16
|
TriggerActivity,
|
|
17
17
|
TriggerActivityStats } from './activity';
|
|
18
18
|
export {
|
|
@@ -36,6 +36,7 @@ export {
|
|
|
36
36
|
NativeConnection,
|
|
37
37
|
ProxyType,
|
|
38
38
|
Registry,
|
|
39
|
+
WorkflowConfig,
|
|
39
40
|
WorkerConfig,
|
|
40
41
|
WorkerOptions,
|
|
41
42
|
WorkflowDataType,
|
package/types/stats.ts
CHANGED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { EngineService } from '../engine';
|
|
2
|
-
import { Activity, ActivityType } from './activity';
|
|
3
|
-
import { ActivityData, ActivityMetadata, EmitActivity } from '../../types/activity';
|
|
4
|
-
declare class Emit extends Activity {
|
|
5
|
-
config: EmitActivity;
|
|
6
|
-
constructor(config: ActivityType, data: ActivityData, metadata: ActivityMetadata, hook: ActivityData | null, engine: EngineService);
|
|
7
|
-
mapInputData(): Promise<void>;
|
|
8
|
-
}
|
|
9
|
-
export { Emit };
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Emit = void 0;
|
|
4
|
-
const activity_1 = require("./activity");
|
|
5
|
-
class Emit extends activity_1.Activity {
|
|
6
|
-
constructor(config, data, metadata, hook, engine) {
|
|
7
|
-
super(config, data, metadata, hook, engine);
|
|
8
|
-
}
|
|
9
|
-
async mapInputData() {
|
|
10
|
-
this.logger.info('emit-map-input-data');
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
exports.Emit = Emit;
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { EngineService } from '../engine';
|
|
2
|
-
import { Activity, ActivityType } from './activity';
|
|
3
|
-
import {
|
|
4
|
-
ActivityData,
|
|
5
|
-
ActivityMetadata,
|
|
6
|
-
EmitActivity } from '../../types/activity';
|
|
7
|
-
|
|
8
|
-
class Emit extends Activity {
|
|
9
|
-
config: EmitActivity;
|
|
10
|
-
|
|
11
|
-
constructor(
|
|
12
|
-
config: ActivityType,
|
|
13
|
-
data: ActivityData,
|
|
14
|
-
metadata: ActivityMetadata,
|
|
15
|
-
hook: ActivityData | null,
|
|
16
|
-
engine: EngineService) {
|
|
17
|
-
super(config, data, metadata, hook, engine);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
async mapInputData(): Promise<void> {
|
|
21
|
-
this.logger.info('emit-map-input-data');
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export { Emit };
|