@ercworldio/blockchain-shared 1.0.0-dev.5 → 1.0.0-dev.7
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/build/chains/networks_dev.json +8 -8
- package/build/chains/networks_prod-bu.json +31 -5
- package/build/chains/networks_prod.json +239 -227
- package/build/chains/networks_stg-bu.json +6 -6
- package/build/chains/networks_stg-dz.json +5 -5
- package/build/interfaces/config.d.ts +5 -1
- package/build/interfaces/config.d.ts.map +1 -1
- package/build/services/AccountingService.d.ts +1 -1
- package/build/services/AccountingService.d.ts.map +1 -1
- package/build/services/AlchemyWebhookSignature.d.ts +3 -3
- package/build/services/AlchemyWebhookSignature.d.ts.map +1 -1
- package/build/services/AlchemyWebhookSignature.js +8 -8
- package/build/services/ClaimJobService.d.ts +1 -0
- package/build/services/ClaimJobService.d.ts.map +1 -1
- package/build/services/ClaimJobService.js +9 -0
- package/build/services/DepositAddressService.d.ts +1 -0
- package/build/services/DepositAddressService.d.ts.map +1 -1
- package/build/services/DepositAddressService.js +11 -0
- package/build/services/InvoiceQueue.d.ts +1 -1
- package/build/services/InvoiceQueue.d.ts.map +1 -1
- package/build/services/KeyVaultService.d.ts +1 -1
- package/build/services/KeyVaultService.d.ts.map +1 -1
- package/build/services/KeyVaultService.js +3 -30
- package/build/services/ProviderManager.d.ts.map +1 -1
- package/build/services/ProviderManager.js +6 -1
- package/build/services/QuicknodeWebhookSignature.d.ts +3 -3
- package/build/services/QuicknodeWebhookSignature.d.ts.map +1 -1
- package/build/services/QuicknodeWebhookSignature.js +8 -8
- package/build/services/Redis.d.ts +20 -9
- package/build/services/Redis.d.ts.map +1 -1
- package/build/services/Redis.js +246 -199
- package/build/services/RedisListQueue.d.ts.map +1 -1
- package/build/services/RedisListQueue.js +7 -1
- package/build/services/StorageService.js +2 -2
- package/build/services/SweepJobService.d.ts +1 -0
- package/build/services/SweepJobService.d.ts.map +1 -1
- package/build/services/SweepJobService.js +9 -0
- package/build/services/TimerManager.d.ts.map +1 -1
- package/build/services/TimerManager.js +9 -1
- package/build/services/WithdrawalManager.d.ts +1 -1
- package/build/services/WithdrawalManager.d.ts.map +1 -1
- package/build/services/WithdrawalManager.js +41 -37
- package/build/services/solana/escrow/services/EscrowAdminUtility.d.ts +1 -0
- package/build/services/solana/escrow/services/EscrowAdminUtility.d.ts.map +1 -1
- package/build/services/solana/escrow/services/EscrowAdminUtility.js +3 -1
- package/build/utils/AsyncRateLimiter.d.ts.map +1 -1
- package/build/utils/AsyncRateLimiter.js +3 -0
- package/build/utils/custodial.js +2 -2
- package/package.json +1 -1
package/build/services/Redis.js
CHANGED
|
@@ -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
|
-
|
|
22
|
-
this.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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.
|
|
58
|
-
this.
|
|
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
|
-
|
|
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
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
return this.
|
|
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(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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
|
-
//
|
|
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(
|
|
149
|
-
const db = (
|
|
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
|
-
|
|
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:
|
|
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 (
|
|
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 (
|
|
168
|
-
|
|
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
|
-
|
|
175
|
-
return key;
|
|
176
|
-
}
|
|
177
|
-
else {
|
|
178
|
-
return `${this.prefix}-${key}`;
|
|
179
|
-
}
|
|
250
|
+
return use_prefix ? `${this.prefix}-${key}` : key;
|
|
180
251
|
}
|
|
181
|
-
|
|
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.
|
|
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
|
-
|
|
261
|
+
_get(final_key) {
|
|
192
262
|
return __awaiter(this, void 0, void 0, function* () {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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
|
-
|
|
223
|
-
|
|
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
|
-
|
|
230
|
-
|
|
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
|
-
|
|
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,
|
|
303
|
+
set(_key, value, options) {
|
|
244
304
|
return __awaiter(this, void 0, void 0, function* () {
|
|
245
|
-
|
|
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
|
-
|
|
252
|
-
return yield this._delete(key);
|
|
310
|
+
return this._delete(this.get_key(_key));
|
|
253
311
|
});
|
|
254
312
|
}
|
|
255
|
-
set_object(_key,
|
|
313
|
+
set_object(_key, value, options) {
|
|
256
314
|
return __awaiter(this, void 0, void 0, function* () {
|
|
257
|
-
|
|
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
|
-
|
|
264
|
-
this.logger.info(`Redis: Getting object with key: ${key}
|
|
265
|
-
const
|
|
266
|
-
return
|
|
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
|
-
|
|
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(
|
|
290
|
-
|
|
291
|
-
|
|
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;
|
|
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
|
}
|
|
@@ -18,7 +18,7 @@ class StorageService {
|
|
|
18
18
|
constructor(config) {
|
|
19
19
|
this.fetchContainerContent = (containerClientName, fileName) => __awaiter(this, void 0, void 0, function* () {
|
|
20
20
|
try {
|
|
21
|
-
const vaultHandler = new KeyVaultService_1.default(this.config.config.
|
|
21
|
+
const vaultHandler = new KeyVaultService_1.default(this.config.config.keyVaultName);
|
|
22
22
|
if (!vaultHandler.client) {
|
|
23
23
|
vaultHandler.initializeKeyVaultService();
|
|
24
24
|
}
|
|
@@ -43,7 +43,7 @@ class StorageService {
|
|
|
43
43
|
// Function to update or create the content of a file in a given container
|
|
44
44
|
this.updateContainerContent = (containerName, fileName, content) => __awaiter(this, void 0, void 0, function* () {
|
|
45
45
|
try {
|
|
46
|
-
const vaultHandler = new KeyVaultService_1.default(this.config.config.
|
|
46
|
+
const vaultHandler = new KeyVaultService_1.default(this.config.config.keyVaultName);
|
|
47
47
|
if (!vaultHandler.client) {
|
|
48
48
|
vaultHandler.initializeKeyVaultService();
|
|
49
49
|
}
|
|
@@ -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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"}
|