@ercworldio/blockchain-shared 1.0.0-dev.4 → 1.0.0

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.
Files changed (40) hide show
  1. package/build/chains/networks_dev.json +9 -55
  2. package/build/chains/networks_prod-bu.json +26 -0
  3. package/build/chains/networks_prod.json +233 -221
  4. package/build/services/AccountingService.d.ts +1 -1
  5. package/build/services/AccountingService.d.ts.map +1 -1
  6. package/build/services/ChainManager.d.ts.map +1 -1
  7. package/build/services/ChainManager.js +10 -8
  8. package/build/services/ClaimJobService.d.ts +1 -0
  9. package/build/services/ClaimJobService.d.ts.map +1 -1
  10. package/build/services/ClaimJobService.js +9 -0
  11. package/build/services/DepositAddressService.d.ts +1 -0
  12. package/build/services/DepositAddressService.d.ts.map +1 -1
  13. package/build/services/DepositAddressService.js +11 -0
  14. package/build/services/InvoiceQueue.d.ts +1 -1
  15. package/build/services/InvoiceQueue.d.ts.map +1 -1
  16. package/build/services/ProviderManager.d.ts.map +1 -1
  17. package/build/services/ProviderManager.js +6 -1
  18. package/build/services/Redis.d.ts +20 -9
  19. package/build/services/Redis.d.ts.map +1 -1
  20. package/build/services/Redis.js +246 -199
  21. package/build/services/RedisListQueue.d.ts.map +1 -1
  22. package/build/services/RedisListQueue.js +7 -1
  23. package/build/services/SweepJobService.d.ts +1 -0
  24. package/build/services/SweepJobService.d.ts.map +1 -1
  25. package/build/services/SweepJobService.js +9 -0
  26. package/build/services/TimerManager.d.ts.map +1 -1
  27. package/build/services/TimerManager.js +9 -1
  28. package/build/services/WithdrawalManager.d.ts +1 -1
  29. package/build/services/WithdrawalManager.d.ts.map +1 -1
  30. package/build/services/WithdrawalManager.js +41 -37
  31. package/build/services/solana/escrow/SolanaEscrowAdmin.d.ts +1 -1
  32. package/build/services/solana/escrow/SolanaEscrowAdmin.d.ts.map +1 -1
  33. package/build/services/solana/escrow/services/EscrowAdminUtility.d.ts +2 -1
  34. package/build/services/solana/escrow/services/EscrowAdminUtility.d.ts.map +1 -1
  35. package/build/services/solana/escrow/services/EscrowAdminUtility.js +4 -2
  36. package/build/services/utils/alchemy.js +1 -1
  37. package/build/utils/AsyncRateLimiter.d.ts.map +1 -1
  38. package/build/utils/AsyncRateLimiter.js +3 -0
  39. package/build/utils/custodial.js +2 -2
  40. package/package.json +2 -2
@@ -18,260 +18,319 @@ const ElasticSearch_1 = __importDefault(require("./ElasticSearch"));
18
18
  const Logger_1 = require("../utils/Logger");
