@hotmeshio/hotmesh 0.0.37 → 0.0.39
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 +14 -8
- package/build/modules/enums.d.ts +29 -23
- package/build/modules/enums.js +38 -29
- package/build/modules/errors.d.ts +1 -1
- package/build/modules/errors.js +9 -7
- package/build/modules/key.d.ts +1 -34
- package/build/modules/key.js +24 -47
- package/build/package.json +1 -1
- package/build/services/activities/activity.js +1 -1
- package/build/services/activities/hook.js +4 -9
- package/build/services/activities/trigger.d.ts +3 -2
- package/build/services/activities/trigger.js +10 -6
- package/build/services/durable/client.d.ts +9 -1
- package/build/services/durable/client.js +30 -14
- package/build/services/durable/handle.js +2 -2
- package/build/services/durable/worker.js +4 -3
- package/build/services/engine/index.d.ts +2 -1
- package/build/services/engine/index.js +6 -6
- package/build/services/hotmesh/index.d.ts +2 -2
- package/build/services/hotmesh/index.js +3 -4
- package/build/services/quorum/index.d.ts +6 -6
- package/build/services/quorum/index.js +47 -11
- package/build/services/router/index.js +16 -14
- package/build/services/store/clients/ioredis.d.ts +1 -0
- package/build/services/store/clients/ioredis.js +9 -0
- package/build/services/store/clients/redis.d.ts +1 -0
- package/build/services/store/clients/redis.js +16 -0
- package/build/services/store/index.d.ts +15 -9
- package/build/services/store/index.js +46 -23
- package/build/services/stream/clients/ioredis.d.ts +1 -0
- package/build/services/stream/clients/ioredis.js +33 -24
- package/build/services/stream/clients/redis.d.ts +1 -0
- package/build/services/stream/clients/redis.js +15 -0
- package/build/services/stream/index.d.ts +1 -0
- package/build/services/task/index.d.ts +10 -3
- package/build/services/task/index.js +35 -17
- package/build/services/worker/index.d.ts +1 -0
- package/build/services/worker/index.js +24 -0
- package/build/types/durable.d.ts +3 -2
- package/build/types/hotmesh.d.ts +43 -2
- package/build/types/hotmesh.js +28 -0
- package/build/types/index.d.ts +3 -2
- package/build/types/index.js +3 -1
- package/build/types/logger.d.ts +1 -0
- package/build/types/logger.js +1 -0
- package/build/types/quorum.d.ts +11 -1
- package/build/types/redisclient.d.ts +1 -0
- package/build/types/task.d.ts +1 -0
- package/build/types/task.js +2 -0
- package/modules/enums.ts +49 -35
- package/modules/errors.ts +17 -8
- package/modules/key.ts +3 -40
- package/package.json +1 -1
- package/services/activities/activity.ts +2 -2
- package/services/activities/hook.ts +18 -9
- package/services/activities/trigger.ts +10 -6
- package/services/durable/client.ts +31 -15
- package/services/durable/handle.ts +3 -3
- package/services/durable/worker.ts +4 -3
- package/services/engine/index.ts +13 -12
- package/services/hotmesh/index.ts +4 -5
- package/services/quorum/index.ts +48 -12
- package/services/router/index.ts +26 -24
- package/services/store/clients/ioredis.ts +9 -0
- package/services/store/clients/redis.ts +16 -0
- package/services/store/index.ts +63 -25
- package/services/stream/clients/ioredis.ts +33 -24
- package/services/stream/clients/redis.ts +14 -0
- package/services/stream/index.ts +1 -0
- package/services/task/index.ts +66 -24
- package/services/worker/index.ts +30 -0
- package/types/durable.ts +6 -5
- package/types/hotmesh.ts +47 -2
- package/types/index.ts +8 -1
- package/types/logger.ts +3 -1
- package/types/quorum.ts +15 -4
- package/types/redisclient.ts +1 -0
- package/types/task.ts +1 -0
|
@@ -25,18 +25,18 @@ class IORedisStreamService extends index_1.StreamService {
|
|
|
25
25
|
try {
|
|
26
26
|
return (await this.redisClient.xgroup(command, key, groupName, id, mkStream)) === 'OK';
|
|
27
27
|
}
|
|
28
|
-
catch (
|
|
28
|
+
catch (error) {
|
|
29
29
|
this.logger.info(`Consumer group not created with MKSTREAM for key: ${key} and group: ${groupName}`);
|
|
30
|
-
throw
|
|
30
|
+
throw error;
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
else {
|
|
34
34
|
try {
|
|
35
35
|
return (await this.redisClient.xgroup(command, key, groupName, id)) === 'OK';
|
|
36
36
|
}
|
|
37
|
-
catch (
|
|
37
|
+
catch (error) {
|
|
38
38
|
this.logger.info(`Consumer group not created for key: ${key} and group: ${groupName}`);
|
|
39
|
-
throw
|
|
39
|
+
throw error;
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
}
|
|
@@ -44,9 +44,9 @@ class IORedisStreamService extends index_1.StreamService {
|
|
|
44
44
|
try {
|
|
45
45
|
return await (multi || this.redisClient).xadd(key, id, messageId, messageValue);
|
|
46
46
|
}
|
|
47
|
-
catch (
|
|
48
|
-
this.logger.error(`Error publishing 'xadd'; key: ${key}`,
|
|
49
|
-
throw
|
|
47
|
+
catch (error) {
|
|
48
|
+
this.logger.error(`Error publishing 'xadd'; key: ${key}`, { error });
|
|
49
|
+
throw error;
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
async xreadgroup(command, groupName, consumerName, blockOption, blockTime, streamsOption, streamName, id) {
|
|
@@ -56,9 +56,9 @@ class IORedisStreamService extends index_1.StreamService {
|
|
|
56
56
|
// @ts-ignore
|
|
57
57
|
blockOption, blockTime, streamsOption, streamName, id);
|
|
58
58
|
}
|
|
59
|
-
catch (
|
|
60
|
-
this.logger.error(`Error reading stream data [Stream ${streamName}] [Group ${groupName}]`,
|
|
61
|
-
throw
|
|
59
|
+
catch (error) {
|
|
60
|
+
this.logger.error(`Error reading stream data [Stream ${streamName}] [Group ${groupName}]`, { error });
|
|
61
|
+
throw error;
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
async xpending(key, group, start, end, count, consumer) {
|
|
@@ -75,40 +75,49 @@ class IORedisStreamService extends index_1.StreamService {
|
|
|
75
75
|
try {
|
|
76
76
|
return await this.redisClient.call('XPENDING', ...args);
|
|
77
77
|
}
|
|
78
|
-
catch (
|
|
79
|
-
this.logger.error('err, args',
|
|
78
|
+
catch (error) {
|
|
79
|
+
this.logger.error('err, args', { error }, args);
|
|
80
80
|
}
|
|
81
81
|
}
|
|
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
|
async xclaim(key, group, consumer, minIdleTime, id, ...args) {
|
|
88
88
|
try {
|
|
89
89
|
return await this.redisClient.xclaim(key, group, consumer, minIdleTime, id, ...args);
|
|
90
90
|
}
|
|
91
|
-
catch (
|
|
92
|
-
this.logger.error(`Error in claiming message with id: ${id} in group: ${group} for key: ${key}`,
|
|
93
|
-
throw
|
|
91
|
+
catch (error) {
|
|
92
|
+
this.logger.error(`Error in claiming message with id: ${id} in group: ${group} for key: ${key}`, { error });
|
|
93
|
+
throw error;
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
async xack(key, group, id, multi) {
|
|
97
97
|
try {
|
|
98
98
|
return await (multi || this.redisClient).xack(key, group, id);
|
|
99
99
|
}
|
|
100
|
-
catch (
|
|
101
|
-
this.logger.error(`Error in acknowledging messages in group: ${group} for key: ${key}`,
|
|
102
|
-
throw
|
|
100
|
+
catch (error) {
|
|
101
|
+
this.logger.error(`Error in acknowledging messages in group: ${group} for key: ${key}`, { error });
|
|
102
|
+
throw error;
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
async xdel(key, id, multi) {
|
|
106
106
|
try {
|
|
107
107
|
return await (multi || this.redisClient).xdel(key, id);
|
|
108
108
|
}
|
|
109
|
-
catch (
|
|
110
|
-
this.logger.error(`Error in deleting messages with id: ${id} for key: ${key}`,
|
|
111
|
-
throw
|
|
109
|
+
catch (error) {
|
|
110
|
+
this.logger.error(`Error in deleting messages with id: ${id} for key: ${key}`, { error });
|
|
111
|
+
throw error;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
async xlen(key, multi) {
|
|
115
|
+
try {
|
|
116
|
+
return await (multi || this.redisClient).xlen(key);
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
this.logger.error(`Error getting stream depth: ${key}`, { error });
|
|
120
|
+
throw error;
|
|
112
121
|
}
|
|
113
122
|
}
|
|
114
123
|
}
|
|
@@ -19,5 +19,6 @@ declare class RedisStreamService extends StreamService<RedisClientType, RedisMul
|
|
|
19
19
|
xclaim(key: string, group: string, consumer: string, minIdleTime: number, id: string, ...args: string[]): Promise<ReclaimedMessageType>;
|
|
20
20
|
xack(key: string, group: string, id: string, multi?: RedisMultiType): Promise<number | RedisMultiType>;
|
|
21
21
|
xdel(key: string, id: string, multi?: RedisMultiType): Promise<number | RedisMultiType>;
|
|
22
|
+
xlen(key: string, multi?: RedisMultiType): Promise<number | RedisMultiType>;
|
|
22
23
|
}
|
|
23
24
|
export { RedisStreamService };
|
|
@@ -115,5 +115,20 @@ class RedisStreamService extends index_1.StreamService {
|
|
|
115
115
|
throw err;
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
|
+
async xlen(key, multi) {
|
|
119
|
+
try {
|
|
120
|
+
if (multi) {
|
|
121
|
+
multi.XLEN(key);
|
|
122
|
+
return multi;
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
return await this.redisClient.XLEN(key);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
this.logger.error(`Error getting stream depth: ${key}`, { error });
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
118
133
|
}
|
|
119
134
|
exports.RedisStreamService = RedisStreamService;
|
|
@@ -17,5 +17,6 @@ declare abstract class StreamService<T, U> {
|
|
|
17
17
|
abstract xclaim(key: string, group: string, consumer: string, minIdleTime: number, id: string, ...args: string[]): Promise<ReclaimedMessageType>;
|
|
18
18
|
abstract xack(key: string, group: string, id: string, multi?: U): Promise<number | U>;
|
|
19
19
|
abstract xdel(key: string, id: string, multi?: U): Promise<number | U>;
|
|
20
|
+
abstract xlen(key: string, multi?: U): Promise<number | U>;
|
|
20
21
|
}
|
|
21
22
|
export { StreamService };
|
|
@@ -4,6 +4,7 @@ import { StoreService } from '../store';
|
|
|
4
4
|
import { HookInterface, HookRule } from '../../types/hook';
|
|
5
5
|
import { JobCompletionOptions, JobState } from '../../types/job';
|
|
6
6
|
import { RedisClient, RedisMulti } from '../../types/redis';
|
|
7
|
+
import { WorkListTaskType } from '../../types/task';
|
|
7
8
|
declare class TaskService {
|
|
8
9
|
store: StoreService<RedisClient, RedisMulti>;
|
|
9
10
|
logger: ILogger;
|
|
@@ -13,12 +14,18 @@ declare class TaskService {
|
|
|
13
14
|
processWebHooks(hookEventCallback: HookInterface): Promise<void>;
|
|
14
15
|
enqueueWorkItems(keys: string[]): Promise<void>;
|
|
15
16
|
registerJobForCleanup(jobId: string, inSeconds: number, options: JobCompletionOptions): Promise<void>;
|
|
16
|
-
registerTimeHook(jobId: string, gId: string, activityId: string, type:
|
|
17
|
+
registerTimeHook(jobId: string, gId: string, activityId: string, type: WorkListTaskType, inSeconds?: number, multi?: RedisMulti): Promise<void>;
|
|
17
18
|
/**
|
|
18
|
-
* Should this engine instance play the role of 'scout'
|
|
19
|
+
* Should this engine instance play the role of 'scout' on behalf
|
|
20
|
+
* of the entire quorum? The scout role is responsible for processing
|
|
21
|
+
* task lists on behalf of the collective.
|
|
19
22
|
*/
|
|
20
23
|
shouldScout(): Promise<boolean>;
|
|
21
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Callback handler that takes an item from a work list and
|
|
26
|
+
* processes according to its type
|
|
27
|
+
*/
|
|
28
|
+
processTimeHooks(timeEventCallback: (jobId: string, gId: string, activityId: string, type: WorkListTaskType) => Promise<void>, listKey?: string): Promise<void>;
|
|
22
29
|
cancelCleanup(): void;
|
|
23
30
|
getHookRule(topic: string): Promise<HookRule | undefined>;
|
|
24
31
|
registerWebHook(topic: string, context: JobState, dad: string, multi?: RedisMulti): Promise<string>;
|
|
@@ -4,6 +4,7 @@ exports.TaskService = void 0;
|
|
|
4
4
|
const enums_1 = require("../../modules/enums");
|
|
5
5
|
const utils_1 = require("../../modules/utils");
|
|
6
6
|
const pipe_1 = require("../pipe");
|
|
7
|
+
const hotmesh_1 = require("../../types/hotmesh");
|
|
7
8
|
class TaskService {
|
|
8
9
|
constructor(store, logger) {
|
|
9
10
|
this.cleanupTimeout = null;
|
|
@@ -31,19 +32,25 @@ class TaskService {
|
|
|
31
32
|
async enqueueWorkItems(keys) {
|
|
32
33
|
await this.store.addTaskQueues(keys);
|
|
33
34
|
}
|
|
34
|
-
async registerJobForCleanup(jobId, inSeconds = enums_1.
|
|
35
|
+
async registerJobForCleanup(jobId, inSeconds = enums_1.HMSH_EXPIRE_DURATION, options) {
|
|
35
36
|
if (inSeconds > 0) {
|
|
36
37
|
await this.store.expireJob(jobId, inSeconds);
|
|
37
|
-
const
|
|
38
|
-
|
|
38
|
+
const fromNow = Date.now() + (inSeconds * 1000);
|
|
39
|
+
const fidelityMS = enums_1.HMSH_FIDELITY_SECONDS * 1000;
|
|
40
|
+
const timeSlot = Math.floor(fromNow / fidelityMS) * fidelityMS;
|
|
41
|
+
await this.store.registerDependenciesForCleanup(jobId, timeSlot, options);
|
|
39
42
|
}
|
|
40
43
|
}
|
|
41
|
-
async registerTimeHook(jobId, gId, activityId, type, inSeconds = enums_1.
|
|
42
|
-
const
|
|
44
|
+
async registerTimeHook(jobId, gId, activityId, type, inSeconds = enums_1.HMSH_FIDELITY_SECONDS, multi) {
|
|
45
|
+
const fromNow = Date.now() + (inSeconds * 1000);
|
|
46
|
+
const fidelityMS = enums_1.HMSH_FIDELITY_SECONDS * 1000;
|
|
47
|
+
const awakenTimeSlot = Math.floor(fromNow / fidelityMS) * fidelityMS;
|
|
43
48
|
await this.store.registerTimeHook(jobId, gId, activityId, type, awakenTimeSlot, multi);
|
|
44
49
|
}
|
|
45
50
|
/**
|
|
46
|
-
* Should this engine instance play the role of 'scout'
|
|
51
|
+
* Should this engine instance play the role of 'scout' on behalf
|
|
52
|
+
* of the entire quorum? The scout role is responsible for processing
|
|
53
|
+
* task lists on behalf of the collective.
|
|
47
54
|
*/
|
|
48
55
|
async shouldScout() {
|
|
49
56
|
const wasScout = this.isScout;
|
|
@@ -52,31 +59,42 @@ class TaskService {
|
|
|
52
59
|
if (!wasScout) {
|
|
53
60
|
setTimeout(() => {
|
|
54
61
|
this.isScout = false;
|
|
55
|
-
}, enums_1.
|
|
62
|
+
}, enums_1.HMSH_SCOUT_INTERVAL_SECONDS * 1000);
|
|
56
63
|
}
|
|
57
64
|
return true;
|
|
58
65
|
}
|
|
59
66
|
return false;
|
|
60
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* Callback handler that takes an item from a work list and
|
|
70
|
+
* processes according to its type
|
|
71
|
+
*/
|
|
61
72
|
async processTimeHooks(timeEventCallback, listKey) {
|
|
62
73
|
if (await this.shouldScout()) {
|
|
63
74
|
try {
|
|
64
|
-
const
|
|
65
|
-
if (Array.isArray(
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
75
|
+
const workListTask = await this.store.getNextTask(listKey);
|
|
76
|
+
if (Array.isArray(workListTask)) {
|
|
77
|
+
const [listKey, target, gId, activityId, type] = workListTask;
|
|
78
|
+
if (type === 'delist') {
|
|
79
|
+
//delist the signalKey (target)
|
|
80
|
+
const key = this.store.mintKey(hotmesh_1.KeyType.SIGNALS, { appId: this.store.appId });
|
|
81
|
+
await this.store.redisClient[this.store.commands.hdel](key, target);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
//awaken/expire/interrupt
|
|
85
|
+
await timeEventCallback(target, gId, activityId, type);
|
|
86
|
+
}
|
|
69
87
|
await (0, utils_1.sleepFor)(0);
|
|
70
88
|
this.processTimeHooks(timeEventCallback, listKey);
|
|
71
89
|
}
|
|
72
|
-
else if (
|
|
73
|
-
//a
|
|
90
|
+
else if (workListTask) {
|
|
91
|
+
//a worklist was just emptied; try again immediately
|
|
74
92
|
await (0, utils_1.sleepFor)(0);
|
|
75
93
|
this.processTimeHooks(timeEventCallback);
|
|
76
94
|
}
|
|
77
95
|
else {
|
|
78
|
-
//
|
|
79
|
-
let sleep = (0, utils_1.XSleepFor)(enums_1.
|
|
96
|
+
//no worklists exist; sleep before checking
|
|
97
|
+
let sleep = (0, utils_1.XSleepFor)(enums_1.HMSH_FIDELITY_SECONDS * 1000);
|
|
80
98
|
this.cleanupTimeout = sleep.timerId;
|
|
81
99
|
await sleep.promise;
|
|
82
100
|
this.processTimeHooks(timeEventCallback);
|
|
@@ -89,7 +107,7 @@ class TaskService {
|
|
|
89
107
|
}
|
|
90
108
|
else {
|
|
91
109
|
//didn't get the scout role; try again in 'one-ish' minutes
|
|
92
|
-
let sleep = (0, utils_1.XSleepFor)(enums_1.
|
|
110
|
+
let sleep = (0, utils_1.XSleepFor)(enums_1.HMSH_SCOUT_INTERVAL_SECONDS * 1000 * 2 * Math.random());
|
|
93
111
|
this.cleanupTimeout = sleep.timerId;
|
|
94
112
|
await sleep.promise;
|
|
95
113
|
this.processTimeHooks(timeEventCallback);
|
|
@@ -25,6 +25,7 @@ declare class WorkerService {
|
|
|
25
25
|
initStreamChannel(service: WorkerService, stream: RedisClient): Promise<void>;
|
|
26
26
|
initRouter(worker: HotMeshWorker, logger: ILogger): Router;
|
|
27
27
|
subscriptionHandler(): SubscriptionCallback;
|
|
28
|
+
sayPong(appId: string, guid: string, originator: string, details?: boolean): Promise<void>;
|
|
28
29
|
throttle(delayInMillis: number): Promise<void>;
|
|
29
30
|
}
|
|
30
31
|
export { WorkerService };
|
|
@@ -96,8 +96,32 @@ class WorkerService {
|
|
|
96
96
|
if (message.type === 'throttle') {
|
|
97
97
|
self.throttle(message.throttle);
|
|
98
98
|
}
|
|
99
|
+
else if (message.type === 'ping') {
|
|
100
|
+
self.sayPong(self.appId, self.guid, message.originator, message.details);
|
|
101
|
+
}
|
|
99
102
|
};
|
|
100
103
|
}
|
|
104
|
+
async sayPong(appId, guid, originator, details = false) {
|
|
105
|
+
let profile;
|
|
106
|
+
if (details) {
|
|
107
|
+
const params = {
|
|
108
|
+
appId: this.appId,
|
|
109
|
+
topic: this.topic,
|
|
110
|
+
};
|
|
111
|
+
profile = {
|
|
112
|
+
engine_id: this.guid,
|
|
113
|
+
namespace: this.namespace,
|
|
114
|
+
app_id: this.appId,
|
|
115
|
+
worker_topic: this.topic,
|
|
116
|
+
stream: this.stream.mintKey(key_1.KeyType.STREAMS, params),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
this.store.publish(key_1.KeyType.QUORUM, {
|
|
120
|
+
type: 'pong',
|
|
121
|
+
guid, originator,
|
|
122
|
+
profile,
|
|
123
|
+
}, appId);
|
|
124
|
+
}
|
|
101
125
|
async throttle(delayInMillis) {
|
|
102
126
|
this.router.setThrottle(delayInMillis);
|
|
103
127
|
}
|
package/build/types/durable.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { LogLevel } from './logger';
|
|
1
2
|
import { RedisClass, RedisOptions } from './redis';
|
|
2
3
|
type WorkflowConfig = {
|
|
3
4
|
backoffCoefficient?: number;
|
|
@@ -151,12 +152,12 @@ type MeshOSActivityOptions = {
|
|
|
151
152
|
type MeshOSWorkerOptions = {
|
|
152
153
|
taskQueue?: string;
|
|
153
154
|
allowList?: Array<MeshOSOptions | string>;
|
|
154
|
-
logLevel?:
|
|
155
|
+
logLevel?: LogLevel;
|
|
155
156
|
maxSystemRetries?: number;
|
|
156
157
|
backoffCoefficient?: number;
|
|
157
158
|
};
|
|
158
159
|
type WorkerOptions = {
|
|
159
|
-
logLevel?:
|
|
160
|
+
logLevel?: LogLevel;
|
|
160
161
|
maxSystemRetries?: number;
|
|
161
162
|
backoffCoefficient?: number;
|
|
162
163
|
};
|
package/build/types/hotmesh.d.ts
CHANGED
|
@@ -3,6 +3,47 @@ import { HotMeshService } from '../services/hotmesh';
|
|
|
3
3
|
import { HookRules } from './hook';
|
|
4
4
|
import { RedisClass, RedisClient, RedisOptions } from './redis';
|
|
5
5
|
import { StreamData, StreamDataResponse } from './stream';
|
|
6
|
+
import { LogLevel } from './logger';
|
|
7
|
+
/**
|
|
8
|
+
* the full set of entity types that are stored in the key/value store
|
|
9
|
+
*/
|
|
10
|
+
declare enum KeyType {
|
|
11
|
+
APP = "APP",
|
|
12
|
+
ENGINE_ID = "ENGINE",
|
|
13
|
+
HOOKS = "HOOKS",
|
|
14
|
+
JOB_DEPENDENTS = "JOB_DEPENDENTS",
|
|
15
|
+
JOB_STATE = "JOB_STATE",
|
|
16
|
+
JOB_STATS_GENERAL = "JOB_STATS_GENERAL",
|
|
17
|
+
JOB_STATS_MEDIAN = "JOB_STATS_MEDIAN",
|
|
18
|
+
JOB_STATS_INDEX = "JOB_STATS_INDEX",
|
|
19
|
+
HOTMESH = "HOTMESH",
|
|
20
|
+
QUORUM = "QUORUM",
|
|
21
|
+
SCHEMAS = "SCHEMAS",
|
|
22
|
+
SIGNALS = "SIGNALS",
|
|
23
|
+
STREAMS = "STREAMS",
|
|
24
|
+
SUBSCRIPTIONS = "SUBSCRIPTIONS",
|
|
25
|
+
SUBSCRIPTION_PATTERNS = "SUBSCRIPTION_PATTERNS",
|
|
26
|
+
SYMKEYS = "SYMKEYS",
|
|
27
|
+
SYMVALS = "SYMVALS",
|
|
28
|
+
TIME_RANGE = "TIME_RANGE",
|
|
29
|
+
WORK_ITEMS = "WORK_ITEMS"
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* minting keys, requires one or more of the following parameters
|
|
33
|
+
*/
|
|
34
|
+
type KeyStoreParams = {
|
|
35
|
+
appId?: string;
|
|
36
|
+
engineId?: string;
|
|
37
|
+
appVersion?: string;
|
|
38
|
+
jobId?: string;
|
|
39
|
+
activityId?: string;
|
|
40
|
+
jobKey?: string;
|
|
41
|
+
dateTime?: string;
|
|
42
|
+
facet?: string;
|
|
43
|
+
topic?: string;
|
|
44
|
+
timeValue?: number;
|
|
45
|
+
scoutType?: 'signal' | 'time';
|
|
46
|
+
};
|
|
6
47
|
type HotMesh = typeof HotMeshService;
|
|
7
48
|
type RedisConfig = {
|
|
8
49
|
class: RedisClass;
|
|
@@ -34,7 +75,7 @@ type HotMeshConfig = {
|
|
|
34
75
|
namespace?: string;
|
|
35
76
|
name?: string;
|
|
36
77
|
logger?: ILogger;
|
|
37
|
-
logLevel?:
|
|
78
|
+
logLevel?: LogLevel;
|
|
38
79
|
engine?: HotMeshEngine;
|
|
39
80
|
workers?: HotMeshWorker[];
|
|
40
81
|
};
|
|
@@ -79,4 +120,4 @@ type HotMeshApps = {
|
|
|
79
120
|
export { HotMesh, HotMeshEngine, RedisConfig, HotMeshWorker, HotMeshSettings, HotMeshApp, //a single app in the db
|
|
80
121
|
HotMeshApps, //object array of all apps in the db
|
|
81
122
|
HotMeshConfig, //customer config
|
|
82
|
-
HotMeshManifest, HotMeshGraph };
|
|
123
|
+
HotMeshManifest, HotMeshGraph, KeyType, KeyStoreParams, };
|
package/build/types/hotmesh.js
CHANGED
|
@@ -1,2 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KeyType = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* the full set of entity types that are stored in the key/value store
|
|
6
|
+
*/
|
|
7
|
+
var KeyType;
|
|
8
|
+
(function (KeyType) {
|
|
9
|
+
KeyType["APP"] = "APP";
|
|
10
|
+
KeyType["ENGINE_ID"] = "ENGINE";
|
|
11
|
+
KeyType["HOOKS"] = "HOOKS";
|
|
12
|
+
KeyType["JOB_DEPENDENTS"] = "JOB_DEPENDENTS";
|
|
13
|
+
KeyType["JOB_STATE"] = "JOB_STATE";
|
|
14
|
+
KeyType["JOB_STATS_GENERAL"] = "JOB_STATS_GENERAL";
|
|
15
|
+
KeyType["JOB_STATS_MEDIAN"] = "JOB_STATS_MEDIAN";
|
|
16
|
+
KeyType["JOB_STATS_INDEX"] = "JOB_STATS_INDEX";
|
|
17
|
+
KeyType["HOTMESH"] = "HOTMESH";
|
|
18
|
+
KeyType["QUORUM"] = "QUORUM";
|
|
19
|
+
KeyType["SCHEMAS"] = "SCHEMAS";
|
|
20
|
+
KeyType["SIGNALS"] = "SIGNALS";
|
|
21
|
+
KeyType["STREAMS"] = "STREAMS";
|
|
22
|
+
KeyType["SUBSCRIPTIONS"] = "SUBSCRIPTIONS";
|
|
23
|
+
KeyType["SUBSCRIPTION_PATTERNS"] = "SUBSCRIPTION_PATTERNS";
|
|
24
|
+
KeyType["SYMKEYS"] = "SYMKEYS";
|
|
25
|
+
KeyType["SYMVALS"] = "SYMVALS";
|
|
26
|
+
KeyType["TIME_RANGE"] = "TIME_RANGE";
|
|
27
|
+
KeyType["WORK_ITEMS"] = "WORK_ITEMS";
|
|
28
|
+
})(KeyType || (KeyType = {}));
|
|
29
|
+
exports.KeyType = KeyType;
|
|
30
|
+
;
|
package/build/types/index.d.ts
CHANGED
|
@@ -10,12 +10,13 @@ export { ILogger } from './logger';
|
|
|
10
10
|
export { JobData, JobsData, JobMetadata, JobOutput, JobState, JobStatus, PartialJobState } from './job';
|
|
11
11
|
export { MappingStatements } from './map';
|
|
12
12
|
export { Pipe, PipeItem, PipeItems } from './pipe';
|
|
13
|
-
export { HotMesh, HotMeshApp, HotMeshApps, HotMeshConfig, HotMeshEngine, RedisConfig, HotMeshGraph, HotMeshManifest, HotMeshSettings, HotMeshWorker } from './hotmesh';
|
|
14
|
-
export { ActivateMessage, JobMessage, JobMessageCallback, PingMessage, PongMessage, QuorumMessage, SubscriptionCallback, ThrottleMessage, WorkMessage } from './quorum';
|
|
13
|
+
export { HotMesh, HotMeshApp, HotMeshApps, HotMeshConfig, HotMeshEngine, RedisConfig, HotMeshGraph, HotMeshManifest, HotMeshSettings, HotMeshWorker, KeyStoreParams, KeyType } from './hotmesh';
|
|
14
|
+
export { ActivateMessage, JobMessage, JobMessageCallback, PingMessage, PongMessage, QuorumMessage, QuorumMessageCallback, QuorumProfile, SubscriptionCallback, ThrottleMessage, WorkMessage } from './quorum';
|
|
15
15
|
export { MultiResponseFlags, RedisClient, RedisMulti } from './redis';
|
|
16
16
|
export { RedisClientType, RedisMultiType } from './redisclient';
|
|
17
17
|
export { JSONSchema, StringAnyType, StringScalarType, StringStringType, SymbolMap, SymbolMaps, SymbolRanges, Symbols, SymbolSets } from './serializer';
|
|
18
18
|
export { AggregatedData, CountByFacet, GetStatsOptions, IdsData, Measure, MeasureIds, MetricTypes, StatType, StatsType, IdsResponse, JobStats, JobStatsInput, JobStatsRange, StatsResponse, Segment, TimeSegment } from './stats';
|
|
19
19
|
export { ReclaimedMessageType, StreamCode, StreamConfig, StreamData, StreamDataType, StreamError, StreamDataResponse, StreamRetryPolicy, StreamRole, StreamStatus } from './stream';
|
|
20
20
|
export { context, Context, Counter, Meter, metrics, propagation, SpanContext, Span, SpanStatus, SpanStatusCode, SpanKind, trace, Tracer, ValueType } from './telemetry';
|
|
21
|
+
export { WorkListTaskType } from './task';
|
|
21
22
|
export { TransitionMatch, TransitionRule, Transitions } from './transition';
|
package/build/types/index.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ValueType = exports.trace = exports.SpanKind = exports.SpanStatusCode = exports.propagation = exports.metrics = exports.context = exports.StreamStatus = exports.StreamRole = exports.StreamDataType = exports.IORedisClientType = exports.HookGate = exports.CollationFaultType = void 0;
|
|
3
|
+
exports.ValueType = exports.trace = exports.SpanKind = exports.SpanStatusCode = exports.propagation = exports.metrics = exports.context = exports.StreamStatus = exports.StreamRole = exports.StreamDataType = exports.KeyType = exports.IORedisClientType = exports.HookGate = exports.CollationFaultType = void 0;
|
|
4
4
|
var collator_1 = require("./collator");
|
|
5
5
|
Object.defineProperty(exports, "CollationFaultType", { enumerable: true, get: function () { return collator_1.CollationFaultType; } });
|
|
6
6
|
var hook_1 = require("./hook");
|
|
7
7
|
Object.defineProperty(exports, "HookGate", { enumerable: true, get: function () { return hook_1.HookGate; } });
|
|
8
8
|
var ioredisclient_1 = require("./ioredisclient");
|
|
9
9
|
Object.defineProperty(exports, "IORedisClientType", { enumerable: true, get: function () { return ioredisclient_1.RedisClientType; } });
|
|
10
|
+
var hotmesh_1 = require("./hotmesh");
|
|
11
|
+
Object.defineProperty(exports, "KeyType", { enumerable: true, get: function () { return hotmesh_1.KeyType; } });
|
|
10
12
|
var stream_1 = require("./stream");
|
|
11
13
|
Object.defineProperty(exports, "StreamDataType", { enumerable: true, get: function () { return stream_1.StreamDataType; } });
|
|
12
14
|
Object.defineProperty(exports, "StreamRole", { enumerable: true, get: function () { return stream_1.StreamRole; } });
|
package/build/types/logger.d.ts
CHANGED
package/build/types/logger.js
CHANGED
package/build/types/quorum.d.ts
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import { JobOutput } from "./job";
|
|
2
|
+
export interface QuorumProfile {
|
|
3
|
+
namespace: string;
|
|
4
|
+
app_id: string;
|
|
5
|
+
engine_id: string;
|
|
6
|
+
worker_topic?: string;
|
|
7
|
+
stream?: string;
|
|
8
|
+
stream_depth?: number;
|
|
9
|
+
}
|
|
2
10
|
export interface PingMessage {
|
|
3
11
|
type: 'ping';
|
|
4
12
|
originator: string;
|
|
13
|
+
details?: boolean;
|
|
5
14
|
}
|
|
6
15
|
export interface WorkMessage {
|
|
7
16
|
type: 'work';
|
|
@@ -13,8 +22,9 @@ export interface CronMessage {
|
|
|
13
22
|
}
|
|
14
23
|
export interface PongMessage {
|
|
15
24
|
type: 'pong';
|
|
16
|
-
originator: string;
|
|
17
25
|
guid: string;
|
|
26
|
+
originator: string;
|
|
27
|
+
profile?: QuorumProfile;
|
|
18
28
|
}
|
|
19
29
|
export interface ActivateMessage {
|
|
20
30
|
type: 'activate';
|
|
@@ -4,6 +4,7 @@ interface RedisMultiType {
|
|
|
4
4
|
XADD(key: string, id: string, fields: any): this;
|
|
5
5
|
XACK(key: string, group: string, id: string): this;
|
|
6
6
|
XDEL(key: string, id: string): this;
|
|
7
|
+
XLEN(key: string): this;
|
|
7
8
|
HDEL(key: string, itemId: string): this;
|
|
8
9
|
HGET(key: string, itemId: string): this;
|
|
9
10
|
HGETALL(key: string): this;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type WorkListTaskType = 'sleep' | 'expire' | 'interrupt' | 'delist';
|
package/modules/enums.ts
CHANGED
|
@@ -1,35 +1,49 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export const
|
|
10
|
-
export const
|
|
11
|
-
export const
|
|
12
|
-
|
|
13
|
-
export const
|
|
14
|
-
|
|
15
|
-
export const
|
|
16
|
-
|
|
17
|
-
export const
|
|
18
|
-
export const
|
|
19
|
-
export const
|
|
20
|
-
|
|
21
|
-
export const
|
|
22
|
-
|
|
23
|
-
export const
|
|
24
|
-
|
|
25
|
-
//
|
|
26
|
-
export const
|
|
27
|
-
export const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
export const
|
|
33
|
-
|
|
34
|
-
//
|
|
35
|
-
|
|
1
|
+
import { LogLevel } from "../types/logger";
|
|
2
|
+
|
|
3
|
+
// HOTMESH SYSTEM
|
|
4
|
+
export const HMSH_LOGLEVEL = process.env.HMSH_LOGLEVEL as LogLevel || 'info';
|
|
5
|
+
|
|
6
|
+
// STATUS CODES AND MESSAGES
|
|
7
|
+
export const HMSH_CODE_SUCCESS = 200;
|
|
8
|
+
export const HMSH_CODE_PENDING = 202;
|
|
9
|
+
export const HMSH_CODE_NOTFOUND = 404;
|
|
10
|
+
export const HMSH_CODE_INTERRUPT = 410;
|
|
11
|
+
export const HMSH_CODE_UNKNOWN = 500;
|
|
12
|
+
export const HMSH_CODE_TIMEOUT = 504;
|
|
13
|
+
export const HMSH_CODE_UNACKED = 999;
|
|
14
|
+
|
|
15
|
+
export const HMSH_CODE_DURABLE_SLEEPFOR = 592;
|
|
16
|
+
export const HMSH_CODE_DURABLE_INCOMPLETE = 593;
|
|
17
|
+
export const HMSH_CODE_DURABLE_WAITFOR = 594;
|
|
18
|
+
export const HMSH_CODE_DURABLE_TIMEOUT = 596;
|
|
19
|
+
export const HMSH_CODE_DURABLE_MAXED = 597;
|
|
20
|
+
export const HMSH_CODE_DURABLE_FATAL = 598;
|
|
21
|
+
export const HMSH_CODE_DURABLE_RETRYABLE = 599;
|
|
22
|
+
|
|
23
|
+
export const HMSH_STATUS_UNKNOWN = 'unknown';
|
|
24
|
+
|
|
25
|
+
// ENGINE
|
|
26
|
+
export const HMSH_OTT_WAIT_TIME = parseInt(process.env.HMSH_OTT_WAIT_TIME, 10) || 1000;
|
|
27
|
+
export const HMSH_EXPIRE_JOB_SECONDS = parseInt(process.env.HMSH_EXPIRE_JOB_SECONDS, 10) || 1;
|
|
28
|
+
|
|
29
|
+
// STREAM ROUTER
|
|
30
|
+
export const HMSH_MAX_RETRIES = parseInt(process.env.HMSH_MAX_RETRIES, 10) || 3;
|
|
31
|
+
export const HMSH_MAX_TIMEOUT_MS = parseInt(process.env.HMSH_MAX_TIMEOUT_MS, 10) || 60000;
|
|
32
|
+
export const HMSH_GRADUATED_INTERVAL_MS = parseInt(process.env.HMSH_GRADUATED_INTERVAL_MS, 10) || 5000;
|
|
33
|
+
|
|
34
|
+
const BASE_BLOCK_DURATION = 10000; // Modified for clarity
|
|
35
|
+
const TEST_BLOCK_DURATION = 1000; // Modified for clarity
|
|
36
|
+
export const HMSH_BLOCK_TIME_MS = process.env.HMSH_BLOCK_TIME_MS ? parseInt(process.env.HMSH_BLOCK_TIME_MS, 10) : (process.env.NODE_ENV === 'test' ? TEST_BLOCK_DURATION : BASE_BLOCK_DURATION);
|
|
37
|
+
|
|
38
|
+
export const HMSH_XCLAIM_DELAY_MS = parseInt(process.env.HMSH_XCLAIM_DELAY_MS, 10) || 1000 * 60;
|
|
39
|
+
export const HMSH_XCLAIM_COUNT = parseInt(process.env.HMSH_XCLAIM_COUNT, 10) || 3;
|
|
40
|
+
export const HMSH_XPENDING_COUNT = parseInt(process.env.HMSH_XPENDING_COUNT, 10) || 10;
|
|
41
|
+
|
|
42
|
+
// TASK WORKER
|
|
43
|
+
export const HMSH_EXPIRE_DURATION = parseInt(process.env.HMSH_EXPIRE_DURATION, 10) || 1;
|
|
44
|
+
|
|
45
|
+
const BASE_FIDELITY_SECONDS = 5;
|
|
46
|
+
const TEST_FIDELITY_SECONDS = 5;
|
|
47
|
+
export const HMSH_FIDELITY_SECONDS = process.env.HMSH_FIDELITY_SECONDS ? parseInt(process.env.HMSH_FIDELITY_SECONDS, 10) : (process.env.NODE_ENV === 'test' ? TEST_FIDELITY_SECONDS : BASE_FIDELITY_SECONDS);
|
|
48
|
+
|
|
49
|
+
export const HMSH_SCOUT_INTERVAL_SECONDS = parseInt(process.env.HMSH_SCOUT_INTERVAL_SECONDS, 10) || 60;
|