@digitalwalletcorp/redis-pooling 1.3.0 → 1.4.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/README.md +32 -1
- package/lib/redis-pooling.d.ts +18 -2
- package/lib/redis-pooling.js +53 -20
- package/lib/redis-pooling.js.map +1 -1
- package/package.json +2 -2
- package/src/redis-pooling.ts +66 -20
package/README.md
CHANGED
|
@@ -12,6 +12,7 @@ Designed for both server-side Node.js applications and cron-style background job
|
|
|
12
12
|
* **Custom Utilities**: Built-in helper methods like `getKeys(pattern)` and `deleteKeys(pattern)` for convenient Redis key operations.
|
|
13
13
|
* **Connection Validation**: PING-based validation with timeout before borrowing from the pool.
|
|
14
14
|
* **TLS Support**: Optional TLS configuration for secure Redis connections.
|
|
15
|
+
* **Pluggable Logging**: Pass your own logger (`debug` / `info` / `warn` / `error`) to route logs into your application's logging. Without one, `debug` / `info` logs go to the console when `debug` is enabled and warnings go through `process.emitWarning`.
|
|
15
16
|
|
|
16
17
|
#### 📦 Installation
|
|
17
18
|
|
|
@@ -113,7 +114,7 @@ async function manageCache() {
|
|
|
113
114
|
|
|
114
115
|
#### 📚 API Reference
|
|
115
116
|
|
|
116
|
-
##### `new RedisPool(config: RedisConfig)`
|
|
117
|
+
##### `new RedisPool(config: RedisConfig, options?: RedisPoolOptions)`
|
|
117
118
|
|
|
118
119
|
Creates a Redis connection pool.
|
|
119
120
|
|
|
@@ -128,6 +129,35 @@ Creates a Redis connection pool.
|
|
|
128
129
|
| `testOnBorrow` | boolean | true | Enable connection validate on borrow. |
|
|
129
130
|
| `enableTls` | boolean | false | Enable TLS for Redis connection. |
|
|
130
131
|
|
|
132
|
+
`RedisPoolOptions`:
|
|
133
|
+
|
|
134
|
+
| Property | Type | Default | Description |
|
|
135
|
+
| ----------------- | -------------------- | --------- | ------------------------------------------------------------------------------------------------------------- |
|
|
136
|
+
| `logger` | `RedisPoolLogger` | - | Destination of all logs. When given, the logger decides which levels are output (`debug` is ignored). |
|
|
137
|
+
| `debug` | boolean | false | Only used without `logger`. When `true`, `debug` / `info` logs are written to `console.debug` / `console.info`. |
|
|
138
|
+
| `acquireLogLevel` | `'debug' \| 'info'` | `'debug'` | Level used for client acquire / release logs. |
|
|
139
|
+
|
|
140
|
+
`RedisPoolLogger`:
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
interface RedisPoolLogger {
|
|
144
|
+
debug(...args: any[]): void;
|
|
145
|
+
info(...args: any[]): void;
|
|
146
|
+
warn(...args: any[]): void;
|
|
147
|
+
error(...args: any[]): void;
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Each log is called with the header `'[RedisPooling]'`, a message, and optional details, e.g. `logger.error('[RedisPooling]', 'detected error (on error)', error)`.
|
|
152
|
+
|
|
153
|
+
| Level | Messages |
|
|
154
|
+
| ---------------- | --------------------------------------------------------------------------------------------------------------- |
|
|
155
|
+
| `debug` / `info` | `Redis client N has been acquired.`, `Redis client released.`, `Redis client destroyed due to invalid status.` (chosen by `acquireLogLevel`) |
|
|
156
|
+
| `info` | `Destroying Redis pool...`, `Redis pool destroyed.` |
|
|
157
|
+
| `debug` | `start validate`, `ping succeeded`, `retry strategy called ...`, `client quit`, `client disconnected` |
|
|
158
|
+
| `warn` | `ping failed`, `detected error (on reconnectOnError)` |
|
|
159
|
+
| `error` | `detected error (on error)` |
|
|
160
|
+
|
|
131
161
|
##### `RedisPool` Methods
|
|
132
162
|
|
|
133
163
|
| Method | Signature | Description |
|
|
@@ -176,6 +206,7 @@ const client2 = await pool.acquire();
|
|
|
176
206
|
|
|
177
207
|
* Always release clients back to the pool using `release(client)` to avoid connection leaks.
|
|
178
208
|
* Use `acquire()` and `release()` inside `try/finally` blocks for safe resource management.
|
|
209
|
+
* Without `logger`, `warn` / `error` logs are emitted via `process.emitWarning` so that callers can suppress them with the `--no-warnings` flag (e.g. `node --no-warnings app.js`, or `NODE_OPTIONS=--no-warnings`) or handle them with `process.on('warning')`.
|
|
179
210
|
|
|
180
211
|
#### 📜 License
|
|
181
212
|
|
package/lib/redis-pooling.d.ts
CHANGED
|
@@ -9,8 +9,23 @@ export interface RedisConfig {
|
|
|
9
9
|
testOnBorrow?: boolean;
|
|
10
10
|
enableTls?: boolean;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* ログの出力先
|
|
14
|
+
* 渡した場合、どのレベルを出力するかはこのロガーが決める
|
|
15
|
+
*/
|
|
16
|
+
export interface RedisPoolLogger {
|
|
17
|
+
debug(...args: any[]): void;
|
|
18
|
+
info(...args: any[]): void;
|
|
19
|
+
warn(...args: any[]): void;
|
|
20
|
+
error(...args: any[]): void;
|
|
21
|
+
}
|
|
12
22
|
export interface RedisPoolOptions {
|
|
23
|
+
/** ログの出力先。未指定の場合はconsole(debug/info)とprocess.emitWarning(warn/error)に出力する */
|
|
24
|
+
logger?: RedisPoolLogger;
|
|
25
|
+
/** loggerを渡さない場合のみ有効。trueの場合はdebug/infoも出力する */
|
|
13
26
|
debug?: boolean;
|
|
27
|
+
/** クライアントの貸出・返却ログを出力するレベル */
|
|
28
|
+
acquireLogLevel?: 'debug' | 'info';
|
|
14
29
|
}
|
|
15
30
|
export interface RedisClient extends Redis {
|
|
16
31
|
getKeys(pattern: string, count?: number): Promise<string[]>;
|
|
@@ -27,7 +42,8 @@ export declare class RedisPool {
|
|
|
27
42
|
private readonly tls?;
|
|
28
43
|
private pool?;
|
|
29
44
|
private initialized;
|
|
30
|
-
private readonly
|
|
45
|
+
private readonly logger;
|
|
46
|
+
private readonly acquireLogLevel;
|
|
31
47
|
constructor(config: RedisConfig, options?: RedisPoolOptions);
|
|
32
48
|
acquire(dbIndex?: number): Promise<RedisClient>;
|
|
33
49
|
release(client?: RedisClient): Promise<void>;
|
|
@@ -45,7 +61,7 @@ export declare class RedisPool {
|
|
|
45
61
|
*/
|
|
46
62
|
private waitForReady;
|
|
47
63
|
private ping;
|
|
48
|
-
private
|
|
64
|
+
private acquireLog;
|
|
49
65
|
private getPool;
|
|
50
66
|
private createPool;
|
|
51
67
|
}
|
package/lib/redis-pooling.js
CHANGED
|
@@ -32,8 +32,12 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
35
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
39
|
exports.RedisPool = void 0;
|
|
40
|
+
const util_1 = __importDefault(require("util"));
|
|
37
41
|
const ioredis_1 = require("ioredis");
|
|
38
42
|
const genericPool = __importStar(require("generic-pool"));
|
|
39
43
|
const logHeader = '[RedisPooling]';
|
|
@@ -42,6 +46,29 @@ const DEFAULT_ACQUIRE_TIMEOUT = 10000;
|
|
|
42
46
|
const DEFAULT_MAX_POOLING_SIZE = 10;
|
|
43
47
|
const DEFAULT_MIN_POOLING_SIZE = 0;
|
|
44
48
|
const REDIS_PING_TIMEOUT_MS = 3000; // 3秒
|
|
49
|
+
/**
|
|
50
|
+
* loggerが渡されなかった場合のロガー
|
|
51
|
+
* 警告とエラーは呼び出し元が--no-warningsやprocess.on('warning')で抑止・捕捉できるようにprocess.emitWarningで出力する
|
|
52
|
+
*
|
|
53
|
+
* @param {boolean} debug trueの場合はdebug/infoもconsoleに出力する
|
|
54
|
+
* @returns {RedisPoolLogger}
|
|
55
|
+
*/
|
|
56
|
+
function createDefaultLogger(debug) {
|
|
57
|
+
return {
|
|
58
|
+
debug: (...args) => {
|
|
59
|
+
if (debug) {
|
|
60
|
+
console.debug(...args);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
info: (...args) => {
|
|
64
|
+
if (debug) {
|
|
65
|
+
console.info(...args);
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
warn: (...args) => process.emitWarning(util_1.default.format(...args)),
|
|
69
|
+
error: (...args) => process.emitWarning(util_1.default.format(...args))
|
|
70
|
+
};
|
|
71
|
+
}
|
|
45
72
|
class RedisPool {
|
|
46
73
|
url;
|
|
47
74
|
db;
|
|
@@ -53,7 +80,8 @@ class RedisPool {
|
|
|
53
80
|
tls;
|
|
54
81
|
pool;
|
|
55
82
|
initialized = false;
|
|
56
|
-
|
|
83
|
+
logger;
|
|
84
|
+
acquireLogLevel;
|
|
57
85
|
constructor(config, options) {
|
|
58
86
|
if (!config.url) {
|
|
59
87
|
throw new Error(`${logHeader} Redis connection url is required.`);
|
|
@@ -66,7 +94,8 @@ class RedisPool {
|
|
|
66
94
|
this.min = config.min ?? DEFAULT_MIN_POOLING_SIZE;
|
|
67
95
|
this.testOnBorrow = config.testOnBorrow ?? true;
|
|
68
96
|
this.tls = config.enableTls ? { rejectUnauthorized: false } : undefined;
|
|
69
|
-
this.
|
|
97
|
+
this.logger = options?.logger ?? createDefaultLogger(options?.debug ?? false);
|
|
98
|
+
this.acquireLogLevel = options?.acquireLogLevel ?? 'debug';
|
|
70
99
|
}
|
|
71
100
|
async acquire(dbIndex) {
|
|
72
101
|
if (!this.initialized) {
|
|
@@ -87,7 +116,7 @@ class RedisPool {
|
|
|
87
116
|
await pool.destroy(client);
|
|
88
117
|
throw error;
|
|
89
118
|
}
|
|
90
|
-
this.
|
|
119
|
+
this.acquireLog(logHeader, `Redis client ${index} has been acquired.`);
|
|
91
120
|
return client;
|
|
92
121
|
}
|
|
93
122
|
async release(client) {
|
|
@@ -97,11 +126,11 @@ class RedisPool {
|
|
|
97
126
|
if (client.status === 'end' || client.status === 'close') {
|
|
98
127
|
// 再利用できない状態のRedisクライアントはプールから破棄する
|
|
99
128
|
await this.pool.destroy(client);
|
|
100
|
-
this.
|
|
129
|
+
this.acquireLog(logHeader, 'Redis client destroyed due to invalid status.');
|
|
101
130
|
}
|
|
102
131
|
else {
|
|
103
132
|
await this.pool.release(client);
|
|
104
|
-
this.
|
|
133
|
+
this.acquireLog(logHeader, 'Redis client released.');
|
|
105
134
|
}
|
|
106
135
|
}
|
|
107
136
|
async destroy(timeoutMs = 5000) {
|
|
@@ -109,7 +138,7 @@ class RedisPool {
|
|
|
109
138
|
if (!pool) {
|
|
110
139
|
return;
|
|
111
140
|
}
|
|
112
|
-
this.
|
|
141
|
+
this.logger.info(logHeader, 'Destroying Redis pool...');
|
|
113
142
|
let timer;
|
|
114
143
|
try {
|
|
115
144
|
await Promise.race([
|
|
@@ -125,7 +154,7 @@ class RedisPool {
|
|
|
125
154
|
finally {
|
|
126
155
|
clearTimeout(timer);
|
|
127
156
|
}
|
|
128
|
-
this.
|
|
157
|
+
this.logger.info(logHeader, 'Redis pool destroyed.');
|
|
129
158
|
this.pool = undefined;
|
|
130
159
|
}
|
|
131
160
|
/**
|
|
@@ -175,28 +204,32 @@ class RedisPool {
|
|
|
175
204
|
});
|
|
176
205
|
}
|
|
177
206
|
async ping(client) {
|
|
207
|
+
let timer;
|
|
178
208
|
try {
|
|
179
|
-
this.
|
|
209
|
+
this.logger.debug(logHeader, 'start validate');
|
|
180
210
|
const timeout = new Promise((_, reject) => {
|
|
181
|
-
setTimeout(() => reject(new Error(`Redis PING timeout after ${REDIS_PING_TIMEOUT_MS}ms`)), REDIS_PING_TIMEOUT_MS);
|
|
211
|
+
timer = setTimeout(() => reject(new Error(`Redis PING timeout after ${REDIS_PING_TIMEOUT_MS}ms`)), REDIS_PING_TIMEOUT_MS);
|
|
182
212
|
});
|
|
183
213
|
await Promise.race([
|
|
184
214
|
client.ping(),
|
|
185
215
|
timeout
|
|
186
216
|
]);
|
|
187
|
-
this.
|
|
217
|
+
this.logger.debug(logHeader, 'ping succeeded');
|
|
188
218
|
return client.status === 'ready';
|
|
189
219
|
}
|
|
190
220
|
catch (error) {
|
|
191
|
-
|
|
221
|
+
// 検証に失敗した接続はプールから破棄される
|
|
222
|
+
this.logger.warn(logHeader, 'ping failed', error);
|
|
192
223
|
return false;
|
|
193
224
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
console.debug(...args);
|
|
225
|
+
finally {
|
|
226
|
+
// PINGが先に応答した場合もタイマーを残さない
|
|
227
|
+
clearTimeout(timer);
|
|
198
228
|
}
|
|
199
229
|
}
|
|
230
|
+
acquireLog(...args) {
|
|
231
|
+
this.logger[this.acquireLogLevel](...args);
|
|
232
|
+
}
|
|
200
233
|
getPool() {
|
|
201
234
|
if (!this.pool) {
|
|
202
235
|
this.pool = this.createPool();
|
|
@@ -215,18 +248,18 @@ class RedisPool {
|
|
|
215
248
|
retryStrategy: (times) => {
|
|
216
249
|
const delay = Math.min(times * 50, 1000);
|
|
217
250
|
if (process.env.NODE_ENV !== 'test') {
|
|
218
|
-
this.
|
|
251
|
+
this.logger.debug(logHeader, `retry strategy called ${times} times. delaying ${delay}ms`);
|
|
219
252
|
}
|
|
220
253
|
return delay;
|
|
221
254
|
},
|
|
222
255
|
reconnectOnError: (error) => {
|
|
223
|
-
|
|
256
|
+
this.logger.warn(logHeader, 'detected error (on reconnectOnError)', error);
|
|
224
257
|
// フェイルオーバー後にレプリカへ接続したままになっている場合だけ、再接続で解消できる
|
|
225
258
|
return error.message.startsWith('READONLY');
|
|
226
259
|
}
|
|
227
260
|
});
|
|
228
261
|
client.on('error', error => {
|
|
229
|
-
|
|
262
|
+
this.logger.error(logHeader, 'detected error (on error)', error);
|
|
230
263
|
});
|
|
231
264
|
// カスタムメソッド START
|
|
232
265
|
/**
|
|
@@ -324,11 +357,11 @@ class RedisPool {
|
|
|
324
357
|
destroy: async (client) => {
|
|
325
358
|
try {
|
|
326
359
|
await client.quit();
|
|
327
|
-
this.
|
|
360
|
+
this.logger.debug(logHeader, 'client quit');
|
|
328
361
|
}
|
|
329
362
|
catch (error) {
|
|
330
363
|
client.disconnect();
|
|
331
|
-
this.
|
|
364
|
+
this.logger.debug(logHeader, 'client disconnected');
|
|
332
365
|
}
|
|
333
366
|
},
|
|
334
367
|
validate: async (client) => {
|
package/lib/redis-pooling.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis-pooling.js","sourceRoot":"","sources":["../src/redis-pooling.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"redis-pooling.js","sourceRoot":"","sources":["../src/redis-pooling.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@digitalwalletcorp/redis-pooling",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "This is a library for redis connection pooling",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -47,6 +47,6 @@
|
|
|
47
47
|
"ts-jest": "^29.4.9",
|
|
48
48
|
"ts-node": "^10.9.2",
|
|
49
49
|
"tsconfig-paths": "^4.2.0",
|
|
50
|
-
"typescript": "
|
|
50
|
+
"typescript": "6.0.3"
|
|
51
51
|
}
|
|
52
52
|
}
|
package/src/redis-pooling.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import util from 'util';
|
|
1
2
|
import { Redis } from 'ioredis';
|
|
2
3
|
import * as genericPool from 'generic-pool';
|
|
3
4
|
|
|
@@ -12,8 +13,24 @@ export interface RedisConfig {
|
|
|
12
13
|
enableTls?: boolean;
|
|
13
14
|
}
|
|
14
15
|
|
|
16
|
+
/**
|
|
17
|
+
* ログの出力先
|
|
18
|
+
* 渡した場合、どのレベルを出力するかはこのロガーが決める
|
|
19
|
+
*/
|
|
20
|
+
export interface RedisPoolLogger {
|
|
21
|
+
debug(...args: any[]): void;
|
|
22
|
+
info(...args: any[]): void;
|
|
23
|
+
warn(...args: any[]): void;
|
|
24
|
+
error(...args: any[]): void;
|
|
25
|
+
}
|
|
26
|
+
|
|
15
27
|
export interface RedisPoolOptions {
|
|
28
|
+
/** ログの出力先。未指定の場合はconsole(debug/info)とprocess.emitWarning(warn/error)に出力する */
|
|
29
|
+
logger?: RedisPoolLogger;
|
|
30
|
+
/** loggerを渡さない場合のみ有効。trueの場合はdebug/infoも出力する */
|
|
16
31
|
debug?: boolean;
|
|
32
|
+
/** クライアントの貸出・返却ログを出力するレベル */
|
|
33
|
+
acquireLogLevel?: 'debug' | 'info';
|
|
17
34
|
}
|
|
18
35
|
|
|
19
36
|
export interface RedisClient extends Redis {
|
|
@@ -28,6 +45,30 @@ const DEFAULT_MAX_POOLING_SIZE = 10;
|
|
|
28
45
|
const DEFAULT_MIN_POOLING_SIZE = 0;
|
|
29
46
|
const REDIS_PING_TIMEOUT_MS = 3000; // 3秒
|
|
30
47
|
|
|
48
|
+
/**
|
|
49
|
+
* loggerが渡されなかった場合のロガー
|
|
50
|
+
* 警告とエラーは呼び出し元が--no-warningsやprocess.on('warning')で抑止・捕捉できるようにprocess.emitWarningで出力する
|
|
51
|
+
*
|
|
52
|
+
* @param {boolean} debug trueの場合はdebug/infoもconsoleに出力する
|
|
53
|
+
* @returns {RedisPoolLogger}
|
|
54
|
+
*/
|
|
55
|
+
function createDefaultLogger(debug: boolean): RedisPoolLogger {
|
|
56
|
+
return {
|
|
57
|
+
debug: (...args: any[]) => {
|
|
58
|
+
if (debug) {
|
|
59
|
+
console.debug(...args);
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
info: (...args: any[]) => {
|
|
63
|
+
if (debug) {
|
|
64
|
+
console.info(...args);
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
warn: (...args: any[]) => process.emitWarning(util.format(...args)),
|
|
68
|
+
error: (...args: any[]) => process.emitWarning(util.format(...args))
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
31
72
|
export class RedisPool {
|
|
32
73
|
|
|
33
74
|
private readonly url: string;
|
|
@@ -41,7 +82,8 @@ export class RedisPool {
|
|
|
41
82
|
|
|
42
83
|
private pool?: genericPool.Pool<RedisClient>;
|
|
43
84
|
private initialized = false;
|
|
44
|
-
private readonly
|
|
85
|
+
private readonly logger: RedisPoolLogger;
|
|
86
|
+
private readonly acquireLogLevel: 'debug' | 'info';
|
|
45
87
|
|
|
46
88
|
constructor(config: RedisConfig, options?: RedisPoolOptions) {
|
|
47
89
|
if (!config.url) {
|
|
@@ -57,7 +99,8 @@ export class RedisPool {
|
|
|
57
99
|
this.testOnBorrow = config.testOnBorrow ?? true;
|
|
58
100
|
this.tls = config.enableTls ? { rejectUnauthorized: false } : undefined;
|
|
59
101
|
|
|
60
|
-
this.
|
|
102
|
+
this.logger = options?.logger ?? createDefaultLogger(options?.debug ?? false);
|
|
103
|
+
this.acquireLogLevel = options?.acquireLogLevel ?? 'debug';
|
|
61
104
|
}
|
|
62
105
|
|
|
63
106
|
public async acquire(dbIndex?: number): Promise<RedisClient> {
|
|
@@ -79,7 +122,7 @@ export class RedisPool {
|
|
|
79
122
|
await pool.destroy(client);
|
|
80
123
|
throw error;
|
|
81
124
|
}
|
|
82
|
-
this.
|
|
125
|
+
this.acquireLog(logHeader, `Redis client ${index} has been acquired.`);
|
|
83
126
|
return client;
|
|
84
127
|
}
|
|
85
128
|
|
|
@@ -90,10 +133,10 @@ export class RedisPool {
|
|
|
90
133
|
if (client.status === 'end' || client.status === 'close') {
|
|
91
134
|
// 再利用できない状態のRedisクライアントはプールから破棄する
|
|
92
135
|
await this.pool.destroy(client);
|
|
93
|
-
this.
|
|
136
|
+
this.acquireLog(logHeader, 'Redis client destroyed due to invalid status.');
|
|
94
137
|
} else {
|
|
95
138
|
await this.pool.release(client);
|
|
96
|
-
this.
|
|
139
|
+
this.acquireLog(logHeader, 'Redis client released.');
|
|
97
140
|
}
|
|
98
141
|
}
|
|
99
142
|
|
|
@@ -102,7 +145,7 @@ export class RedisPool {
|
|
|
102
145
|
if (!pool) {
|
|
103
146
|
return;
|
|
104
147
|
}
|
|
105
|
-
this.
|
|
148
|
+
this.logger.info(logHeader, 'Destroying Redis pool...');
|
|
106
149
|
let timer: NodeJS.Timeout | undefined;
|
|
107
150
|
try {
|
|
108
151
|
await Promise.race([
|
|
@@ -117,7 +160,7 @@ export class RedisPool {
|
|
|
117
160
|
} finally {
|
|
118
161
|
clearTimeout(timer);
|
|
119
162
|
}
|
|
120
|
-
this.
|
|
163
|
+
this.logger.info(logHeader, 'Redis pool destroyed.');
|
|
121
164
|
this.pool = undefined;
|
|
122
165
|
}
|
|
123
166
|
|
|
@@ -170,27 +213,30 @@ export class RedisPool {
|
|
|
170
213
|
}
|
|
171
214
|
|
|
172
215
|
private async ping(client: Redis): Promise<boolean> {
|
|
216
|
+
let timer: NodeJS.Timeout | undefined;
|
|
173
217
|
try {
|
|
174
|
-
this.
|
|
218
|
+
this.logger.debug(logHeader, 'start validate');
|
|
175
219
|
const timeout = new Promise<void>((_, reject) => {
|
|
176
|
-
setTimeout(() => reject(new Error(`Redis PING timeout after ${REDIS_PING_TIMEOUT_MS}ms`)), REDIS_PING_TIMEOUT_MS);
|
|
220
|
+
timer = setTimeout(() => reject(new Error(`Redis PING timeout after ${REDIS_PING_TIMEOUT_MS}ms`)), REDIS_PING_TIMEOUT_MS);
|
|
177
221
|
});
|
|
178
222
|
await Promise.race([
|
|
179
223
|
client.ping(),
|
|
180
224
|
timeout
|
|
181
225
|
]);
|
|
182
|
-
this.
|
|
226
|
+
this.logger.debug(logHeader, 'ping succeeded');
|
|
183
227
|
return client.status === 'ready';
|
|
184
228
|
} catch (error: any) {
|
|
185
|
-
|
|
229
|
+
// 検証に失敗した接続はプールから破棄される
|
|
230
|
+
this.logger.warn(logHeader, 'ping failed', error);
|
|
186
231
|
return false;
|
|
232
|
+
} finally {
|
|
233
|
+
// PINGが先に応答した場合もタイマーを残さない
|
|
234
|
+
clearTimeout(timer);
|
|
187
235
|
}
|
|
188
236
|
}
|
|
189
237
|
|
|
190
|
-
private
|
|
191
|
-
|
|
192
|
-
console.debug(...args);
|
|
193
|
-
}
|
|
238
|
+
private acquireLog(...args: any[]): void {
|
|
239
|
+
this.logger[this.acquireLogLevel](...args);
|
|
194
240
|
}
|
|
195
241
|
|
|
196
242
|
private getPool(): genericPool.Pool<RedisClient> {
|
|
@@ -212,18 +258,18 @@ export class RedisPool {
|
|
|
212
258
|
retryStrategy: (times) => {
|
|
213
259
|
const delay = Math.min(times * 50, 1000);
|
|
214
260
|
if (process.env.NODE_ENV !== 'test') {
|
|
215
|
-
this.
|
|
261
|
+
this.logger.debug(logHeader, `retry strategy called ${times} times. delaying ${delay}ms`);
|
|
216
262
|
}
|
|
217
263
|
return delay;
|
|
218
264
|
},
|
|
219
265
|
reconnectOnError: (error) => {
|
|
220
|
-
|
|
266
|
+
this.logger.warn(logHeader, 'detected error (on reconnectOnError)', error);
|
|
221
267
|
// フェイルオーバー後にレプリカへ接続したままになっている場合だけ、再接続で解消できる
|
|
222
268
|
return error.message.startsWith('READONLY');
|
|
223
269
|
}
|
|
224
270
|
}) as RedisClient;
|
|
225
271
|
client.on('error', error => {
|
|
226
|
-
|
|
272
|
+
this.logger.error(logHeader, 'detected error (on error)', error);
|
|
227
273
|
});
|
|
228
274
|
|
|
229
275
|
// カスタムメソッド START
|
|
@@ -324,10 +370,10 @@ export class RedisPool {
|
|
|
324
370
|
destroy: async (client: Redis) => {
|
|
325
371
|
try {
|
|
326
372
|
await client.quit();
|
|
327
|
-
this.
|
|
373
|
+
this.logger.debug(logHeader, 'client quit');
|
|
328
374
|
} catch (error) {
|
|
329
375
|
client.disconnect();
|
|
330
|
-
this.
|
|
376
|
+
this.logger.debug(logHeader, 'client disconnected');
|
|
331
377
|
}
|
|
332
378
|
},
|
|
333
379
|
validate: async (client: Redis) => {
|