pg-cache 3.10.1 → 3.11.1
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/esm/index.js +2 -2
- package/esm/lru.js +35 -10
- package/esm/pg.js +24 -1
- package/index.d.ts +3 -3
- package/index.js +3 -1
- package/lru.d.ts +16 -0
- package/lru.js +36 -10
- package/package.json +5 -5
- package/pg.d.ts +13 -2
- package/pg.js +25 -1
package/esm/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// Main exports from pg-cache package
|
|
2
|
-
export { close, pgCache, PgPoolCacheManager, teardownPgPools } from './lru';
|
|
3
|
-
export { buildConnectionString, getPgPool } from './pg';
|
|
2
|
+
export { close, getPgCacheConfig, pgCache, PgPoolCacheManager, teardownPgPools } from './lru';
|
|
3
|
+
export { buildConnectionString, getPgPool, getPgPoolConfig } from './pg';
|
package/esm/lru.js
CHANGED
|
@@ -6,6 +6,25 @@ const ONE_DAY = ONE_HOUR_IN_MS * 24;
|
|
|
6
6
|
const ONE_YEAR = ONE_DAY * 366;
|
|
7
7
|
// Kubernetes sends only SIGTERM on pod shutdown
|
|
8
8
|
const SYS_EVENTS = ['SIGTERM'];
|
|
9
|
+
const parseEnvInt = (val, fallback) => {
|
|
10
|
+
if (!val)
|
|
11
|
+
return fallback;
|
|
12
|
+
const n = parseInt(val, 10);
|
|
13
|
+
return isNaN(n) ? fallback : n;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Read cache configuration from environment variables.
|
|
17
|
+
*
|
|
18
|
+
* Supports:
|
|
19
|
+
* - PG_CACHE_MAX: Maximum number of pools (default: 50)
|
|
20
|
+
* - PG_CACHE_TTL_MS: TTL in milliseconds (default: ONE_YEAR)
|
|
21
|
+
*/
|
|
22
|
+
export function getPgCacheConfig() {
|
|
23
|
+
return {
|
|
24
|
+
max: parseEnvInt(process.env.PG_CACHE_MAX, 50),
|
|
25
|
+
ttl: parseEnvInt(process.env.PG_CACHE_TTL_MS, ONE_YEAR),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
9
28
|
class ManagedPgPool {
|
|
10
29
|
pool;
|
|
11
30
|
key;
|
|
@@ -41,16 +60,22 @@ export class PgPoolCacheManager {
|
|
|
41
60
|
cleanupTasks = [];
|
|
42
61
|
closed = false;
|
|
43
62
|
cleanupCallbacks = new Set();
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
this.
|
|
51
|
-
this.
|
|
52
|
-
|
|
53
|
-
|
|
63
|
+
config;
|
|
64
|
+
pgCache;
|
|
65
|
+
constructor(config) {
|
|
66
|
+
const defaults = getPgCacheConfig();
|
|
67
|
+
this.config = { ...defaults, ...config };
|
|
68
|
+
this.pgCache = new LRUCache({
|
|
69
|
+
max: this.config.max,
|
|
70
|
+
ttl: this.config.ttl,
|
|
71
|
+
updateAgeOnGet: true,
|
|
72
|
+
dispose: (managedPool, key, reason) => {
|
|
73
|
+
log.debug(`Disposing pg pool [${key}] (${reason})`);
|
|
74
|
+
this.notifyCleanup(key);
|
|
75
|
+
this.disposePool(managedPool);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
54
79
|
// Register a cleanup callback to be called when pools are disposed
|
|
55
80
|
registerCleanupCallback(callback) {
|
|
56
81
|
this.cleanupCallbacks.add(callback);
|
package/esm/pg.js
CHANGED
|
@@ -4,6 +4,28 @@ import { Logger } from '@pgpmjs/logger';
|
|
|
4
4
|
import { pgCache } from './lru';
|
|
5
5
|
const log = new Logger('pg-cache');
|
|
6
6
|
export const buildConnectionString = (user, password, host, port, database) => `postgres://${user}:${password}@${host}:${port}/${database}`;
|
|
7
|
+
const parseEnvInt = (val, fallback) => {
|
|
8
|
+
if (!val)
|
|
9
|
+
return fallback;
|
|
10
|
+
const n = parseInt(val, 10);
|
|
11
|
+
return isNaN(n) ? fallback : n;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Read per-pool configuration from environment variables.
|
|
15
|
+
*
|
|
16
|
+
* Supports:
|
|
17
|
+
* - PG_POOL_MAX: Maximum clients per pool (default: 5)
|
|
18
|
+
* - PG_POOL_IDLE_TIMEOUT_MS: Close idle clients after ms (default: 30000)
|
|
19
|
+
* - PG_POOL_CONNECTION_TIMEOUT_MS: Fail connect() after ms (default: 5000)
|
|
20
|
+
*/
|
|
21
|
+
export function getPgPoolConfig(overrides) {
|
|
22
|
+
return {
|
|
23
|
+
max: overrides?.max ?? parseEnvInt(process.env.PG_POOL_MAX, 5),
|
|
24
|
+
idleTimeoutMillis: overrides?.idleTimeoutMillis ?? parseEnvInt(process.env.PG_POOL_IDLE_TIMEOUT_MS, 30000),
|
|
25
|
+
connectionTimeoutMillis: overrides?.connectionTimeoutMillis ?? parseEnvInt(process.env.PG_POOL_CONNECTION_TIMEOUT_MS, 5000),
|
|
26
|
+
...(overrides?.allowExitOnIdle !== undefined && { allowExitOnIdle: overrides.allowExitOnIdle }),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
7
29
|
export const getPgPool = (pgConfig) => {
|
|
8
30
|
const config = getPgEnvOptions(pgConfig);
|
|
9
31
|
const { user, password, host, port, database, } = config;
|
|
@@ -13,7 +35,8 @@ export const getPgPool = (pgConfig) => {
|
|
|
13
35
|
return cached;
|
|
14
36
|
}
|
|
15
37
|
const connectionString = buildConnectionString(user, password, host, port, database);
|
|
16
|
-
const
|
|
38
|
+
const poolConfig = getPgPoolConfig(pgConfig.pool);
|
|
39
|
+
const pgPool = new pg.Pool({ connectionString, ...poolConfig });
|
|
17
40
|
/**
|
|
18
41
|
* IMPORTANT: Pool-level error handler for idle connection errors.
|
|
19
42
|
*
|
package/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { close, pgCache, PgPoolCacheManager, teardownPgPools } from './lru';
|
|
2
|
-
export { buildConnectionString, getPgPool } from './pg';
|
|
3
|
-
export type { PoolCleanupCallback } from './lru';
|
|
1
|
+
export { close, getPgCacheConfig, pgCache, PgPoolCacheManager, teardownPgPools } from './lru';
|
|
2
|
+
export { buildConnectionString, getPgPool, getPgPoolConfig } from './pg';
|
|
3
|
+
export type { PgCacheConfig, PoolCleanupCallback } from './lru';
|
package/index.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getPgPool = exports.buildConnectionString = exports.teardownPgPools = exports.PgPoolCacheManager = exports.pgCache = void 0;
|
|
3
|
+
exports.getPgPoolConfig = exports.getPgPool = exports.buildConnectionString = exports.teardownPgPools = exports.PgPoolCacheManager = exports.pgCache = exports.getPgCacheConfig = void 0;
|
|
4
4
|
// Main exports from pg-cache package
|
|
5
5
|
var lru_1 = require("./lru");
|
|
6
6
|
Object.defineProperty(exports, "close", { enumerable: true, get: function () { return lru_1.close; } });
|
|
7
|
+
Object.defineProperty(exports, "getPgCacheConfig", { enumerable: true, get: function () { return lru_1.getPgCacheConfig; } });
|
|
7
8
|
Object.defineProperty(exports, "pgCache", { enumerable: true, get: function () { return lru_1.pgCache; } });
|
|
8
9
|
Object.defineProperty(exports, "PgPoolCacheManager", { enumerable: true, get: function () { return lru_1.PgPoolCacheManager; } });
|
|
9
10
|
Object.defineProperty(exports, "teardownPgPools", { enumerable: true, get: function () { return lru_1.teardownPgPools; } });
|
|
10
11
|
var pg_1 = require("./pg");
|
|
11
12
|
Object.defineProperty(exports, "buildConnectionString", { enumerable: true, get: function () { return pg_1.buildConnectionString; } });
|
|
12
13
|
Object.defineProperty(exports, "getPgPool", { enumerable: true, get: function () { return pg_1.getPgPool; } });
|
|
14
|
+
Object.defineProperty(exports, "getPgPoolConfig", { enumerable: true, get: function () { return pg_1.getPgPoolConfig; } });
|
package/lru.d.ts
CHANGED
|
@@ -1,11 +1,27 @@
|
|
|
1
1
|
import pg from 'pg';
|
|
2
2
|
type PgPoolKey = string;
|
|
3
3
|
export type PoolCleanupCallback = (pgPoolKey: string) => void;
|
|
4
|
+
export interface PgCacheConfig {
|
|
5
|
+
/** Maximum number of pools in the LRU cache (env: PG_CACHE_MAX, default: 50) */
|
|
6
|
+
max: number;
|
|
7
|
+
/** TTL for cached pools in ms (default: ONE_YEAR) */
|
|
8
|
+
ttl: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Read cache configuration from environment variables.
|
|
12
|
+
*
|
|
13
|
+
* Supports:
|
|
14
|
+
* - PG_CACHE_MAX: Maximum number of pools (default: 50)
|
|
15
|
+
* - PG_CACHE_TTL_MS: TTL in milliseconds (default: ONE_YEAR)
|
|
16
|
+
*/
|
|
17
|
+
export declare function getPgCacheConfig(): PgCacheConfig;
|
|
4
18
|
export declare class PgPoolCacheManager {
|
|
5
19
|
private cleanupTasks;
|
|
6
20
|
private closed;
|
|
7
21
|
private cleanupCallbacks;
|
|
22
|
+
readonly config: PgCacheConfig;
|
|
8
23
|
private readonly pgCache;
|
|
24
|
+
constructor(config?: Partial<PgCacheConfig>);
|
|
9
25
|
registerCleanupCallback(callback: PoolCleanupCallback): () => void;
|
|
10
26
|
get(key: PgPoolKey): pg.Pool | undefined;
|
|
11
27
|
has(key: PgPoolKey): boolean;
|
package/lru.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.teardownPgPools = exports.close = exports.pgCache = exports.PgPoolCacheManager = void 0;
|
|
4
|
+
exports.getPgCacheConfig = getPgCacheConfig;
|
|
4
5
|
const logger_1 = require("@pgpmjs/logger");
|
|
5
6
|
const lru_cache_1 = require("lru-cache");
|
|
6
7
|
const log = new logger_1.Logger('pg-cache');
|
|
@@ -9,6 +10,25 @@ const ONE_DAY = ONE_HOUR_IN_MS * 24;
|
|
|
9
10
|
const ONE_YEAR = ONE_DAY * 366;
|
|
10
11
|
// Kubernetes sends only SIGTERM on pod shutdown
|
|
11
12
|
const SYS_EVENTS = ['SIGTERM'];
|
|
13
|
+
const parseEnvInt = (val, fallback) => {
|
|
14
|
+
if (!val)
|
|
15
|
+
return fallback;
|
|
16
|
+
const n = parseInt(val, 10);
|
|
17
|
+
return isNaN(n) ? fallback : n;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Read cache configuration from environment variables.
|
|
21
|
+
*
|
|
22
|
+
* Supports:
|
|
23
|
+
* - PG_CACHE_MAX: Maximum number of pools (default: 50)
|
|
24
|
+
* - PG_CACHE_TTL_MS: TTL in milliseconds (default: ONE_YEAR)
|
|
25
|
+
*/
|
|
26
|
+
function getPgCacheConfig() {
|
|
27
|
+
return {
|
|
28
|
+
max: parseEnvInt(process.env.PG_CACHE_MAX, 50),
|
|
29
|
+
ttl: parseEnvInt(process.env.PG_CACHE_TTL_MS, ONE_YEAR),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
12
32
|
class ManagedPgPool {
|
|
13
33
|
pool;
|
|
14
34
|
key;
|
|
@@ -44,16 +64,22 @@ class PgPoolCacheManager {
|
|
|
44
64
|
cleanupTasks = [];
|
|
45
65
|
closed = false;
|
|
46
66
|
cleanupCallbacks = new Set();
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
this.
|
|
54
|
-
this.
|
|
55
|
-
|
|
56
|
-
|
|
67
|
+
config;
|
|
68
|
+
pgCache;
|
|
69
|
+
constructor(config) {
|
|
70
|
+
const defaults = getPgCacheConfig();
|
|
71
|
+
this.config = { ...defaults, ...config };
|
|
72
|
+
this.pgCache = new lru_cache_1.LRUCache({
|
|
73
|
+
max: this.config.max,
|
|
74
|
+
ttl: this.config.ttl,
|
|
75
|
+
updateAgeOnGet: true,
|
|
76
|
+
dispose: (managedPool, key, reason) => {
|
|
77
|
+
log.debug(`Disposing pg pool [${key}] (${reason})`);
|
|
78
|
+
this.notifyCleanup(key);
|
|
79
|
+
this.disposePool(managedPool);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
57
83
|
// Register a cleanup callback to be called when pools are disposed
|
|
58
84
|
registerCleanupCallback(callback) {
|
|
59
85
|
this.cleanupCallbacks.add(callback);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pg-cache",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.11.1",
|
|
4
4
|
"author": "Constructive <developers@constructive.io>",
|
|
5
5
|
"description": "PostgreSQL connection pool LRU cache manager",
|
|
6
6
|
"main": "index.js",
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
"test:watch": "jest --watch"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@pgpmjs/logger": "^2.11.
|
|
33
|
-
"@pgpmjs/types": "^2.
|
|
32
|
+
"@pgpmjs/logger": "^2.11.1",
|
|
33
|
+
"@pgpmjs/types": "^2.28.1",
|
|
34
34
|
"lru-cache": "^11.2.7",
|
|
35
35
|
"pg": "^8.21.0",
|
|
36
|
-
"pg-env": "^1.
|
|
36
|
+
"pg-env": "^1.15.1"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@types/pg": "^8.20.0",
|
|
@@ -48,5 +48,5 @@
|
|
|
48
48
|
"connection",
|
|
49
49
|
"constructive"
|
|
50
50
|
],
|
|
51
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "423992019655cc1e780149ce3f7e6e8c9b1c6e80"
|
|
52
52
|
}
|
package/pg.d.ts
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
import pg from 'pg';
|
|
2
|
-
import { PgConfig } from 'pg-env';
|
|
2
|
+
import { PgConfig, PgPoolConfig } from 'pg-env';
|
|
3
3
|
export declare const buildConnectionString: (user: string, password: string, host: string, port: string | number, database: string) => string;
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Read per-pool configuration from environment variables.
|
|
6
|
+
*
|
|
7
|
+
* Supports:
|
|
8
|
+
* - PG_POOL_MAX: Maximum clients per pool (default: 5)
|
|
9
|
+
* - PG_POOL_IDLE_TIMEOUT_MS: Close idle clients after ms (default: 30000)
|
|
10
|
+
* - PG_POOL_CONNECTION_TIMEOUT_MS: Fail connect() after ms (default: 5000)
|
|
11
|
+
*/
|
|
12
|
+
export declare function getPgPoolConfig(overrides?: PgPoolConfig): pg.PoolConfig;
|
|
13
|
+
export declare const getPgPool: (pgConfig: Partial<PgConfig> & {
|
|
14
|
+
pool?: PgPoolConfig;
|
|
15
|
+
}) => pg.Pool;
|
package/pg.js
CHANGED
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getPgPool = exports.buildConnectionString = void 0;
|
|
7
|
+
exports.getPgPoolConfig = getPgPoolConfig;
|
|
7
8
|
const pg_1 = __importDefault(require("pg"));
|
|
8
9
|
const pg_env_1 = require("pg-env");
|
|
9
10
|
const logger_1 = require("@pgpmjs/logger");
|
|
@@ -11,6 +12,28 @@ const lru_1 = require("./lru");
|
|
|
11
12
|
const log = new logger_1.Logger('pg-cache');
|
|
12
13
|
const buildConnectionString = (user, password, host, port, database) => `postgres://${user}:${password}@${host}:${port}/${database}`;
|
|
13
14
|
exports.buildConnectionString = buildConnectionString;
|
|
15
|
+
const parseEnvInt = (val, fallback) => {
|
|
16
|
+
if (!val)
|
|
17
|
+
return fallback;
|
|
18
|
+
const n = parseInt(val, 10);
|
|
19
|
+
return isNaN(n) ? fallback : n;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Read per-pool configuration from environment variables.
|
|
23
|
+
*
|
|
24
|
+
* Supports:
|
|
25
|
+
* - PG_POOL_MAX: Maximum clients per pool (default: 5)
|
|
26
|
+
* - PG_POOL_IDLE_TIMEOUT_MS: Close idle clients after ms (default: 30000)
|
|
27
|
+
* - PG_POOL_CONNECTION_TIMEOUT_MS: Fail connect() after ms (default: 5000)
|
|
28
|
+
*/
|
|
29
|
+
function getPgPoolConfig(overrides) {
|
|
30
|
+
return {
|
|
31
|
+
max: overrides?.max ?? parseEnvInt(process.env.PG_POOL_MAX, 5),
|
|
32
|
+
idleTimeoutMillis: overrides?.idleTimeoutMillis ?? parseEnvInt(process.env.PG_POOL_IDLE_TIMEOUT_MS, 30000),
|
|
33
|
+
connectionTimeoutMillis: overrides?.connectionTimeoutMillis ?? parseEnvInt(process.env.PG_POOL_CONNECTION_TIMEOUT_MS, 5000),
|
|
34
|
+
...(overrides?.allowExitOnIdle !== undefined && { allowExitOnIdle: overrides.allowExitOnIdle }),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
14
37
|
const getPgPool = (pgConfig) => {
|
|
15
38
|
const config = (0, pg_env_1.getPgEnvOptions)(pgConfig);
|
|
16
39
|
const { user, password, host, port, database, } = config;
|
|
@@ -20,7 +43,8 @@ const getPgPool = (pgConfig) => {
|
|
|
20
43
|
return cached;
|
|
21
44
|
}
|
|
22
45
|
const connectionString = (0, exports.buildConnectionString)(user, password, host, port, database);
|
|
23
|
-
const
|
|
46
|
+
const poolConfig = getPgPoolConfig(pgConfig.pool);
|
|
47
|
+
const pgPool = new pg_1.default.Pool({ connectionString, ...poolConfig });
|
|
24
48
|
/**
|
|
25
49
|
* IMPORTANT: Pool-level error handler for idle connection errors.
|
|
26
50
|
*
|