19
19
  class Redis {
20
20
  constructor(config) {
21
- this.initializingPromise = null;
22
- this.create_redis_client = () => {
23
- if (this.config.serverConfig.environment === 'local') {
24
- this.client = (0, redis_1.createClient)();
25
- }
26
- else {
27
- const parsed_string = (0, Parsing_1.parseRedisUrl)(this.config.config.redisConnectionstring);
28
- let url = `rediss://${parsed_string.host}:${parsed_string.port}`;
29
- this.client = (0, redis_1.createClient)({
30
- pingInterval: 10000,
31
- url,
32
- password: parsed_string.password,
33
- socket: {
34
- host: parsed_string.host,
35
- port: parsed_string.port,
36
- tls: true,
37
- reconnectStrategy: (retries) => {
38
- if (retries > 20)
39
- return new Error('Max retries reached');
40
- return Math.min(retries * 200, 5000);
41
- }
42
- // reconnectStrategy: (retries) => {
43
- // if (retries < 10) {
44
- // return 200;
45
- // }
46
- // // this.reinitialize();
47
- // return false;
48
- // }
49
- }
50
- });
51
- }
52
- return this.client;
53
- };
21
+ // Prevent concurrent connect / subscriber-connect attempts
22
+ this.connectPromise = null;
23
+ this.subscriberConnectPromise = null;
24
+ // Stored so the subscription can be restored after subscriber recreation
25
+ this.expiryPattern = null;
26
+ this.expiryHandler = null;
54
27
  this.config = config;
55
- this.initialized = false;
56
28
  this.prefix = `${config.serverConfig.projectName}-${config.serverConfig.environment}`;
57
- this.client = this.create_redis_client();
58
- this.logger = (0, Logger_1.createLogger)(`Redis`, this.config.pipelineConfig.azureAppName);
29
+ this.logger = (0, Logger_1.createLogger)("Redis", config.pipelineConfig.azureAppName);
30
+ this.client = this.createClient();
59
31
  }
60
32
  static getInstance(config) {
61
33
  if (!this.instance) {
62
34
  this.instance = new Redis(config);
63
35
  }
64
- if (!this.instance.client.isOpen) {
65
- this.instance.initialize().then(() => this.instance.logger.info(`Initialized redis`)).catch((err) => this.instance.logger.info(`Error initializing Redis client: `, err));
66
- }
67
36
  return this.instance;
68
37
  }
69
- reinitialize() {
38
+ // -------------------------------------------------------------------------
39
+ // Client / subscriber creation
40
+ // -------------------------------------------------------------------------
41
+ createClient() {
42
+ let client;
43
+ if (this.config.serverConfig.environment === "local") {
44
+ client = (0, redis_1.createClient)();
45
+ }
46
+ else {
47
+ const p = (0, Parsing_1.parseRedisUrl)(this.config.config.redisConnectionstring);
48
+ client = (0, redis_1.createClient)({
49
+ pingInterval: 10000,
50
+ url: `rediss://${p.host}:${p.port}`,
51
+ password: p.password,
52
+ socket: {
53
+ host: p.host,
54
+ port: p.port,
55
+ tls: true,
56
+ connectTimeout: 10000,
57
+ reconnectStrategy: (retries) => {
58
+ if (retries > 20)
59
+ return new Error("Redis: max reconnect retries reached");
60
+ const delay = Math.min(retries * 200, 5000);
61
+ this.logger.warn(`Redis: reconnect attempt ${retries}, retrying in ${delay}ms`);
62
+ return delay;
63
+ },
64
+ },
65
+ });
66
+ }
67
+ this.attachMainClientListeners(client);
68
+ return client;
69
+ }
70
+ attachMainClientListeners(client) {
71
+ client.on("error", (err) => {
72
+ var _a;
73
+ this.logger.warn("Redis: client error", { data: { error: err === null || err === void 0 ? void 0 : err.message } });
74
+ ElasticSearch_1.default.getInstance(this.config).index_log("Redis", "client.error", "Error", "Redis client error", { message: (_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : "Unexpected error" });
75
+ });
76
+ client.on("reconnecting", () => this.logger.warn("Redis: client reconnecting"));
77
+ client.on("connect", () => this.logger.info("Redis: client connected"));
78
+ client.on("ready", () => {
79
+ this.logger.info("Redis: client ready");
80
+ // Enable TCP keep-alive on the underlying socket
81
+ const stream = client.socket;
82
+ if (stream === null || stream === void 0 ? void 0 : stream.setKeepAlive)
83
+ stream.setKeepAlive(true, 10000);
84
+ });
85
+ client.on("end", () => {
86
+ // Fires when reconnectStrategy gave up (or explicit quit — not used here).
87
+ // Create a completely fresh client; the old one is dead.
88
+ this.logger.warn("Redis: client ended — reconnect strategy exhausted, creating fresh client");
89
+ if (this.connectPromise)
90
+ return; // already recovering
91
+ this.client = this.createClient();
92
+ this.connectPromise = this.connectClient(this.client)
93
+ .catch((err) => this.logger.error("Redis: fresh client connect failed", { data: { error: err } }))
94
+ .finally(() => { this.connectPromise = null; });
95
+ });
96
+ }
97
+ attachSubscriberListeners(subscriber) {
98
+ subscriber.on("error", (err) => this.logger.warn("Redis: subscriber error", { data: { error: err === null || err === void 0 ? void 0 : err.message } }));
99
+ subscriber.on("reconnecting", () => this.logger.warn("Redis: subscriber reconnecting"));
100
+ subscriber.on("connect", () => this.logger.info("Redis: subscriber connected"));
101
+ subscriber.on("ready", () => this.logger.info("Redis: subscriber ready"));
102
+ subscriber.on("end", () => {
103
+ // Subscriber's reconnect strategy gave up — rebuild from scratch and restore subscription.
104
+ this.logger.warn("Redis: subscriber ended — recreating");
105
+ this.recreateSubscriber();
106
+ });
107
+ }
108
+ // -------------------------------------------------------------------------
109
+ // Connection management
110
+ // -------------------------------------------------------------------------
111
+ connectClient(client) {
70
112
  return __awaiter(this, void 0, void 0, function* () {
71
- try {
72
- this.logger.info("Redis: Reinitializing Redis...");
73
- this.client = this.create_redis_client();
74
- this.initialized = false;
75
- yield this.initialize();
76
- }
77
- catch (err) {
78
- this.logger.warn("Reinit failed:", { data: { error: err } });
113
+ this.logger.info("Redis: connecting main client");
114
+ yield client.connect();
115
+ if (this.config.serverConfig.environment === "local") {
116
+ yield client.configSet("notify-keyspace-events", "Exg");
79
117
  }
118
+ this.logger.info("Redis: main client ready");
119
+ });
120
+ }
121
+ connectSubscriber() {
122
+ return __awaiter(this, void 0, void 0, function* () {
123
+ var _a;
124
+ if ((_a = this.subscriber) === null || _a === void 0 ? void 0 : _a.isOpen)
125
+ return;
126
+ if (this.subscriberConnectPromise)
127
+ return this.subscriberConnectPromise;
128
+ this.subscriberConnectPromise = this._doConnectSubscriber()
129
+ .finally(() => { this.subscriberConnectPromise = null; });
130
+ return this.subscriberConnectPromise;
131
+ });
132
+ }
133
+ _doConnectSubscriber() {
134
+ return __awaiter(this, void 0, void 0, function* () {
135
+ this.logger.info("Redis: connecting subscriber");
136
+ // duplicate() copies all connection options, no re-auth needed
137
+ this.subscriber = this.client.duplicate();
138
+ this.attachSubscriberListeners(this.subscriber);
139
+ yield Promise.race([
140
+ this.subscriber.connect(),
141
+ new Promise((_, reject) => setTimeout(() => reject(new Error("Subscriber connect timed out after 10s")), 10000)),
142
+ ]);
143
+ this.logger.info("Redis: subscriber ready");
80
144
  });
81
145
  }
146
+ /**
147
+ * Called when the subscriber's reconnectStrategy fails
148
+ * Removes dead subscriber and creates a new one.
149
+ * Restores expiry subscription using the stored pattern/handler
150
+ */
151
+ recreateSubscriber() {
152
+ this.subscriber = undefined;
153
+ this.subscriberConnectPromise = null;
154
+ if (!this.client.isOpen) {
155
+ // Main client is also down, skip
156
+ // When the main client recovers, the next initialize() call will
157
+ // create a fresh subscriber and resubscribe
158
+ this.logger.warn("Redis: main client not ready, deferring subscriber recreation");
159
+ return;
160
+ }
161
+ this.connectSubscriber()
162
+ .then(() => __awaiter(this, void 0, void 0, function* () {
163
+ if (this.expiryPattern && this.expiryHandler && this.subscriber) {
164
+ yield this.subscriber.pSubscribe(this.expiryPattern, this.expiryHandler);
165
+ this.logger.info("Redis: subscriber recreated and expiry subscription restored");
166
+ }
167
+ }))
168
+ .catch((err) => this.logger.error("Redis: subscriber recreation failed", { data: { error: err } }));
169
+ }
170
+ // -------------------------------------------------------------------------
171
+ // Public initializer — safe to call multiple times / concurrently
172
+ // -------------------------------------------------------------------------
82
173
  initialize() {
83
174
  return __awaiter(this, void 0, void 0, function* () {
175
+ var _a;
84
176
  if (this.client.isOpen) {
85
- this.initialized = true;
177
+ // Main client is up — ensure subscriber is also up
178
+ if (!((_a = this.subscriber) === null || _a === void 0 ? void 0 : _a.isOpen)) {
179
+ yield this.connectSubscriber().catch((err) => this.logger.warn("Redis: subscriber connect failed during initialize", { data: { error: err } }));
180
+ }
86
181
  return;
87
182
  }
88
- if (this.initializingPromise)
89
- return this.initializingPromise;
90
- this.initializingPromise = this._doInitialize().finally(() => {
91
- this.initializingPromise = null;
92
- });
93
- return this.initializingPromise;
183
+ // Deduplicate concurrent callers
184
+ if (this.connectPromise)
185
+ return this.connectPromise;
186
+ this.connectPromise = this._doInitialize()
187
+ .finally(() => { this.connectPromise = null; });
188
+ return this.connectPromise;
94
189
  });
95
190
  }
96
191
  _doInitialize() {
97
192
  return __awaiter(this, void 0, void 0, function* () {
98
- this.logger.info(`Redis: Initializing redis....`);
99
- try {
100
- this.client.on('error', (err) => __awaiter(this, void 0, void 0, function* () { return yield this.handle_redis_error(err); }));
101
- this.client.on('reconnecting', () => this.handle_redis_action("reconnecting"));
102
- this.client.on('connect', () => this.handle_redis_action("connect"));
103
- this.client.on('end', () => __awaiter(this, void 0, void 0, function* () { return yield this.handle_redis_action("end"); }));
104
- this.client.on('ping', () => {
105
- console.log('Redis PING sent');
106
- });
107
- // Enable TCP keep-alive on the underlying socket after connecting
108
- this.client.on('ready', () => {
109
- var _a, _b;
110
- this.logger;
111
- const socket = (_b = (_a = this.client) === null || _a === void 0 ? void 0 : _a.options) === null || _b === void 0 ? void 0 : _b.socket;
112
- // Access the raw net.Socket and enable keep-alive
113
- const stream = this.client.socket;
114
- if (stream === null || stream === void 0 ? void 0 : stream.setKeepAlive) {
115
- stream.setKeepAlive(true, 10000);
116
- this.logger.info(``);
117
- }
118
- });
119
- // Enable keyspace notifications for expired events
120
- try {
121
- yield this.client.connect();
122
- // Subscribe to events on local redis
123
- if (this.config.serverConfig.environment === "local") {
124
- yield this.client.configSet('notify-keyspace-events', 'Exg');
125
- }
126
- this.initialized = true;
127
- // // Create a dedicated subscriber connection for notifications
128
- this.subscriber = this.client.duplicate();
129
- // this.subscriber.on('error', async (err) => await this.handle_redis_error(err));
130
- yield this.subscriber.connect();
131
- this.initialized = true;
132
- }
133
- catch (e) {
134
- this.logger.warn('Redis: Redis init Error:', { data: { error: e } });
135
- }
136
- this.logger.info(`Redis: Initialized redis`);
137
- }
138
- catch (error) {
139
- this.logger.error(`Redis: Error initializoing redis client`, { data: error });
140
- }
193
+ this.logger.info("Redis: initializing");
194
+ yield this.connectClient(this.client);
195
+ // Subscriber failure is non-fatal for initialization commands still work.
196
+ // The subscriber will be retried the first time subscribeToExpiry is called.
197
+ yield this.connectSubscriber().catch((err) => this.logger.warn("Redis: subscriber connect failed during init — will retry on use", { data: { error: err } }));
198
+ this.logger.info("Redis: initialization complete");
141
199
  });
142
200
  }
143
- // Subscribe to key expiry notifications
201
+ // -------------------------------------------------------------------------
202
+ // Expiry subscription
203
+ // -------------------------------------------------------------------------
144
204
  subscribeToExpiry(onExpire) {
145
205
  return __awaiter(this, void 0, void 0, function* () {
146
- var _a, _b;
206
+ var _a, _b, _c;
207
+ if (!((_a = this.subscriber) === null || _a === void 0 ? void 0 : _a.isOpen))
208
+ yield this.connectSubscriber();
147
209
  if (!this.subscriber)
148
- throw new Error('Redis subscriber not initialized');
149
- const db = (_b = (_a = this.client.options) === null || _a === void 0 ? void 0 : _a.database) !== null && _b !== void 0 ? _b : 0;
210
+ throw new Error("Redis: subscriber not available");
211
+ const db = (_c = (_b = this.client.options) === null || _b === void 0 ? void 0 : _b.database) !== null && _c !== void 0 ? _c : 0;
150
212
  const pattern = `__keyevent@${db}__:expired`;
151
- yield this.subscriber.pSubscribe(pattern, (expiredKey) => __awaiter(this, void 0, void 0, function* () {
213
+ const handler = (expiredKey) => __awaiter(this, void 0, void 0, function* () {
152
214
  try {
153
- // Get the value before it expires (if possible) or use the key
154
215
  const pref = `${this.prefix}-`;
155
216
  const normalizedKey = expiredKey.startsWith(pref) ? expiredKey.slice(pref.length) : expiredKey;
156
- this.logger.info(`Redis: Expired key: ${normalizedKey} `);
157
- // Try to get the value from the expired key (might not work for expired keys)
217
+ this.logger.info(`Redis: key expired: ${normalizedKey}`);
158
218
  let value = null;
159
219
  try {
160
220
  value = yield this.get_object(expiredKey);
161
221
  }
162
- catch (e) {
163
- // Key already expired, use the key itself
164
- }
222
+ catch ( /* already gone */_a) { /* already gone */ }
165
223
  onExpire(normalizedKey, value);
166
224
  }
167
- catch (e) {
168
- yield this.handle_redis_error(e);
225
+ catch (err) {
226
+ this.logger.error("Redis: expiry handler error", { data: { error: err } });
169
227
  }
170
- }));
228
+ });
229
+ // Persist so recreateSubscriber can restore the subscription automatically.
230
+ this.expiryPattern = pattern;
231
+ this.expiryHandler = handler;
232
+ try {
233
+ yield Promise.race([
234
+ this.subscriber.pSubscribe(pattern, handler),
235
+ new Promise((_, reject) => setTimeout(() => reject(new Error("pSubscribe timed out after 10s")), 10000)),
236
+ ]);
237
+ this.logger.info(`Redis: subscribed to expiry pattern ${pattern}`);
238
+ }
239
+ catch (err) {
240
+ // Non-fatal: handler is stored — subscription is restored automatically
241
+ // when the subscriber reconnects (see recreateSubscriber / 'end' event).
242
+ this.logger.warn("Redis: pSubscribe timed out — will retry when subscriber reconnects", { data: { error: err } });
243
+ }
171
244
  });
172
245
  }
246
+ // -------------------------------------------------------------------------
247
+ // Key helpers
248
+ // -------------------------------------------------------------------------
173
249
  get_key(key, use_prefix = true) {
174
- if (!use_prefix) {
175
- return key;
176
- }
177
- else {
178
- return `${this.prefix}-${key}`;
179
- }
250
+ return use_prefix ? `${this.prefix}-${key}` : key;
180
251
  }
181
- _get(final_key) {
252
+ // -------------------------------------------------------------------------
253
+ // Core read / write / delete — all guarded by ensureConnected + withTimeout
254
+ // -------------------------------------------------------------------------
255
+ ensureConnected() {
182
256
  return __awaiter(this, void 0, void 0, function* () {
183
- if (!this.initialized)
257
+ if (!this.client.isOpen)
184
258
  yield this.initialize();
185
- const value = yield this.withTimeout(() => this.client.get(final_key));
186
- if (!value)
187
- return null;
188
- return value;
189
259
  });
190
260
  }
191
- _set(final_key, _value, options) {
261
+ _get(final_key) {
192
262
  return __awaiter(this, void 0, void 0, function* () {
193
- if (!this.initialized)
194
- yield this.initialize();
195
- if (options) {
196
- const expiry_timestamp = options.expires_at;
197
- const ttl = options.ttl;
198
- if (!expiry_timestamp)
199
- throw new Error("Expiry timestamp is required");
200
- if (!ttl)
201
- throw new Error("TTL for key required");
202
- let opt = {
203
- expiration: {
204
- type: "EXAT",
205
- value: expiry_timestamp
206
- },
207
- };
208
- let now_s = Math.floor(new Date().getTime() / 1000);
209
- if (options.publish) {
210
- const publishName = options.publish.name;
211
- return yield this.withTimeout(() => {
212
- const multi = this.client.multi();
213
- multi.set(final_key, _value, ttl ? { EX: ttl } : undefined);
214
- multi.publish(publishName, _value);
215
- return multi.exec();
216
- });
217
- }
218
- else {
219
- return yield this.withTimeout(() => this.client.set(final_key, _value, { EX: ttl }));
220
- }
263
+ yield this.ensureConnected();
264
+ return this.withTimeout(() => this.client.get(final_key));
265
+ });
266
+ }
267
+ _set(final_key, value, options) {
268
+ return __awaiter(this, void 0, void 0, function* () {
269
+ yield this.ensureConnected();
270
+ if (!options) {
271
+ return this.withTimeout(() => this.client.set(final_key, value));
221
272
  }
222
- else {
223
- return yield this.withTimeout(() => this.client.set(final_key, _value));
273
+ const { expires_at, ttl, publish } = options;
274
+ if (!expires_at)
275
+ throw new Error("expires_at is required");
276
+ if (!ttl)
277
+ throw new Error("ttl is required");
278
+ if (publish) {
279
+ return this.withTimeout(() => {
280
+ const multi = this.client.multi();
281
+ multi.set(final_key, value, { EX: ttl });
282
+ multi.publish(publish.name, value);
283
+ return multi.exec();
284
+ });
224
285
  }
286
+ return this.withTimeout(() => this.client.set(final_key, value, { EX: ttl }));
225
287
  });
226
288
  }
227
289
  _delete(final_key) {
228
290
  return __awaiter(this, void 0, void 0, function* () {
229
- if (!this.initialized)
230
- yield this.initialize();
231
- return yield this.withTimeout(() => this.client.del(final_key));
291
+ yield this.ensureConnected();
292
+ return this.withTimeout(() => this.client.del(final_key));
232
293
  });
233
294
  }
295
+ // -------------------------------------------------------------------------
296
+ // Public API (interface preserved)
297
+ // -------------------------------------------------------------------------
234
298
  get(_key) {
235
299
  return __awaiter(this, void 0, void 0, function* () {
236
- let key = this.get_key(_key);
237
- const value = yield this._get(key);
238
- if (!value)
239
- return null;
240
- return value;
300
+ return this._get(this.get_key(_key));
241
301
  });
242
302
  }
243
- set(_key, _value, options) {
303
+ set(_key, value, options) {
244
304
  return __awaiter(this, void 0, void 0, function* () {
245
- let key = this.get_key(_key);
246
- return yield this._set(key, _value, options);
305
+ return this._set(this.get_key(_key), value, options);
247
306
  });
248
307
  }
249
308
  delete(_key) {
250
309
  return __awaiter(this, void 0, void 0, function* () {
251
- let key = this.get_key(_key);
252
- return yield this._delete(key);
310
+ return this._delete(this.get_key(_key));
253
311
  });
254
312
  }
255
- set_object(_key, _value, options) {
313
+ set_object(_key, value, options) {
256
314
  return __awaiter(this, void 0, void 0, function* () {
257
- let key = this.get_key(_key);
258
- return this._set(key, JSON.stringify(_value), options);
315
+ return this._set(this.get_key(_key), JSON.stringify(value), options);
259
316
  });
260
317
  }
261
318
  get_object(_key_1) {
262
319
  return __awaiter(this, arguments, void 0, function* (_key, use_prefix = true) {
263
- let key = this.get_key(_key, use_prefix);
264
- this.logger.info(`Redis: Getting object with key: ${key} `);
265
- const value = yield this._get(key);
266
- return value ? JSON.parse(value) : null;
320
+ const key = this.get_key(_key, use_prefix);
321
+ this.logger.info(`Redis: Getting object with key: ${key}`);
322
+ const raw = yield this._get(key);
323
+ return raw ? JSON.parse(raw) : null;
267
324
  });
268
325
  }
269
326
  delete_object(_key) {
270
327
  return __awaiter(this, void 0, void 0, function* () {
271
- let key = this.get_key(_key);
272
- return yield this._delete(key);
328
+ return this._delete(this.get_key(_key));
273
329
  });
274
330
  }
331
+ // -------------------------------------------------------------------------
332
+ // Command execution with timeout + single retry on dead connection
333
+ // -------------------------------------------------------------------------
275
334
  withTimeout(fn_1) {
276
335
  return __awaiter(this, arguments, void 0, function* (fn, ms = 5000, retry = true) {
277
336
  let timedOut = false;
@@ -286,32 +345,20 @@ class Redis {
286
345
  }
287
346
  catch (err) {
288
347
  if (timedOut && retry) {
289
- this.logger.warn(`Redis: command timed out, reinitializing and retrying once`);
290
- yield this.reinitialize();
291
- return this.withTimeout(fn, ms, false); // retry once on fresh connection, no further retry
348
+ this.logger.warn("Redis: command timed out attempting recovery");
349
+ if (!this.client.isOpen) {
350
+ // Connection is dead create a fresh client before retrying.
351
+ // This also covers the case where the 'end' event hasn't fired yet.
352
+ this.logger.warn("Redis: client closed, creating fresh client before retry");
353
+ this.client = this.createClient();
354
+ yield this.connectClient(this.client);
355
+ }
356
+ // fn() references this.client via arrow closure — picks up the new client.
357
+ return this.withTimeout(fn, ms, false);
292
358
  }
293
359
  throw err;
294
360
  }
295
361
  });
296
362
  }
297
- handle_redis_error(error) {
298
- return __awaiter(this, void 0, void 0, function* () {
299
- this.logger.info(`Redis: Redis Client Error: `, { data: { error } });
300
- const error_data = { message: (error === null || error === void 0 ? void 0 : error.message) ? error.message : "Unexpected error occured" };
301
- ElasticSearch_1.default.getInstance(this.config).index_log("Redis", this.handle_redis_error.name, "Error", "Redis Client Error", error_data);
302
- });
303
- }
304
- handle_redis_action(type) {
305
- return __awaiter(this, void 0, void 0, function* () {
306
- let message = "Redis Client Connected";
307
- if (type === "reconnecting")
308
- message = "Redis Client Reconnecting";
309
- else if (type === "end") {
310
- message = "Redis Client Connection Ended";
311
- yield this.reinitialize();
312
- }
313
- this.logger.info(`Redis: Redis client action: ${message} type: ${type}`);
314
- });
315
- }
316
363
  }
317
364
  exports.default = Redis;
@@ -1 +1 @@
1
- {"version":3,"file":"RedisListQueue.d.ts","sourceRoot":"","sources":["../../src/services/RedisListQueue.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAG/C,cAAM,cAAc;IAChB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM;IAOnC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtB,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;IAQlB,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE;IAiBzB,WAAW,CAAC,CAAC,EAAE,cAAc,SAAI,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAWrD,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,SAAI,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAgB3D,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;CAGlC;AAED,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"RedisListQueue.d.ts","sourceRoot":"","sources":["../../src/services/RedisListQueue.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAG/C,cAAM,cAAc;IAChB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM;IAOnC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAMtB,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;IASlB,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE;IAkBzB,WAAW,CAAC,CAAC,EAAE,cAAc,SAAI,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAYrD,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,SAAI,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAiB3D,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;CAIlC;AAED,eAAe,cAAc,CAAC"}
@@ -23,12 +23,14 @@ class RedisListQueue {
23
23
  // Clear the queue completely
24
24
  clear() {
25
25
  return __awaiter(this, void 0, void 0, function* () {
26
+ yield this.redis.initialize();
26
27
  yield this.redis.client.del(this.key);
27
28
  });
28
29
  }
29
- // Push single message
30
+ // Push single message
30
31
  push(message) {
31
32
  return __awaiter(this, void 0, void 0, function* () {
33
+ yield this.redis.initialize();
32
34
  yield this.redis.client.rPush(this.key, JSON.stringify(message));
33
35
  });
34
36
  }
@@ -37,6 +39,7 @@ class RedisListQueue {
37
39
  return __awaiter(this, void 0, void 0, function* () {
38
40
  if (!messages.length)
39
41
  return;
42
+ yield this.redis.initialize();
40
43
  const multi = this.redis.client.multi();
41
44
  for (const m of messages) {
42
45
  multi.rPush(this.key, JSON.stringify(m));
@@ -49,6 +52,7 @@ class RedisListQueue {
49
52
  // Blocking pop (consumer side)
50
53
  popBlocking() {
51
54
  return __awaiter(this, arguments, void 0, function* (timeoutSeconds = 0) {
55
+ yield this.redis.initialize();
52
56
  const result = yield this.redis.client.blPop(this.key, timeoutSeconds);
53
57
  if (!result)
54
58
  return null;
@@ -58,6 +62,7 @@ class RedisListQueue {
58
62
  // Blocking pop many
59
63
  popMany(count_1) {
60
64
  return __awaiter(this, arguments, void 0, function* (count, timeoutSeconds = 0) {
65
+ yield this.redis.initialize();
61
66
  const results = [];
62
67
  const first = yield this.redis.client.blPop(this.key, timeoutSeconds);
63
68
  if (!first)
@@ -74,6 +79,7 @@ class RedisListQueue {
74
79
  }
75
80
  length() {
76
81
  return __awaiter(this, void 0, void 0, function* () {
82
+ yield this.redis.initialize();
77
83
  return yield this.redis.client.lLen(this.key);
78
84
  });
79
85
  }
@@ -46,6 +46,7 @@ WHERE job_status IN ('pending', 'queued');
46
46
  batch_update_failed_jobs: (request_ids: number[], new_status: SweepJobStatus, error_message?: string, retryable?: boolean) => Promise<void>;
47
47
  batch_update_failed_jobs_with_error: (jobs: SweepJob[], retryable: boolean) => Promise<void>;
48
48
  batch_update_confirming: (jobs: SweepResult[], expected_status: SweepJobStatus) => Promise<void>;
49
+ reset_retry_count: (job_ids: number[]) => Promise<void>;
49
50
  find_confirming_jobs_with_tx_hash(blockchain: BlockchainType, limit: number, lock_owner: string, lock_minutes?: number): Promise<SweepJob[]>;
50
51
  }
51
52
  export default SweepJobService;
@@ -1 +1 @@
1
- {"version":3,"file":"SweepJobService.d.ts","sourceRoot":"","sources":["../../src/services/SweepJobService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SweepJobService.d.ts","sourceRoot":"","sources":["../../src/services/SweepJobService.ts"],"names":[],"mappings":"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"}
@@ -269,6 +269,15 @@ class SweepJobService {
269
269
  AND sj.tx_hash IS NULL;
270
270
  `, [ids, tx_hashes, expected_status]);
271
271
  });
272
+ this.reset_retry_count = (job_ids) => __awaiter(this, void 0, void 0, function* () {
273
+ const repo = this.getRepo();
274
+ const parsed_ids = job_ids.map(id => Number(id));
275
+ yield repo.query(`
276
+ UPDATE usersmanagement.sweep_jobs
277
+ SET retry_count = 0, updated_at = now()
278
+ WHERE id = ANY($1)
279
+ `, [parsed_ids]);
280
+ });
272
281
  this.dbPool = dbPool;
273
282
  this.config = config;
274
283
  this.logger = (0, Logger_1.createLogger)(`SweepJobService`, config.pipelineConfig.azureAppName);
@@ -1 +1 @@
1
- {"version":3,"file":"TimerManager.d.ts","sourceRoot":"","sources":["../../src/services/TimerManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAE5D,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,KAAK,MAAM,SAAS,CAAC;AAE5B,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAoBvD,cAAM,YAAY;IACd,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC;IAC9B,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,0BAA0B,CAAS;IAC3C,OAAO,CAAC,+BAA+B,CAAS;IACzC,KAAK,EAAE,KAAK,CAAC;IACpB,OAAO,CAAC,WAAW,CAAU;IAC7B,OAAO,CAAC,gBAAgB,CAAc;IACtC,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,+BAA+B,CAAkB;IACzD,OAAO,CAAC,MAAM,CAAS;gBACX,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,MAAM;IAcpE,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa;IAQ5C,UAAU;YAOT,iBAAiB;IA2BxB,0BAA0B,GAAU,UAAU,MAAM,EAAE,QAAQ,MAAM,EAAE,YAAY,cAAc,EAAE,SAAS,MAAM,EAAE,YAAY,CAAC,GAAG,EAAE,yBAAyB,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,mBAkBrN;IAEM,cAAc,GAAU,cAAc,yBAAyB,EAAE,SAAS,MAAM,EAAE,QAAQ,OAAO,mBA6BvG;IAED,OAAO,CAAC,UAAU;IAiBlB,OAAO,CAAC,WAAW;IAIZ,iBAAiB,IAAI;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,cAAc,CAAC;QAAC,SAAS,EAAE,IAAI,CAAA;KAAE,EAAE;IAQhF,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc;IAOvD,oBAAoB,CAC7B,MAAM,EAAE,OAAO,EACf,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,yBAAyB,EACvC,UAAU,GAAE,MAAW,GACxB,OAAO,CAAC,OAAO,CAAC;YAUL,sBAAsB;IAYvB,YAAY,CACrB,MAAM,EAAE,OAAO,EACf,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,yBAAyB,EACvC,UAAU,GAAE,MAAW,GACxB,OAAO,CAAC,OAAO,CAAC;YAeL,aAAa;IAwBd,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IAM1E,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IAUzE,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;CAM9F;AAED,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"TimerManager.d.ts","sourceRoot":"","sources":["../../src/services/TimerManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAE5D,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,KAAK,MAAM,SAAS,CAAC;AAE5B,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAoBvD,cAAM,YAAY;IACd,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC;IAC9B,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,0BAA0B,CAAS;IAC3C,OAAO,CAAC,+BAA+B,CAAS;IACzC,KAAK,EAAE,KAAK,CAAC;IACpB,OAAO,CAAC,WAAW,CAAU;IAC7B,OAAO,CAAC,gBAAgB,CAAc;IACtC,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,+BAA+B,CAAkB;IACzD,OAAO,CAAC,MAAM,CAAS;gBACX,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,MAAM;IAcpE,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa;IAQ5C,UAAU;YAOT,iBAAiB;IA2BxB,0BAA0B,GAAU,UAAU,MAAM,EAAE,QAAQ,MAAM,EAAE,YAAY,cAAc,EAAE,SAAS,MAAM,EAAE,YAAY,CAAC,GAAG,EAAE,yBAAyB,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,mBAkBrN;IAEM,cAAc,GAAU,cAAc,yBAAyB,EAAE,SAAS,MAAM,EAAE,QAAQ,OAAO,mBA6BvG;IAED,OAAO,CAAC,UAAU;IAiBlB,OAAO,CAAC,WAAW;IAIZ,iBAAiB,IAAI;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,cAAc,CAAC;QAAC,SAAS,EAAE,IAAI,CAAA;KAAE,EAAE;IAQhF,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc;IAUvD,oBAAoB,CAC7B,MAAM,EAAE,OAAO,EACf,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,yBAAyB,EACvC,UAAU,GAAE,MAAW,GACxB,OAAO,CAAC,OAAO,CAAC;YAeL,sBAAsB;IAYvB,YAAY,CACrB,MAAM,EAAE,OAAO,EACf,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,yBAAyB,EACvC,UAAU,GAAE,MAAW,GACxB,OAAO,CAAC,OAAO,CAAC;YAmBL,aAAa;IAwBd,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IAM1E,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IAUzE,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;CAM9F;AAED,eAAe,YAAY,CAAC"}