@koala42/redis-highway 0.2.3 → 0.2.4
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/dist/src/base-worker.d.ts +3 -2
- package/dist/src/base-worker.js +9 -2
- package/dist/src/batch-worker.d.ts +2 -2
- package/dist/src/batch-worker.js +2 -2
- package/dist/src/interfaces.d.ts +4 -0
- package/dist/src/interfaces.js +4 -1
- package/dist/src/lua.d.ts +1 -0
- package/dist/src/lua.js +31 -1
- package/dist/src/worker.d.ts +2 -2
- package/dist/src/worker.js +2 -2
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { EventEmitter } from "events";
|
|
2
2
|
import { KeyManager } from "./keys";
|
|
3
3
|
import Redis from "ioredis";
|
|
4
|
-
import { BaseWorkerControlOptions, BaseWorkerOptions, StreamMessage, XReadGroupResponse } from "./interfaces";
|
|
4
|
+
import { BaseWorkerControlOptions, BaseWorkerCustomMetricsOptions, BaseWorkerOptions, StreamMessage, XReadGroupResponse } from "./interfaces";
|
|
5
5
|
import { StreamMessageEntity } from "./stream-message-entity";
|
|
6
6
|
export declare abstract class BaseWorker<T extends Record<string, unknown>> {
|
|
7
7
|
protected redis: Redis;
|
|
@@ -20,7 +20,8 @@ export declare abstract class BaseWorker<T extends Record<string, unknown>> {
|
|
|
20
20
|
protected readonly _claimIntervalMs: number;
|
|
21
21
|
protected readonly _minIdleTimeMs: number;
|
|
22
22
|
protected readonly _collectMetrics: boolean;
|
|
23
|
-
|
|
23
|
+
protected readonly _finalIncrementMetricKey: ((item: T) => string | null) | null;
|
|
24
|
+
constructor(redis: Redis, options: BaseWorkerOptions, controlOptions: BaseWorkerControlOptions, metricsOptions: BaseWorkerCustomMetricsOptions<T>);
|
|
24
25
|
/**
|
|
25
26
|
* Start the worker process
|
|
26
27
|
* Starts fetch loop and auto claim loop
|
package/dist/src/base-worker.js
CHANGED
|
@@ -7,7 +7,7 @@ const uuid_1 = require("uuid");
|
|
|
7
7
|
const stream_message_entity_1 = require("./stream-message-entity");
|
|
8
8
|
const lua_1 = require("./lua");
|
|
9
9
|
class BaseWorker {
|
|
10
|
-
constructor(redis, options, controlOptions) {
|
|
10
|
+
constructor(redis, options, controlOptions, metricsOptions) {
|
|
11
11
|
this.redis = redis;
|
|
12
12
|
this._isRunning = false;
|
|
13
13
|
this._activeCount = 0;
|
|
@@ -22,6 +22,7 @@ class BaseWorker {
|
|
|
22
22
|
this._claimIntervalMs = controlOptions.claimIntervalMs;
|
|
23
23
|
this._minIdleTimeMs = controlOptions.minIdleTimeMs;
|
|
24
24
|
this._collectMetrics = controlOptions.collectMetrics;
|
|
25
|
+
this._finalIncrementMetricKey = metricsOptions.finalIncrementMetricKey ?? null;
|
|
25
26
|
this._consumerName = `${this._groupName}-${this._consumerId}`;
|
|
26
27
|
this._keys = new keys_1.KeyManager(options.streamName);
|
|
27
28
|
this._blockingRedis = redis.duplicate();
|
|
@@ -178,7 +179,13 @@ class BaseWorker {
|
|
|
178
179
|
}
|
|
179
180
|
for (const msg of messages) {
|
|
180
181
|
const statusKey = this._keys.getJobStatusKey(msg.messageUuid);
|
|
181
|
-
|
|
182
|
+
const customMetricKey = this._finalIncrementMetricKey ? this._finalIncrementMetricKey(msg.data) : null;
|
|
183
|
+
if (customMetricKey) {
|
|
184
|
+
pipeline.eval(lua_1.LUA_FINALIZE_CUSTOM_METRIC, 3, statusKey, this._streamName, customMetricKey, this._groupName, timestamp, msg.streamMessageId);
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
pipeline.eval(lua_1.LUA_FINALIZE, 2, statusKey, this._streamName, this._groupName, timestamp, msg.streamMessageId);
|
|
188
|
+
}
|
|
182
189
|
}
|
|
183
190
|
await pipeline.exec();
|
|
184
191
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import Redis from "ioredis";
|
|
2
|
-
import { BaseWorkerControlOptions, BatchWorkerOptions } from "./interfaces";
|
|
2
|
+
import { BaseWorkerControlOptions, BaseWorkerCustomMetricsOptions, BatchWorkerOptions } from "./interfaces";
|
|
3
3
|
import { BaseWorker } from "./base-worker";
|
|
4
4
|
export declare abstract class BatchWorker<T extends Record<string, unknown>> extends BaseWorker<T> {
|
|
5
5
|
private readonly _batchSize;
|
|
6
6
|
private readonly _maxFetchCount;
|
|
7
|
-
constructor(redis: Redis, options: BatchWorkerOptions, controlOptions?: BaseWorkerControlOptions);
|
|
7
|
+
constructor(redis: Redis, options: BatchWorkerOptions, controlOptions?: BaseWorkerControlOptions, metricsOptions?: BaseWorkerCustomMetricsOptions<T>);
|
|
8
8
|
protected _fetchLoop(): Promise<void>;
|
|
9
9
|
/**
|
|
10
10
|
* Spawn worker for current processing
|
package/dist/src/batch-worker.js
CHANGED
|
@@ -5,8 +5,8 @@ const interfaces_1 = require("./interfaces");
|
|
|
5
5
|
const stream_message_entity_1 = require("./stream-message-entity");
|
|
6
6
|
const base_worker_1 = require("./base-worker");
|
|
7
7
|
class BatchWorker extends base_worker_1.BaseWorker {
|
|
8
|
-
constructor(redis, options, controlOptions = interfaces_1.defaultBaseWorkerControlOptions) {
|
|
9
|
-
super(redis, options, controlOptions);
|
|
8
|
+
constructor(redis, options, controlOptions = interfaces_1.defaultBaseWorkerControlOptions, metricsOptions = interfaces_1.defaultBaseWorkerCustomMetrics) {
|
|
9
|
+
super(redis, options, controlOptions, metricsOptions);
|
|
10
10
|
this._batchSize = options.batchSize;
|
|
11
11
|
this._maxFetchCount = options.maxFetchCount;
|
|
12
12
|
if (this._batchSize === 1) {
|
package/dist/src/interfaces.d.ts
CHANGED
|
@@ -12,6 +12,10 @@ export interface BaseWorkerControlOptions {
|
|
|
12
12
|
minIdleTimeMs: number;
|
|
13
13
|
collectMetrics: boolean;
|
|
14
14
|
}
|
|
15
|
+
export interface BaseWorkerCustomMetricsOptions<T extends Record<string, unknown>> {
|
|
16
|
+
finalIncrementMetricKey?: ((item: T) => string | null) | null;
|
|
17
|
+
}
|
|
18
|
+
export declare const defaultBaseWorkerCustomMetrics: BaseWorkerCustomMetricsOptions<{}>;
|
|
15
19
|
export declare const defaultBaseWorkerControlOptions: BaseWorkerControlOptions;
|
|
16
20
|
export interface BatchWorkerOptions extends BaseWorkerOptions {
|
|
17
21
|
batchSize: number;
|
package/dist/src/interfaces.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.defaultBaseWorkerControlOptions = void 0;
|
|
3
|
+
exports.defaultBaseWorkerControlOptions = exports.defaultBaseWorkerCustomMetrics = void 0;
|
|
4
|
+
exports.defaultBaseWorkerCustomMetrics = {
|
|
5
|
+
finalIncrementMetricKey: null
|
|
6
|
+
};
|
|
4
7
|
exports.defaultBaseWorkerControlOptions = {
|
|
5
8
|
maxRetries: 3,
|
|
6
9
|
minIdleTimeMs: 120000,
|
package/dist/src/lua.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
1
|
export declare const LUA_FINALIZE = "\n-- KEYS[1] = status key\n-- KEYS[2] = stream key\n-- ARGV[1] = group name\n-- ARGV[2] = timestamp\n-- ARGV[3] = msgId\n\n-- 1. Update status\nredis.call('HSET', KEYS[1], ARGV[1], ARGV[2])\n\n-- 2. Check completions\nlocal current_fields = redis.call('HLEN', KEYS[1])\nlocal target_str = redis.call('HGET', KEYS[1], '__target')\nlocal target = tonumber(target_str)\n\nif not target then\n return 0\nend\n\n-- 3. Cleanup if done\nif current_fields >= (target + 1) then\n redis.call('DEL', KEYS[1])\n redis.call('XDEL', KEYS[2], ARGV[3])\n return 1\nend\n\nreturn 0\n";
|
|
2
|
+
export declare const LUA_FINALIZE_CUSTOM_METRIC = "\n -- KEYS[1] = status key\n -- KEYS[2] = stream key\n -- KEYS[3] = custom metric increment key\n -- ARGV[1] = group name\n -- ARGV[2] = timestamp\n -- ARGV[3] = msgId\n\n -- 1. Update status\n redis.call('HSET', KEYS[1], ARGV[1], ARGV[2])\n\n -- 2. Check completions\n local current_fields = redis.call('HLEN', KEYS[1])\n local target_str = redis.call('HGET', KEYS[1], '__target')\n local target = tonumber(target_str)\n\n if not target then\n return 0\n end\n\n -- 3. Cleanup if done\n if current_fields >= (target + 1) then\n redis.call('DEL', KEYS[1])\n redis.call('XDEL', KEYS[2], ARGV[3])\n redis.pcall('INCRBY', KEYS[3], 1)\n return 1\n end\n\n return 0\n";
|
package/dist/src/lua.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LUA_FINALIZE = void 0;
|
|
3
|
+
exports.LUA_FINALIZE_CUSTOM_METRIC = exports.LUA_FINALIZE = void 0;
|
|
4
4
|
exports.LUA_FINALIZE = `
|
|
5
5
|
-- KEYS[1] = status key
|
|
6
6
|
-- KEYS[2] = stream key
|
|
@@ -29,3 +29,33 @@ end
|
|
|
29
29
|
|
|
30
30
|
return 0
|
|
31
31
|
`;
|
|
32
|
+
exports.LUA_FINALIZE_CUSTOM_METRIC = `
|
|
33
|
+
-- KEYS[1] = status key
|
|
34
|
+
-- KEYS[2] = stream key
|
|
35
|
+
-- KEYS[3] = custom metric increment key
|
|
36
|
+
-- ARGV[1] = group name
|
|
37
|
+
-- ARGV[2] = timestamp
|
|
38
|
+
-- ARGV[3] = msgId
|
|
39
|
+
|
|
40
|
+
-- 1. Update status
|
|
41
|
+
redis.call('HSET', KEYS[1], ARGV[1], ARGV[2])
|
|
42
|
+
|
|
43
|
+
-- 2. Check completions
|
|
44
|
+
local current_fields = redis.call('HLEN', KEYS[1])
|
|
45
|
+
local target_str = redis.call('HGET', KEYS[1], '__target')
|
|
46
|
+
local target = tonumber(target_str)
|
|
47
|
+
|
|
48
|
+
if not target then
|
|
49
|
+
return 0
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
-- 3. Cleanup if done
|
|
53
|
+
if current_fields >= (target + 1) then
|
|
54
|
+
redis.call('DEL', KEYS[1])
|
|
55
|
+
redis.call('XDEL', KEYS[2], ARGV[3])
|
|
56
|
+
redis.pcall('INCRBY', KEYS[3], 1)
|
|
57
|
+
return 1
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
return 0
|
|
61
|
+
`;
|
package/dist/src/worker.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import Redis from "ioredis";
|
|
2
|
-
import { BaseWorkerOptions, BaseWorkerControlOptions } from "./interfaces";
|
|
2
|
+
import { BaseWorkerOptions, BaseWorkerControlOptions, BaseWorkerCustomMetricsOptions } from "./interfaces";
|
|
3
3
|
import { BaseWorker } from "./base-worker";
|
|
4
4
|
export declare abstract class Worker<T extends Record<string, unknown>> extends BaseWorker<T> {
|
|
5
|
-
constructor(redis: Redis, options: BaseWorkerOptions, controlOptions?: BaseWorkerControlOptions);
|
|
5
|
+
constructor(redis: Redis, options: BaseWorkerOptions, controlOptions?: BaseWorkerControlOptions, metricsOptions?: BaseWorkerCustomMetricsOptions<T>);
|
|
6
6
|
/**
|
|
7
7
|
* Fetch loop (the main loop)
|
|
8
8
|
* Based on free slots (concurrency - active count) gets new messages
|
package/dist/src/worker.js
CHANGED
|
@@ -5,8 +5,8 @@ const interfaces_1 = require("./interfaces");
|
|
|
5
5
|
const stream_message_entity_1 = require("./stream-message-entity");
|
|
6
6
|
const base_worker_1 = require("./base-worker");
|
|
7
7
|
class Worker extends base_worker_1.BaseWorker {
|
|
8
|
-
constructor(redis, options, controlOptions = interfaces_1.defaultBaseWorkerControlOptions) {
|
|
9
|
-
super(redis, options, controlOptions);
|
|
8
|
+
constructor(redis, options, controlOptions = interfaces_1.defaultBaseWorkerControlOptions, metricsOptions = interfaces_1.defaultBaseWorkerCustomMetrics) {
|
|
9
|
+
super(redis, options, controlOptions, metricsOptions);
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
12
|
* Fetch loop (the main loop)
|