-
Notifications
You must be signed in to change notification settings - Fork 67
Expand file tree
/
Copy pathregistry.js
More file actions
80 lines (69 loc) · 2.44 KB
/
Copy pathregistry.js
File metadata and controls
80 lines (69 loc) · 2.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
class LruConnectionMap {
constructor(maxSize, onEvict) {
this.map = new Map();
this.maxSize = maxSize;
this.onEvict = onEvict;
}
get(key) {
if (!this.map.has(key)) return undefined;
// Move to end to mark as recently used
const val = this.map.get(key);
this.map.delete(key);
this.map.set(key, val);
return val;
}
set(key, value) {
if (this.map.has(key)) {
this.map.delete(key);
} else if (this.map.size >= this.maxSize) {
// Evict oldest (least recently used)
const oldestKey = this.map.keys().next().value;
const oldestVal = this.map.get(oldestKey);
this.map.delete(oldestKey);
if (this.onEvict) {
try {
this.onEvict(oldestKey, oldestVal);
} catch (e) {
console.error(`Error during LRU eviction for ${oldestKey}:`, e);
}
}
}
this.map.set(key, value);
}
has(key) {
return this.map.has(key);
}
delete(key) {
return this.map.delete(key);
}
deleteIfCurrent(key, expectedValue) {
if (this.map.has(key) && this.map.get(key) === expectedValue) {
return this.map.delete(key);
}
return false;
}
get size() {
return this.map.size;
}
// Support Iterators for gc.js compatibility
*[Symbol.iterator]() {
yield* this.map[Symbol.iterator]();
}
}
// Mongoose connection pool registry (limit 50 to protect Node.js RAM/sockets)
const registry = new LruConnectionMap(50, (key, conn) => {
console.log(`[LRU Eviction] Closing idle Mongoose connection for project ${key}`);
if (conn && typeof conn.close === 'function') {
conn.close().catch(err => console.error(`[LRU Eviction Error] Failed to close connection ${key}:`, err));
}
});
// Storage registry (S3/R2 clients, lower overhead so limit is higher)
const storageRegistry = new LruConnectionMap(200, (key, client) => {
console.log(`[LRU Eviction] Removing idle storage client for project ${key}`);
if (client && typeof client.destroy === 'function') {
client.destroy();
}
});
// Circuit Breaker State Registry (Capped to prevent memory leak on inactive projects)
const circuitBreakers = new LruConnectionMap(5000);
module.exports = { registry, storageRegistry, circuitBreakers, LruConnectionMap };