@goatlab/node-backend 1.1.8 → 1.1.10
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/dist/Cache.d.ts +14 -0
- package/dist/Cache.js +35 -19
- package/dist/Cache.js.map +1 -1
- package/dist/cache/RedisConnectionPool.d.ts +53 -0
- package/dist/cache/RedisConnectionPool.js +112 -0
- package/dist/cache/RedisConnectionPool.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
package/dist/Cache.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ export declare class Cache<T extends object = any> extends Keyv<T> {
|
|
|
7
7
|
private usesLRUMemory?;
|
|
8
8
|
private keyvLru;
|
|
9
9
|
private memoryCache;
|
|
10
|
+
private connectionString?;
|
|
11
|
+
private connectionPool;
|
|
10
12
|
constructor({ connection, opts }: {
|
|
11
13
|
connection: string | undefined;
|
|
12
14
|
opts?: Options<T> & {
|
|
@@ -60,5 +62,17 @@ export declare class Cache<T extends object = any> extends Keyv<T> {
|
|
|
60
62
|
flush(): Promise<void>;
|
|
61
63
|
deleteWhereStartsWith(value: string): Promise<void>;
|
|
62
64
|
getValueWhereKeyStartsWith<T>(value: string): Promise<T[]>;
|
|
65
|
+
/**
|
|
66
|
+
* Dispose of this cache instance and release the Redis connection.
|
|
67
|
+
* After calling this, the cache instance should not be used.
|
|
68
|
+
* The connection will remain in the pool for reuse by other instances.
|
|
69
|
+
*/
|
|
70
|
+
dispose(): void;
|
|
71
|
+
/**
|
|
72
|
+
* Disconnect the Redis connection for this cache instance.
|
|
73
|
+
* This removes the connection from the pool entirely.
|
|
74
|
+
* Use this when you're certain no other instances need this connection.
|
|
75
|
+
*/
|
|
76
|
+
disconnect(): Promise<void>;
|
|
63
77
|
}
|
|
64
78
|
export {};
|
package/dist/Cache.js
CHANGED
|
@@ -2,36 +2,30 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Cache = void 0;
|
|
4
4
|
const js_utils_1 = require("@goatlab/js-utils");
|
|
5
|
-
const redis_1 = require("@keyv/redis");
|
|
6
5
|
const Keyv = require('keyv');
|
|
7
6
|
const KeyvLrus_1 = require("./cache/KeyvLrus");
|
|
8
|
-
|
|
9
|
-
* Shared Redis connection pool to avoid creating multiple connections
|
|
10
|
-
* Key: Redis connection string
|
|
11
|
-
* Value: KeyvRedis instance
|
|
12
|
-
*/
|
|
13
|
-
const redisConnectionPool = new Map();
|
|
14
|
-
function getOrCreateRedisStore(connection) {
|
|
15
|
-
if (!redisConnectionPool.has(connection)) {
|
|
16
|
-
redisConnectionPool.set(connection, new redis_1.default(connection));
|
|
17
|
-
}
|
|
18
|
-
return redisConnectionPool.get(connection);
|
|
19
|
-
}
|
|
7
|
+
const RedisConnectionPool_1 = require("./cache/RedisConnectionPool");
|
|
20
8
|
class Cache extends Keyv {
|
|
21
9
|
ns;
|
|
22
10
|
_tenantId;
|
|
23
11
|
usesLRUMemory;
|
|
24
12
|
keyvLru;
|
|
25
13
|
memoryCache;
|
|
14
|
+
connectionString;
|
|
15
|
+
connectionPool;
|
|
26
16
|
constructor({ connection, opts }) {
|
|
27
17
|
const tenantId = opts?.tenantId;
|
|
28
18
|
const namespace = opts?.namespace || '';
|
|
29
|
-
const tenantNs = tenantId ? `tenant:${tenantId}` : '';
|
|
30
19
|
// Build the full namespace including tenant ID if provided
|
|
31
|
-
|
|
20
|
+
// Format: "tenantId:namespace" or "tenantId" or "namespace" or ""
|
|
21
|
+
const fullNamespace = tenantId && namespace
|
|
22
|
+
? `${tenantId}:${namespace}`
|
|
23
|
+
: tenantId || namespace || '';
|
|
24
|
+
// Get connection pool instance
|
|
25
|
+
const pool = RedisConnectionPool_1.RedisConnectionPool.getInstance();
|
|
32
26
|
super({
|
|
33
27
|
store: connection
|
|
34
|
-
?
|
|
28
|
+
? pool.getConnection(connection)
|
|
35
29
|
: new KeyvLrus_1.KeyvLru({
|
|
36
30
|
max: 1000,
|
|
37
31
|
resetTtl: false,
|
|
@@ -40,6 +34,8 @@ class Cache extends Keyv {
|
|
|
40
34
|
...opts,
|
|
41
35
|
namespace: fullNamespace
|
|
42
36
|
});
|
|
37
|
+
this.connectionString = connection;
|
|
38
|
+
this.connectionPool = pool;
|
|
43
39
|
this.keyvLru = new KeyvLrus_1.KeyvLru({
|
|
44
40
|
max: 1000,
|
|
45
41
|
resetTtl: false,
|
|
@@ -83,7 +79,7 @@ class Cache extends Keyv {
|
|
|
83
79
|
// It will greatly improve performance
|
|
84
80
|
// for "frequent" uses
|
|
85
81
|
if (this.usesLRUMemory) {
|
|
86
|
-
const memoryVal = await this.memoryCache.get(
|
|
82
|
+
const memoryVal = await this.memoryCache.get(key);
|
|
87
83
|
if (memoryVal) {
|
|
88
84
|
return memoryVal;
|
|
89
85
|
}
|
|
@@ -91,13 +87,13 @@ class Cache extends Keyv {
|
|
|
91
87
|
const result = await super.get(key);
|
|
92
88
|
if (this.usesLRUMemory && result) {
|
|
93
89
|
// We could also just overwrite the set method as well
|
|
94
|
-
await this.memoryCache.set(
|
|
90
|
+
await this.memoryCache.set(key, result);
|
|
95
91
|
}
|
|
96
92
|
return result;
|
|
97
93
|
}
|
|
98
94
|
async delete(key) {
|
|
99
95
|
if (this.usesLRUMemory) {
|
|
100
|
-
await this.memoryCache.delete(
|
|
96
|
+
await this.memoryCache.delete(key);
|
|
101
97
|
}
|
|
102
98
|
return await super.delete(key);
|
|
103
99
|
}
|
|
@@ -240,6 +236,26 @@ class Cache extends Keyv {
|
|
|
240
236
|
}
|
|
241
237
|
return result;
|
|
242
238
|
}
|
|
239
|
+
/**
|
|
240
|
+
* Dispose of this cache instance and release the Redis connection.
|
|
241
|
+
* After calling this, the cache instance should not be used.
|
|
242
|
+
* The connection will remain in the pool for reuse by other instances.
|
|
243
|
+
*/
|
|
244
|
+
dispose() {
|
|
245
|
+
if (this.connectionString) {
|
|
246
|
+
this.connectionPool.releaseConnection(this.connectionString);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Disconnect the Redis connection for this cache instance.
|
|
251
|
+
* This removes the connection from the pool entirely.
|
|
252
|
+
* Use this when you're certain no other instances need this connection.
|
|
253
|
+
*/
|
|
254
|
+
async disconnect() {
|
|
255
|
+
if (this.connectionString) {
|
|
256
|
+
await this.connectionPool.disconnect(this.connectionString);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
243
259
|
}
|
|
244
260
|
exports.Cache = Cache;
|
|
245
261
|
//# sourceMappingURL=Cache.js.map
|
package/dist/Cache.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Cache.js","sourceRoot":"","sources":["../src/Cache.ts"],"names":[],"mappings":";;;AAAA,gDAA+D;
|
|
1
|
+
{"version":3,"file":"Cache.js","sourceRoot":"","sources":["../src/Cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import KeyvRedis from '@keyv/redis';
|
|
2
|
+
/**
|
|
3
|
+
* Singleton connection pool for Redis connections.
|
|
4
|
+
* Ensures multiple Cache instances pointing to the same Redis instance
|
|
5
|
+
* share the same underlying Redis client, avoiding connection exhaustion.
|
|
6
|
+
* Each Cache gets its own KeyvRedis wrapper but shares the client.
|
|
7
|
+
*/
|
|
8
|
+
export declare class RedisConnectionPool {
|
|
9
|
+
private static instance;
|
|
10
|
+
private pool;
|
|
11
|
+
private constructor();
|
|
12
|
+
static getInstance(): RedisConnectionPool;
|
|
13
|
+
/**
|
|
14
|
+
* Get a Redis store from the pool. Creates a new KeyvRedis instance that uses
|
|
15
|
+
* a shared Redis client if one exists, or creates a new client if not.
|
|
16
|
+
* @param connectionString The Redis connection string
|
|
17
|
+
* @returns KeyvRedis store instance
|
|
18
|
+
*/
|
|
19
|
+
getConnection(connectionString: string): KeyvRedis;
|
|
20
|
+
/**
|
|
21
|
+
* Release a Redis connection. When reference count reaches 0,
|
|
22
|
+
* the connection is kept in the pool for reuse.
|
|
23
|
+
* @param connectionString The Redis connection string
|
|
24
|
+
*/
|
|
25
|
+
releaseConnection(connectionString: string): void;
|
|
26
|
+
/**
|
|
27
|
+
* Disconnect and remove a connection from the pool.
|
|
28
|
+
* This should be called when you're certain no more instances will need this connection.
|
|
29
|
+
* @param connectionString The Redis connection string
|
|
30
|
+
*/
|
|
31
|
+
disconnect(connectionString: string): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Disconnect all connections in the pool.
|
|
34
|
+
* Useful for cleanup during application shutdown.
|
|
35
|
+
*/
|
|
36
|
+
disconnectAll(): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Get the reference count for a connection.
|
|
39
|
+
* Useful for testing and debugging.
|
|
40
|
+
* @param connectionString The Redis connection string
|
|
41
|
+
*/
|
|
42
|
+
getRefCount(connectionString: string): number;
|
|
43
|
+
/**
|
|
44
|
+
* Get the number of connections in the pool.
|
|
45
|
+
* Useful for testing and debugging.
|
|
46
|
+
*/
|
|
47
|
+
getPoolSize(): number;
|
|
48
|
+
/**
|
|
49
|
+
* Clear the pool without disconnecting.
|
|
50
|
+
* Only use this for testing purposes.
|
|
51
|
+
*/
|
|
52
|
+
clearPool(): void;
|
|
53
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RedisConnectionPool = void 0;
|
|
4
|
+
// npx vitest run ./src/cache/RedisConnectionPool.test.ts
|
|
5
|
+
const redis_1 = require("@keyv/redis");
|
|
6
|
+
/**
|
|
7
|
+
* Singleton connection pool for Redis connections.
|
|
8
|
+
* Ensures multiple Cache instances pointing to the same Redis instance
|
|
9
|
+
* share the same underlying Redis client, avoiding connection exhaustion.
|
|
10
|
+
* Each Cache gets its own KeyvRedis wrapper but shares the client.
|
|
11
|
+
*/
|
|
12
|
+
class RedisConnectionPool {
|
|
13
|
+
static instance;
|
|
14
|
+
pool = new Map();
|
|
15
|
+
constructor() { }
|
|
16
|
+
static getInstance() {
|
|
17
|
+
if (!RedisConnectionPool.instance) {
|
|
18
|
+
RedisConnectionPool.instance = new RedisConnectionPool();
|
|
19
|
+
}
|
|
20
|
+
return RedisConnectionPool.instance;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Get a Redis store from the pool. Creates a new KeyvRedis instance that uses
|
|
24
|
+
* a shared Redis client if one exists, or creates a new client if not.
|
|
25
|
+
* @param connectionString The Redis connection string
|
|
26
|
+
* @returns KeyvRedis store instance
|
|
27
|
+
*/
|
|
28
|
+
getConnection(connectionString) {
|
|
29
|
+
const entry = this.pool.get(connectionString);
|
|
30
|
+
if (entry) {
|
|
31
|
+
entry.refCount++;
|
|
32
|
+
// Create a new KeyvRedis instance that uses the existing client
|
|
33
|
+
return new redis_1.default(entry.client);
|
|
34
|
+
}
|
|
35
|
+
// Create new connection - KeyvRedis will create the Redis client
|
|
36
|
+
const store = new redis_1.default(connectionString);
|
|
37
|
+
// @ts-expect-error - accessing private property to get the client
|
|
38
|
+
const client = store.redis || store.client;
|
|
39
|
+
this.pool.set(connectionString, {
|
|
40
|
+
client,
|
|
41
|
+
refCount: 1
|
|
42
|
+
});
|
|
43
|
+
return store;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Release a Redis connection. When reference count reaches 0,
|
|
47
|
+
* the connection is kept in the pool for reuse.
|
|
48
|
+
* @param connectionString The Redis connection string
|
|
49
|
+
*/
|
|
50
|
+
releaseConnection(connectionString) {
|
|
51
|
+
const entry = this.pool.get(connectionString);
|
|
52
|
+
if (!entry) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
entry.refCount--;
|
|
56
|
+
// We keep the connection in the pool even when refCount reaches 0
|
|
57
|
+
// for potential reuse. Use disconnect() to actually remove it.
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Disconnect and remove a connection from the pool.
|
|
61
|
+
* This should be called when you're certain no more instances will need this connection.
|
|
62
|
+
* @param connectionString The Redis connection string
|
|
63
|
+
*/
|
|
64
|
+
async disconnect(connectionString) {
|
|
65
|
+
const entry = this.pool.get(connectionString);
|
|
66
|
+
if (!entry) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
// Disconnect the Redis client
|
|
70
|
+
if (entry.client) {
|
|
71
|
+
if (typeof entry.client.disconnect === 'function') {
|
|
72
|
+
await entry.client.disconnect();
|
|
73
|
+
}
|
|
74
|
+
else if (typeof entry.client.quit === 'function') {
|
|
75
|
+
await entry.client.quit();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
this.pool.delete(connectionString);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Disconnect all connections in the pool.
|
|
82
|
+
* Useful for cleanup during application shutdown.
|
|
83
|
+
*/
|
|
84
|
+
async disconnectAll() {
|
|
85
|
+
const disconnectPromises = Array.from(this.pool.keys()).map(key => this.disconnect(key));
|
|
86
|
+
await Promise.all(disconnectPromises);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Get the reference count for a connection.
|
|
90
|
+
* Useful for testing and debugging.
|
|
91
|
+
* @param connectionString The Redis connection string
|
|
92
|
+
*/
|
|
93
|
+
getRefCount(connectionString) {
|
|
94
|
+
return this.pool.get(connectionString)?.refCount || 0;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get the number of connections in the pool.
|
|
98
|
+
* Useful for testing and debugging.
|
|
99
|
+
*/
|
|
100
|
+
getPoolSize() {
|
|
101
|
+
return this.pool.size;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Clear the pool without disconnecting.
|
|
105
|
+
* Only use this for testing purposes.
|
|
106
|
+
*/
|
|
107
|
+
clearPool() {
|
|
108
|
+
this.pool.clear();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
exports.RedisConnectionPool = RedisConnectionPool;
|
|
112
|
+
//# sourceMappingURL=RedisConnectionPool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RedisConnectionPool.js","sourceRoot":"","sources":["../../src/cache/RedisConnectionPool.ts"],"names":[],"mappings":"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"}
|