@getstrata/core 2.2.24 → 2.2.25
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 +4 -0
- package/dist/core/queue/redisQueue.d.ts +2 -1
- package/dist/core/queue/redisStreams.d.ts +2 -1
- package/dist/entries/queue/createAppQueue.js +31 -3
- package/dist/entries/queue/publicQueue.js +31 -3
- package/dist/entries/queue/queueMetrics.js +31 -3
- package/dist/entries/queue/redisQueue.js +31 -3
- package/dist/index.js +31 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# @getstrata/core changelog
|
|
2
2
|
|
|
3
|
+
## 2.2.25
|
|
4
|
+
|
|
5
|
+
Queue worker run loops recover native Redis connection closure with bounded backoff and a fresh connection. Uncertain Redis mutations are not replayed; retained reservations and retries use normal recovery. Explicit closure remains terminal and non-connection errors remain fatal. Native poll/ack closure regressions cover Streams and list transports.
|
|
6
|
+
|
|
3
7
|
## 2.2.24
|
|
4
8
|
|
|
5
9
|
Fix Redis cache recovery after transport failures and command deadlines: retire failed connections, abort active fills, and lazily reconnect for later operations without replaying uncertain commands; preserve permanent explicit closure and shared invalidation fencing.
|
|
@@ -27,13 +27,14 @@ declare class RedisQueue implements Queue {
|
|
|
27
27
|
dispatch<TPayload extends object>(job: Job<TPayload>, payload: TPayload): Promise<void>;
|
|
28
28
|
}
|
|
29
29
|
declare class QueueWorker {
|
|
30
|
+
private readonly redisUrl;
|
|
30
31
|
private readonly failedJobs;
|
|
31
32
|
private readonly timeoutSeconds;
|
|
32
33
|
private readonly queueKeys;
|
|
33
34
|
private readonly owner;
|
|
34
35
|
private running;
|
|
35
36
|
private stopping;
|
|
36
|
-
private
|
|
37
|
+
private client;
|
|
37
38
|
constructor(redisUrl: string, failedJobs: FailedJobService, timeoutSeconds?: number, queueKeys?: readonly string[]);
|
|
38
39
|
requestStop(): void;
|
|
39
40
|
isRunning(): boolean;
|
|
@@ -49,10 +49,11 @@ declare class RedisStreamsQueue implements Queue {
|
|
|
49
49
|
cancel(jobId: string): Promise<boolean>;
|
|
50
50
|
}
|
|
51
51
|
declare class RedisStreamsWorker {
|
|
52
|
+
private readonly redisUrl;
|
|
52
53
|
private readonly failedJobs;
|
|
53
54
|
private readonly timeoutSeconds;
|
|
54
55
|
private readonly queueKeys;
|
|
55
|
-
private
|
|
56
|
+
private client;
|
|
56
57
|
private readonly owner;
|
|
57
58
|
private readonly cursors;
|
|
58
59
|
private processing;
|
|
@@ -690,6 +690,7 @@ class RedisStreamsQueue {
|
|
|
690
690
|
}
|
|
691
691
|
|
|
692
692
|
class RedisStreamsWorker {
|
|
693
|
+
redisUrl;
|
|
693
694
|
failedJobs;
|
|
694
695
|
timeoutSeconds;
|
|
695
696
|
queueKeys;
|
|
@@ -702,6 +703,7 @@ class RedisStreamsWorker {
|
|
|
702
703
|
stopping = false;
|
|
703
704
|
active;
|
|
704
705
|
constructor(redisUrl, failedJobs, timeoutSeconds = 5, queueKeys = defaultQueueKeys()) {
|
|
706
|
+
this.redisUrl = redisUrl;
|
|
705
707
|
this.failedJobs = failedJobs;
|
|
706
708
|
this.timeoutSeconds = timeoutSeconds;
|
|
707
709
|
this.queueKeys = queueKeys;
|
|
@@ -891,8 +893,21 @@ class RedisStreamsWorker {
|
|
|
891
893
|
async run() {
|
|
892
894
|
this.running = true;
|
|
893
895
|
try {
|
|
894
|
-
while (!this.stopping)
|
|
895
|
-
|
|
896
|
+
while (!this.stopping) {
|
|
897
|
+
try {
|
|
898
|
+
await this.processNext();
|
|
899
|
+
} catch (error) {
|
|
900
|
+
if (!(error && typeof error === "object" && ("code" in error) && error.code === "ERR_REDIS_CONNECTION_CLOSED"))
|
|
901
|
+
throw error;
|
|
902
|
+
this.client.close();
|
|
903
|
+
await Bun.sleep(250);
|
|
904
|
+
if (this.stopping)
|
|
905
|
+
return;
|
|
906
|
+
this.client = new RedisClient(this.redisUrl);
|
|
907
|
+
this.initialized = false;
|
|
908
|
+
this.cursors.clear();
|
|
909
|
+
}
|
|
910
|
+
}
|
|
896
911
|
} finally {
|
|
897
912
|
this.running = false;
|
|
898
913
|
}
|
|
@@ -1195,6 +1210,7 @@ class RedisQueue {
|
|
|
1195
1210
|
}
|
|
1196
1211
|
|
|
1197
1212
|
class QueueWorker {
|
|
1213
|
+
redisUrl;
|
|
1198
1214
|
failedJobs;
|
|
1199
1215
|
timeoutSeconds;
|
|
1200
1216
|
queueKeys;
|
|
@@ -1203,6 +1219,7 @@ class QueueWorker {
|
|
|
1203
1219
|
stopping = false;
|
|
1204
1220
|
client;
|
|
1205
1221
|
constructor(redisUrl, failedJobs, timeoutSeconds = 5, queueKeys = QUEUE_KEYS) {
|
|
1222
|
+
this.redisUrl = redisUrl;
|
|
1206
1223
|
this.failedJobs = failedJobs;
|
|
1207
1224
|
this.timeoutSeconds = timeoutSeconds;
|
|
1208
1225
|
this.queueKeys = queueKeys;
|
|
@@ -1283,13 +1300,24 @@ class QueueWorker {
|
|
|
1283
1300
|
this.running = true;
|
|
1284
1301
|
try {
|
|
1285
1302
|
while (!this.stopping) {
|
|
1286
|
-
|
|
1303
|
+
try {
|
|
1304
|
+
await this.processNext();
|
|
1305
|
+
} catch (error) {
|
|
1306
|
+
if (!(error && typeof error === "object" && ("code" in error) && error.code === "ERR_REDIS_CONNECTION_CLOSED"))
|
|
1307
|
+
throw error;
|
|
1308
|
+
this.client.close();
|
|
1309
|
+
await Bun.sleep(250);
|
|
1310
|
+
if (this.stopping)
|
|
1311
|
+
return;
|
|
1312
|
+
this.client = new RedisClient2(this.redisUrl);
|
|
1313
|
+
}
|
|
1287
1314
|
}
|
|
1288
1315
|
} finally {
|
|
1289
1316
|
this.running = false;
|
|
1290
1317
|
}
|
|
1291
1318
|
}
|
|
1292
1319
|
close() {
|
|
1320
|
+
this.stopping = true;
|
|
1293
1321
|
this.client.close();
|
|
1294
1322
|
}
|
|
1295
1323
|
}
|
|
@@ -690,6 +690,7 @@ class RedisStreamsQueue {
|
|
|
690
690
|
}
|
|
691
691
|
|
|
692
692
|
class RedisStreamsWorker {
|
|
693
|
+
redisUrl;
|
|
693
694
|
failedJobs;
|
|
694
695
|
timeoutSeconds;
|
|
695
696
|
queueKeys;
|
|
@@ -702,6 +703,7 @@ class RedisStreamsWorker {
|
|
|
702
703
|
stopping = false;
|
|
703
704
|
active;
|
|
704
705
|
constructor(redisUrl, failedJobs, timeoutSeconds = 5, queueKeys = defaultQueueKeys()) {
|
|
706
|
+
this.redisUrl = redisUrl;
|
|
705
707
|
this.failedJobs = failedJobs;
|
|
706
708
|
this.timeoutSeconds = timeoutSeconds;
|
|
707
709
|
this.queueKeys = queueKeys;
|
|
@@ -891,8 +893,21 @@ class RedisStreamsWorker {
|
|
|
891
893
|
async run() {
|
|
892
894
|
this.running = true;
|
|
893
895
|
try {
|
|
894
|
-
while (!this.stopping)
|
|
895
|
-
|
|
896
|
+
while (!this.stopping) {
|
|
897
|
+
try {
|
|
898
|
+
await this.processNext();
|
|
899
|
+
} catch (error) {
|
|
900
|
+
if (!(error && typeof error === "object" && ("code" in error) && error.code === "ERR_REDIS_CONNECTION_CLOSED"))
|
|
901
|
+
throw error;
|
|
902
|
+
this.client.close();
|
|
903
|
+
await Bun.sleep(250);
|
|
904
|
+
if (this.stopping)
|
|
905
|
+
return;
|
|
906
|
+
this.client = new RedisClient(this.redisUrl);
|
|
907
|
+
this.initialized = false;
|
|
908
|
+
this.cursors.clear();
|
|
909
|
+
}
|
|
910
|
+
}
|
|
896
911
|
} finally {
|
|
897
912
|
this.running = false;
|
|
898
913
|
}
|
|
@@ -1195,6 +1210,7 @@ class RedisQueue {
|
|
|
1195
1210
|
}
|
|
1196
1211
|
|
|
1197
1212
|
class QueueWorker {
|
|
1213
|
+
redisUrl;
|
|
1198
1214
|
failedJobs;
|
|
1199
1215
|
timeoutSeconds;
|
|
1200
1216
|
queueKeys;
|
|
@@ -1203,6 +1219,7 @@ class QueueWorker {
|
|
|
1203
1219
|
stopping = false;
|
|
1204
1220
|
client;
|
|
1205
1221
|
constructor(redisUrl, failedJobs, timeoutSeconds = 5, queueKeys = QUEUE_KEYS) {
|
|
1222
|
+
this.redisUrl = redisUrl;
|
|
1206
1223
|
this.failedJobs = failedJobs;
|
|
1207
1224
|
this.timeoutSeconds = timeoutSeconds;
|
|
1208
1225
|
this.queueKeys = queueKeys;
|
|
@@ -1283,13 +1300,24 @@ class QueueWorker {
|
|
|
1283
1300
|
this.running = true;
|
|
1284
1301
|
try {
|
|
1285
1302
|
while (!this.stopping) {
|
|
1286
|
-
|
|
1303
|
+
try {
|
|
1304
|
+
await this.processNext();
|
|
1305
|
+
} catch (error) {
|
|
1306
|
+
if (!(error && typeof error === "object" && ("code" in error) && error.code === "ERR_REDIS_CONNECTION_CLOSED"))
|
|
1307
|
+
throw error;
|
|
1308
|
+
this.client.close();
|
|
1309
|
+
await Bun.sleep(250);
|
|
1310
|
+
if (this.stopping)
|
|
1311
|
+
return;
|
|
1312
|
+
this.client = new RedisClient2(this.redisUrl);
|
|
1313
|
+
}
|
|
1287
1314
|
}
|
|
1288
1315
|
} finally {
|
|
1289
1316
|
this.running = false;
|
|
1290
1317
|
}
|
|
1291
1318
|
}
|
|
1292
1319
|
close() {
|
|
1320
|
+
this.stopping = true;
|
|
1293
1321
|
this.client.close();
|
|
1294
1322
|
}
|
|
1295
1323
|
}
|
|
@@ -1569,6 +1569,7 @@ class RedisStreamsQueue {
|
|
|
1569
1569
|
}
|
|
1570
1570
|
|
|
1571
1571
|
class RedisStreamsWorker {
|
|
1572
|
+
redisUrl;
|
|
1572
1573
|
failedJobs;
|
|
1573
1574
|
timeoutSeconds;
|
|
1574
1575
|
queueKeys;
|
|
@@ -1581,6 +1582,7 @@ class RedisStreamsWorker {
|
|
|
1581
1582
|
stopping = false;
|
|
1582
1583
|
active;
|
|
1583
1584
|
constructor(redisUrl, failedJobs, timeoutSeconds = 5, queueKeys = defaultQueueKeys()) {
|
|
1585
|
+
this.redisUrl = redisUrl;
|
|
1584
1586
|
this.failedJobs = failedJobs;
|
|
1585
1587
|
this.timeoutSeconds = timeoutSeconds;
|
|
1586
1588
|
this.queueKeys = queueKeys;
|
|
@@ -1770,8 +1772,21 @@ class RedisStreamsWorker {
|
|
|
1770
1772
|
async run() {
|
|
1771
1773
|
this.running = true;
|
|
1772
1774
|
try {
|
|
1773
|
-
while (!this.stopping)
|
|
1774
|
-
|
|
1775
|
+
while (!this.stopping) {
|
|
1776
|
+
try {
|
|
1777
|
+
await this.processNext();
|
|
1778
|
+
} catch (error) {
|
|
1779
|
+
if (!(error && typeof error === "object" && ("code" in error) && error.code === "ERR_REDIS_CONNECTION_CLOSED"))
|
|
1780
|
+
throw error;
|
|
1781
|
+
this.client.close();
|
|
1782
|
+
await Bun.sleep(250);
|
|
1783
|
+
if (this.stopping)
|
|
1784
|
+
return;
|
|
1785
|
+
this.client = new RedisClient(this.redisUrl);
|
|
1786
|
+
this.initialized = false;
|
|
1787
|
+
this.cursors.clear();
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1775
1790
|
} finally {
|
|
1776
1791
|
this.running = false;
|
|
1777
1792
|
}
|
|
@@ -2074,6 +2089,7 @@ class RedisQueue {
|
|
|
2074
2089
|
}
|
|
2075
2090
|
|
|
2076
2091
|
class QueueWorker {
|
|
2092
|
+
redisUrl;
|
|
2077
2093
|
failedJobs;
|
|
2078
2094
|
timeoutSeconds;
|
|
2079
2095
|
queueKeys;
|
|
@@ -2082,6 +2098,7 @@ class QueueWorker {
|
|
|
2082
2098
|
stopping = false;
|
|
2083
2099
|
client;
|
|
2084
2100
|
constructor(redisUrl, failedJobs, timeoutSeconds = 5, queueKeys = QUEUE_KEYS) {
|
|
2101
|
+
this.redisUrl = redisUrl;
|
|
2085
2102
|
this.failedJobs = failedJobs;
|
|
2086
2103
|
this.timeoutSeconds = timeoutSeconds;
|
|
2087
2104
|
this.queueKeys = queueKeys;
|
|
@@ -2162,13 +2179,24 @@ class QueueWorker {
|
|
|
2162
2179
|
this.running = true;
|
|
2163
2180
|
try {
|
|
2164
2181
|
while (!this.stopping) {
|
|
2165
|
-
|
|
2182
|
+
try {
|
|
2183
|
+
await this.processNext();
|
|
2184
|
+
} catch (error) {
|
|
2185
|
+
if (!(error && typeof error === "object" && ("code" in error) && error.code === "ERR_REDIS_CONNECTION_CLOSED"))
|
|
2186
|
+
throw error;
|
|
2187
|
+
this.client.close();
|
|
2188
|
+
await Bun.sleep(250);
|
|
2189
|
+
if (this.stopping)
|
|
2190
|
+
return;
|
|
2191
|
+
this.client = new RedisClient2(this.redisUrl);
|
|
2192
|
+
}
|
|
2166
2193
|
}
|
|
2167
2194
|
} finally {
|
|
2168
2195
|
this.running = false;
|
|
2169
2196
|
}
|
|
2170
2197
|
}
|
|
2171
2198
|
close() {
|
|
2199
|
+
this.stopping = true;
|
|
2172
2200
|
this.client.close();
|
|
2173
2201
|
}
|
|
2174
2202
|
}
|
|
@@ -622,6 +622,7 @@ class RedisStreamsQueue {
|
|
|
622
622
|
}
|
|
623
623
|
|
|
624
624
|
class RedisStreamsWorker {
|
|
625
|
+
redisUrl;
|
|
625
626
|
failedJobs;
|
|
626
627
|
timeoutSeconds;
|
|
627
628
|
queueKeys;
|
|
@@ -634,6 +635,7 @@ class RedisStreamsWorker {
|
|
|
634
635
|
stopping = false;
|
|
635
636
|
active;
|
|
636
637
|
constructor(redisUrl, failedJobs, timeoutSeconds = 5, queueKeys = defaultQueueKeys()) {
|
|
638
|
+
this.redisUrl = redisUrl;
|
|
637
639
|
this.failedJobs = failedJobs;
|
|
638
640
|
this.timeoutSeconds = timeoutSeconds;
|
|
639
641
|
this.queueKeys = queueKeys;
|
|
@@ -823,8 +825,21 @@ class RedisStreamsWorker {
|
|
|
823
825
|
async run() {
|
|
824
826
|
this.running = true;
|
|
825
827
|
try {
|
|
826
|
-
while (!this.stopping)
|
|
827
|
-
|
|
828
|
+
while (!this.stopping) {
|
|
829
|
+
try {
|
|
830
|
+
await this.processNext();
|
|
831
|
+
} catch (error) {
|
|
832
|
+
if (!(error && typeof error === "object" && ("code" in error) && error.code === "ERR_REDIS_CONNECTION_CLOSED"))
|
|
833
|
+
throw error;
|
|
834
|
+
this.client.close();
|
|
835
|
+
await Bun.sleep(250);
|
|
836
|
+
if (this.stopping)
|
|
837
|
+
return;
|
|
838
|
+
this.client = new RedisClient(this.redisUrl);
|
|
839
|
+
this.initialized = false;
|
|
840
|
+
this.cursors.clear();
|
|
841
|
+
}
|
|
842
|
+
}
|
|
828
843
|
} finally {
|
|
829
844
|
this.running = false;
|
|
830
845
|
}
|
|
@@ -1127,6 +1142,7 @@ class RedisQueue {
|
|
|
1127
1142
|
}
|
|
1128
1143
|
|
|
1129
1144
|
class QueueWorker {
|
|
1145
|
+
redisUrl;
|
|
1130
1146
|
failedJobs;
|
|
1131
1147
|
timeoutSeconds;
|
|
1132
1148
|
queueKeys;
|
|
@@ -1135,6 +1151,7 @@ class QueueWorker {
|
|
|
1135
1151
|
stopping = false;
|
|
1136
1152
|
client;
|
|
1137
1153
|
constructor(redisUrl, failedJobs, timeoutSeconds = 5, queueKeys = QUEUE_KEYS) {
|
|
1154
|
+
this.redisUrl = redisUrl;
|
|
1138
1155
|
this.failedJobs = failedJobs;
|
|
1139
1156
|
this.timeoutSeconds = timeoutSeconds;
|
|
1140
1157
|
this.queueKeys = queueKeys;
|
|
@@ -1215,13 +1232,24 @@ class QueueWorker {
|
|
|
1215
1232
|
this.running = true;
|
|
1216
1233
|
try {
|
|
1217
1234
|
while (!this.stopping) {
|
|
1218
|
-
|
|
1235
|
+
try {
|
|
1236
|
+
await this.processNext();
|
|
1237
|
+
} catch (error) {
|
|
1238
|
+
if (!(error && typeof error === "object" && ("code" in error) && error.code === "ERR_REDIS_CONNECTION_CLOSED"))
|
|
1239
|
+
throw error;
|
|
1240
|
+
this.client.close();
|
|
1241
|
+
await Bun.sleep(250);
|
|
1242
|
+
if (this.stopping)
|
|
1243
|
+
return;
|
|
1244
|
+
this.client = new RedisClient2(this.redisUrl);
|
|
1245
|
+
}
|
|
1219
1246
|
}
|
|
1220
1247
|
} finally {
|
|
1221
1248
|
this.running = false;
|
|
1222
1249
|
}
|
|
1223
1250
|
}
|
|
1224
1251
|
close() {
|
|
1252
|
+
this.stopping = true;
|
|
1225
1253
|
this.client.close();
|
|
1226
1254
|
}
|
|
1227
1255
|
}
|
package/dist/index.js
CHANGED
|
@@ -14821,6 +14821,7 @@ class RedisStreamsQueue {
|
|
|
14821
14821
|
}
|
|
14822
14822
|
|
|
14823
14823
|
class RedisStreamsWorker {
|
|
14824
|
+
redisUrl;
|
|
14824
14825
|
failedJobs;
|
|
14825
14826
|
timeoutSeconds;
|
|
14826
14827
|
queueKeys;
|
|
@@ -14833,6 +14834,7 @@ class RedisStreamsWorker {
|
|
|
14833
14834
|
stopping = false;
|
|
14834
14835
|
active;
|
|
14835
14836
|
constructor(redisUrl, failedJobs, timeoutSeconds = 5, queueKeys = defaultQueueKeys()) {
|
|
14837
|
+
this.redisUrl = redisUrl;
|
|
14836
14838
|
this.failedJobs = failedJobs;
|
|
14837
14839
|
this.timeoutSeconds = timeoutSeconds;
|
|
14838
14840
|
this.queueKeys = queueKeys;
|
|
@@ -15022,8 +15024,21 @@ class RedisStreamsWorker {
|
|
|
15022
15024
|
async run() {
|
|
15023
15025
|
this.running = true;
|
|
15024
15026
|
try {
|
|
15025
|
-
while (!this.stopping)
|
|
15026
|
-
|
|
15027
|
+
while (!this.stopping) {
|
|
15028
|
+
try {
|
|
15029
|
+
await this.processNext();
|
|
15030
|
+
} catch (error) {
|
|
15031
|
+
if (!(error && typeof error === "object" && ("code" in error) && error.code === "ERR_REDIS_CONNECTION_CLOSED"))
|
|
15032
|
+
throw error;
|
|
15033
|
+
this.client.close();
|
|
15034
|
+
await Bun.sleep(250);
|
|
15035
|
+
if (this.stopping)
|
|
15036
|
+
return;
|
|
15037
|
+
this.client = new RedisClient3(this.redisUrl);
|
|
15038
|
+
this.initialized = false;
|
|
15039
|
+
this.cursors.clear();
|
|
15040
|
+
}
|
|
15041
|
+
}
|
|
15027
15042
|
} finally {
|
|
15028
15043
|
this.running = false;
|
|
15029
15044
|
}
|
|
@@ -15249,6 +15264,7 @@ class RedisQueue {
|
|
|
15249
15264
|
}
|
|
15250
15265
|
|
|
15251
15266
|
class QueueWorker {
|
|
15267
|
+
redisUrl;
|
|
15252
15268
|
failedJobs;
|
|
15253
15269
|
timeoutSeconds;
|
|
15254
15270
|
queueKeys;
|
|
@@ -15257,6 +15273,7 @@ class QueueWorker {
|
|
|
15257
15273
|
stopping = false;
|
|
15258
15274
|
client;
|
|
15259
15275
|
constructor(redisUrl, failedJobs, timeoutSeconds = 5, queueKeys = QUEUE_KEYS) {
|
|
15276
|
+
this.redisUrl = redisUrl;
|
|
15260
15277
|
this.failedJobs = failedJobs;
|
|
15261
15278
|
this.timeoutSeconds = timeoutSeconds;
|
|
15262
15279
|
this.queueKeys = queueKeys;
|
|
@@ -15337,13 +15354,24 @@ class QueueWorker {
|
|
|
15337
15354
|
this.running = true;
|
|
15338
15355
|
try {
|
|
15339
15356
|
while (!this.stopping) {
|
|
15340
|
-
|
|
15357
|
+
try {
|
|
15358
|
+
await this.processNext();
|
|
15359
|
+
} catch (error) {
|
|
15360
|
+
if (!(error && typeof error === "object" && ("code" in error) && error.code === "ERR_REDIS_CONNECTION_CLOSED"))
|
|
15361
|
+
throw error;
|
|
15362
|
+
this.client.close();
|
|
15363
|
+
await Bun.sleep(250);
|
|
15364
|
+
if (this.stopping)
|
|
15365
|
+
return;
|
|
15366
|
+
this.client = new RedisClient4(this.redisUrl);
|
|
15367
|
+
}
|
|
15341
15368
|
}
|
|
15342
15369
|
} finally {
|
|
15343
15370
|
this.running = false;
|
|
15344
15371
|
}
|
|
15345
15372
|
}
|
|
15346
15373
|
close() {
|
|
15374
|
+
this.stopping = true;
|
|
15347
15375
|
this.client.close();
|
|
15348
15376
|
}
|
|
15349
15377
|
}
|