@yroshcha/node-red-contrib-redis-full 1.0.5 → 1.0.6
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/CHANGELOG.md +6 -0
- package/README.md +2 -1
- package/package.json +1 -1
- package/redis.js +20 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project are documented in this file.
|
|
4
4
|
|
|
5
|
+
## 1.0.6 — 2026-08-11
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- `redis xreadgroup` now restores its consumer group with `MKSTREAM` when a running consumer receives `NOGROUP`, including a deleted or restarted DLQ stream.
|
|
10
|
+
|
|
5
11
|
## 1.0.5 — 2026-08-11
|
|
6
12
|
|
|
7
13
|
### Fixed
|
package/README.md
CHANGED
|
@@ -45,7 +45,7 @@ For a local archive, use `npm install /path/to/yroshcha-node-red-contrib-redis-f
|
|
|
45
45
|
|
|
46
46
|
## Release status
|
|
47
47
|
|
|
48
|
-
**`1.0.
|
|
48
|
+
**`1.0.6` is the current stable release.** See [CHANGELOG.md](CHANGELOG.md) for release notes and compatibility information.
|
|
49
49
|
|
|
50
50
|
## Production profile
|
|
51
51
|
|
|
@@ -62,6 +62,7 @@ Safe consumer defaults and important settings:
|
|
|
62
62
|
- **Max deliveries = 5.** After the limit is exceeded, an entry is atomically moved to `<stream>:dlq` and acknowledged. In Redis Cluster, source and DLQ keys must share a hash tag, for example `orders:{eu}` and `orders:{eu}:dlq`.
|
|
63
63
|
- **Start paused (wait for resume)** makes a consumer create/verify its group without calling `XREADGROUP`. It takes no work until a control-plane `resume` request arrives; use it for controlled pod startup after readiness checks.
|
|
64
64
|
- Startup initialisation retries a failed dedicated connection, `XGROUP CREATE`, and the initial `SUBSCRIBE` up to **five times** with exponential backoff and jitter. A transient Redis/TLS/DNS delay does not permanently stop a new consumer or subscriber.
|
|
65
|
+
- If a consumer group disappears after startup (for example after a Redis restart, `XGROUP DESTROY`, or deleting an empty DLQ stream), `redis xreadgroup` recreates it with `MKSTREAM` and resumes.
|
|
65
66
|
- `redis xautoclaim` limits each manual recovery run through `Run limit` (default 1000), avoiding oversized Node-RED payloads.
|
|
66
67
|
- `redis scan` limits one emitted Node-RED message to **10,000** items by default. It sets `msg.scanTruncated = true` when that safety limit is reached; raise `Result limit` / `msg.maxResults` only after sizing the Node-RED heap for the result.
|
|
67
68
|
- `MAXLEN` in `redis xadd` remains blocked until **Allow unsafe MAXLEN trim** is explicitly confirmed. Trimming can remove a payload still represented in a PEL.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yroshcha/node-red-contrib-redis-full",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "Production-oriented Redis palette for Node-RED: generic commands, Pub/Sub, scans, transactions, and Redis Streams consumer groups.",
|
|
5
5
|
"keywords": ["node-red", "redis", "redis-streams", "pubsub", "xadd", "xreadgroup", "ioredis"],
|
|
6
6
|
"license": "MIT",
|
package/redis.js
CHANGED
|
@@ -173,6 +173,10 @@ module.exports = function (RED) {
|
|
|
173
173
|
return obj;
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
+
function isNoGroupError(err) {
|
|
177
|
+
return String(err && err.message ? err.message : err).includes('NOGROUP');
|
|
178
|
+
}
|
|
179
|
+
|
|
176
180
|
// ---------------------------------------------------------------------
|
|
177
181
|
// yroshcha-redis-command — БУДЬ-ЯКА команда Redis через ioredis .call().
|
|
178
182
|
// "block" форсує окреме з'єднання (для BLPOP/BRPOP/WAIT тощо).
|
|
@@ -962,6 +966,22 @@ module.exports = function (RED) {
|
|
|
962
966
|
} catch (err) {
|
|
963
967
|
if (stopped) break;
|
|
964
968
|
|
|
969
|
+
// A Redis restart, a manual XGROUP DESTROY, or deletion of an empty
|
|
970
|
+
// DLQ stream can remove the group after this node has started.
|
|
971
|
+
// Recreate it before backing off; ensureGroup handles a concurrent
|
|
972
|
+
// creator through BUSYGROUP and is safe to call repeatedly.
|
|
973
|
+
if (isNoGroupError(err)) {
|
|
974
|
+
try {
|
|
975
|
+
await ensureGroup(blockingClient);
|
|
976
|
+
currentBackoffMs = node.initialBackoffMs;
|
|
977
|
+
node.status({ fill: 'yellow', shape: 'ring', text: 'consumer group restored' });
|
|
978
|
+
node.warn(`Redis stream consumer group restored: ${node.group}@${node.streamKey}`);
|
|
979
|
+
continue;
|
|
980
|
+
} catch (restoreErr) {
|
|
981
|
+
err = restoreErr;
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
|
|
965
985
|
const jitter = Math.random() * currentBackoffMs * 0.3; // до +30%
|
|
966
986
|
const delay = Math.min(currentBackoffMs, node.maxBackoffMs) + jitter;
|
|
967
987
|
|