@realvare/based 2.5.2 → 2.5.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.
@@ -48,6 +48,47 @@ const makeSocket = (config) => {
48
48
  let keepAliveReq;
49
49
  let qrTimer;
50
50
  let closed = false;
51
+ let reconnectAttempts = 0;
52
+ const performanceConfig = (0, Utils_1.getPerformanceConfig)();
53
+
54
+ const handleReconnect = async () => {
55
+ if (closed) return;
56
+
57
+ reconnectAttempts++;
58
+ const delay = Math.min(
59
+ performanceConfig.performance.retryDelay * Math.pow(
60
+ performanceConfig.performance.retryBackoffMultiplier,
61
+ reconnectAttempts - 1
62
+ ),
63
+ performanceConfig.performance.maxRetryDelay
64
+ );
65
+
66
+ logger?.info({
67
+ reconnectAttempts,
68
+ delay
69
+ }, 'Attempting to reconnect...');
70
+
71
+ await (0, Utils_1.delay)(delay);
72
+
73
+ if (reconnectAttempts <= performanceConfig.performance.maxRetries) {
74
+ try {
75
+ ws.connect();
76
+ } catch (error) {
77
+ logger?.error({ error }, 'Reconnection attempt failed');
78
+ handleReconnect();
79
+ }
80
+ } else {
81
+ logger?.error('Max reconnection attempts reached');
82
+ ev.emit('connection.update', {
83
+ connection: 'close',
84
+ lastDisconnect: {
85
+ error: new boom_1.Boom('Max reconnection attempts reached', {
86
+ statusCode: Types_1.DisconnectReason.connectionClosed
87
+ })
88
+ }
89
+ });
90
+ }
91
+ };
51
92
  const uqTagId = (0, Utils_1.generateMdTagPrefix)();
52
93
  const generateMessageTag = () => `${uqTagId}${epoch++}`;
53
94
  const sendPromise = (0, util_1.promisify)(ws.send);
@@ -266,8 +307,10 @@ const makeSocket = (config) => {
266
307
  logger.trace({ trace: error === null || error === void 0 ? void 0 : error.stack }, 'connection already closed');
267
308
  return;
268
309
  }
269
- closed = true;
270
- logger.info({ trace: error === null || error === void 0 ? void 0 : error.stack }, error ? 'connection errored' : 'connection closed');
310
+ const statusCode = error?.output?.statusCode;
311
+ const shouldReconnect = statusCode !== Types_1.DisconnectReason.loggedOut;
312
+ logger.info({ trace: error === null || error === void 0 ? void 0 : error.stack, shouldReconnect }, error ? 'connection errored' : 'connection closed');
313
+ closed = !shouldReconnect;
271
314
  clearInterval(keepAliveReq);
272
315
  clearTimeout(qrTimer);
273
316
  ws.removeAllListeners('close');
@@ -287,7 +330,12 @@ const makeSocket = (config) => {
287
330
  date: new Date()
288
331
  }
289
332
  });
290
- ev.removeAllListeners('connection.update');
333
+ if (shouldReconnect) {
334
+ handleReconnect();
335
+ }
336
+ else {
337
+ ev.removeAllListeners('connection.update');
338
+ }
291
339
  };
292
340
  const waitForSocketOpen = async () => {
293
341
  if (ws.isOpen) {
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ const NodeCache = require('node-cache');
3
+ const { getPerformanceConfig } = require('./performance-config');
4
+
5
+ class CacheManager {
6
+ constructor() {
7
+ const config = getPerformanceConfig();
8
+ this.caches = {};
9
+ this.memoryCheckInterval = null;
10
+
11
+ // Inizializza le cache con TTL
12
+ Object.entries(config.cache).forEach(([name, options]) => {
13
+ this.caches[name] = new NodeCache({
14
+ stdTTL: options.ttl / 1000, // Converti da ms a secondi
15
+ checkperiod: options.cleanupInterval / 1000,
16
+ maxKeys: options.maxSize
17
+ });
18
+ });
19
+
20
+ if (config.performance.enableMetrics) {
21
+ this.startMemoryMonitoring(config.performance.memoryThreshold);
22
+ }
23
+ }
24
+
25
+ startMemoryMonitoring(threshold) {
26
+ this.memoryCheckInterval = setInterval(() => {
27
+ const used = process.memoryUsage().heapUsed;
28
+ const total = process.memoryUsage().heapTotal;
29
+ const ratio = used / total;
30
+
31
+ if (ratio > threshold) {
32
+ this.evictLeastUsed();
33
+ }
34
+ }, 60000); // Controlla ogni minuto
35
+ }
36
+
37
+ evictLeastUsed() {
38
+ Object.values(this.caches).forEach(cache => {
39
+ const stats = cache.getStats();
40
+ if (stats.keys > 100) { // Mantieni almeno 100 chiavi
41
+ const keys = cache.keys();
42
+ // Rimuovi il 20% delle chiavi meno usate
43
+ const toRemove = Math.floor(keys.length * 0.2);
44
+ keys.slice(0, toRemove).forEach(key => cache.del(key));
45
+ }
46
+ });
47
+ }
48
+
49
+ get(cacheName, key) {
50
+ return this.caches[cacheName]?.get(key);
51
+ }
52
+
53
+ set(cacheName, key, value, ttl = undefined) {
54
+ return this.caches[cacheName]?.set(key, value, ttl);
55
+ }
56
+
57
+ del(cacheName, key) {
58
+ return this.caches[cacheName]?.del(key);
59
+ }
60
+
61
+ getStats(cacheName) {
62
+ return this.caches[cacheName]?.getStats();
63
+ }
64
+
65
+ shutdown() {
66
+ if (this.memoryCheckInterval) {
67
+ clearInterval(this.memoryCheckInterval);
68
+ }
69
+ Object.values(this.caches).forEach(cache => cache.close());
70
+ }
71
+ }
72
+
73
+ module.exports = new CacheManager();