@digitalwalletcorp/redis-pooling 1.1.0 → 1.1.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 CHANGED
@@ -101,8 +101,10 @@ async function manageCache() {
101
101
  console.log('Matching keys:', keys);
102
102
 
103
103
  // Delete all matching keys using UNLINK
104
- const deleted = await client.deleteKeys('cache:*');
105
- console.log(`Deleted ${deleted} keys`);
104
+ const delResults = await client.deleteKeys('cache:*');
105
+ const succeeded = delResults.filter(a => a.status === 'fulfilled');
106
+ const delCount = succeeded.reduce((acc, cur) => acc + (cur as PromiseFulfilledResult<number>).value, 0);
107
+ console.log(`Deleted ${delCount} keys`);
106
108
  } finally {
107
109
  await redisPool.release(client);
108
110
  }
@@ -140,7 +142,7 @@ Extends the standard `ioredis` `Redis` client with additional helpers:
140
142
  | Method | Signature | Description |
141
143
  | ----------------------------- | ------------------- | ----------------------------------------------------------------------------------------------- |
142
144
  | `getKeys(pattern: string)` | `Promise<string[]>` | Scan and return all keys matching a pattern. |
143
- | `deleteKeys(pattern: string)` | `Promise<number>` | Scan and delete all keys matching a pattern using `UNLINK`. Returns the number of deleted keys. |
145
+ | `deleteKeys(pattern: string)` | `Promise<PromiseSettledResult<number>[]>` | Scan and delete all keys matching a pattern using `UNLINK`. Returns an array of results, one for each batch processed by `UNLINK`. Each result contains the number of keys deleted in that batch. |
144
146
 
145
147
  #### 🗄 Database Index Handling
146
148
 
@@ -10,7 +10,7 @@ export interface RedisConfig {
10
10
  }
11
11
  export interface RedisClient extends Redis {
12
12
  getKeys(pattern: string): Promise<string[]>;
13
- deleteKeys(pattern: string): Promise<number>;
13
+ deleteKeys(pattern: string): Promise<PromiseSettledResult<number>[]>;
14
14
  _originalDbIndex?: number;
15
15
  }
16
16
  export declare class RedisPool {
@@ -20,12 +20,24 @@ export declare class RedisPool {
20
20
  private readonly max;
21
21
  private readonly min;
22
22
  private readonly testOnBorrow;
23
- private readonly enableTls?;
23
+ private readonly tls?;
24
24
  private readonly poolMap;
25
- constructor(config: RedisConfig);
25
+ private initialized;
26
+ private readonly debug;
27
+ constructor(config: RedisConfig, options?: {
28
+ debug?: boolean;
29
+ });
26
30
  acquire(dbIndex?: number): Promise<RedisClient>;
27
31
  release(client?: RedisClient): Promise<void>;
28
32
  destroy(timeoutMs?: number): Promise<void>;
33
+ /**
34
+ * 初めてacquireが呼ばれた時に、指定された接続情報で接続できるかチェックする
35
+ *
36
+ * @param {number} dbIndex
37
+ */
38
+ private checkConnectivity;
39
+ private ping;
40
+ debugLog(...args: any[]): void;
29
41
  private getPool;
30
42
  private createSingleDbPool;
31
43
  }
@@ -48,9 +48,11 @@ class RedisPool {
48
48
  max;
49
49
  min;
50
50
  testOnBorrow;
51
- enableTls;
51
+ tls;
52
52
  poolMap = new Map();
53
- constructor(config) {
53
+ initialized = false;
54
+ debug;
55
+ constructor(config, options) {
54
56
  if (!config.url) {
55
57
  throw new Error(`${logHeader} Redis connection url is required.`);
56
58
  }
@@ -60,14 +62,27 @@ class RedisPool {
60
62
  this.max = config.max ?? DEFAULT_MAX_POOLING_SIZE;
61
63
  this.min = config.min ?? DEFAULT_MIN_POOLING_SIZE;
62
64
  this.testOnBorrow = config.testOnBorrow ?? true;
63
- this.enableTls = config.enableTls;
65
+ this.tls = config.enableTls ? { rejectUnauthorized: false } : undefined;
66
+ this.debug = options?.debug ?? false;
64
67
  }
65
68
  async acquire(dbIndex) {
69
+ if (!this.initialized) {
70
+ // 初回acquire呼び出し時のみ接続チェックを行う
71
+ // ホスト不正やパスワード不正による接続不可等を検知する
72
+ // ※ generic-poolのfactoryの方に入ってしまうとエラーを呼び出し元に伝播させることが難しいため、プールとは別の接続でチェックする
73
+ await this.checkConnectivity(dbIndex ?? this.db);
74
+ this.initialized = true;
75
+ }
66
76
  const index = dbIndex ?? this.db;
67
77
  const pool = this.getPool(index);
68
- const client = await pool.acquire();
69
- console.debug(logHeader, `Redis client ${index} has been acquired.`);
70
- return client;
78
+ try {
79
+ const client = await pool.acquire();
80
+ this.debugLog(logHeader, `Redis client ${index} has been acquired.`);
81
+ return client;
82
+ }
83
+ catch (error) {
84
+ throw error;
85
+ }
71
86
  }
72
87
  async release(client) {
73
88
  if (client) {
@@ -98,18 +113,18 @@ class RedisPool {
98
113
  if (needDestroy) {
99
114
  // Redisクライアントの破棄
100
115
  await pool.destroy(client);
101
- console.debug(logHeader, `Redis client ${dbIndex} destroyed due to invalid status.`);
116
+ this.debugLog(logHeader, `Redis client ${dbIndex} destroyed due to invalid status.`);
102
117
  }
103
118
  else {
104
119
  // Redisクライアントの返却
105
120
  await pool.release(client);
106
- console.debug(logHeader, `Redis client ${dbIndex} released.`);
121
+ this.debugLog(logHeader, `Redis client ${dbIndex} released.`);
107
122
  }
108
123
  }
109
124
  }
110
125
  async destroy(timeoutMs = 5000) {
111
126
  for (const [dbIndex, pool] of this.poolMap.entries()) {
112
- console.debug(logHeader, `Destroying Redis pool for DB index ${dbIndex}...`);
127
+ this.debugLog(logHeader, `Destroying Redis pool for DB index ${dbIndex}...`);
113
128
  await Promise.race([
114
129
  (async () => {
115
130
  await pool.drain();
@@ -119,10 +134,60 @@ class RedisPool {
119
134
  setTimeout(() => reject(new Error(`${logHeader} Timeout while draining Redis pool for DB index ${dbIndex}`)), timeoutMs);
120
135
  })
121
136
  ]);
122
- console.debug(logHeader, `Redis pool for DB index ${dbIndex} destroyed.`);
137
+ this.debugLog(logHeader, `Redis pool for DB index ${dbIndex} destroyed.`);
123
138
  this.poolMap.delete(dbIndex);
124
139
  }
125
140
  }
141
+ /**
142
+ * 初めてacquireが呼ばれた時に、指定された接続情報で接続できるかチェックする
143
+ *
144
+ * @param {number} dbIndex
145
+ */
146
+ async checkConnectivity(dbIndex) {
147
+ const client = new ioredis_1.Redis(this.url, {
148
+ db: dbIndex,
149
+ retryStrategy: () => null, // 再接続無効
150
+ reconnectOnError: () => false, // 再接続無効
151
+ connectTimeout: this.connectTimeout,
152
+ tls: this.tls,
153
+ });
154
+ return new Promise((resolve, reject) => {
155
+ const cleanup = () => {
156
+ client.quit().catch(() => client.disconnect());
157
+ };
158
+ client.once('ready', () => {
159
+ cleanup();
160
+ resolve();
161
+ });
162
+ client.once('error', (error) => {
163
+ cleanup();
164
+ reject(error);
165
+ });
166
+ });
167
+ }
168
+ async ping(client) {
169
+ try {
170
+ this.debugLog(logHeader, 'start validate');
171
+ const timeout = new Promise((_, reject) => {
172
+ setTimeout(() => reject(new Error(`Redis PING timeout after ${REDIS_PING_TIMEOUT_MS}ms`)), REDIS_PING_TIMEOUT_MS);
173
+ });
174
+ await Promise.race([
175
+ client.ping(),
176
+ timeout
177
+ ]);
178
+ this.debugLog(logHeader, 'ping succeeded');
179
+ return client.status === 'ready';
180
+ }
181
+ catch (error) {
182
+ this.debugLog(logHeader, 'ping failed');
183
+ return false;
184
+ }
185
+ }
186
+ debugLog(...args) {
187
+ if (this.debug) {
188
+ console.debug(...args);
189
+ }
190
+ }
126
191
  getPool(dbIndex) {
127
192
  let pool = this.poolMap.get(dbIndex);
128
193
  if (!pool) {
@@ -134,35 +199,30 @@ class RedisPool {
134
199
  createSingleDbPool(dbIndex) {
135
200
  const factory = {
136
201
  create: async () => {
137
- let client;
138
- try {
139
- client = new ioredis_1.Redis(this.url, {
140
- db: dbIndex,
141
- connectTimeout: this.connectTimeout,
142
- keepAlive: 1,
143
- enableOfflineQueue: true,
144
- tls: this.enableTls ? { rejectUnauthorized: false } : undefined,
145
- retryStrategy: (times) => {
146
- const delay = Math.min(times * 50, 1000);
147
- if (process.env.NODE_ENV !== 'test') {
148
- console.debug(logHeader, `retry strategy called ${times} times. delaying ${delay}ms`);
149
- }
150
- return delay;
151
- },
152
- reconnectOnError: (error) => {
153
- process.emitWarning(`${logHeader} detected error (on reconnect). ${error.message}`);
154
- return true;
202
+ const client = new ioredis_1.Redis(this.url, {
203
+ db: dbIndex,
204
+ connectTimeout: this.connectTimeout,
205
+ keepAlive: 1,
206
+ enableOfflineQueue: true,
207
+ tls: this.tls,
208
+ retryStrategy: (times) => {
209
+ const delay = Math.min(times * 50, 1000);
210
+ if (process.env.NODE_ENV !== 'test') {
211
+ this.debugLog(logHeader, `retry strategy called ${times} times. delaying ${delay}ms`);
155
212
  }
156
- });
157
- }
158
- catch (error) {
159
- console.error(error);
160
- throw error;
161
- }
213
+ return delay;
214
+ },
215
+ reconnectOnError: (error) => {
216
+ process.emitWarning(`${logHeader} detected error (on reconnectOnError). ${error.message}`);
217
+ return true;
218
+ }
219
+ });
162
220
  client._originalDbIndex = dbIndex;
163
221
  client.on('error', error => {
164
222
  process.emitWarning(`${logHeader} detected error (on error). ${error.message}`);
165
223
  });
224
+ // カスタムメソッド内の処理でthis.debugLogなどが参照できなくなるため、poolのインスタンスを変数キャプチャする
225
+ const poolInstance = this;
166
226
  // カスタムメソッド START
167
227
  /**
168
228
  * 指定されたパターンに一致するキーを Redis から全て取得する
@@ -184,19 +244,29 @@ class RedisPool {
184
244
  });
185
245
  stream.on('end', () => resolve(allKeys));
186
246
  stream.on('error', (err) => {
187
- console.error(logHeader, `Error during getKeys scan for pattern '${pattern}'.`, err);
188
247
  reject(err);
189
248
  });
190
249
  });
191
250
  };
192
251
  /**
193
252
  * 指定されたパターンに一致するキーを Redis から全て削除する (UNLINKを使用)
253
+ * 返却値の配列サイズはscanStreamが'data'を受信した回数で、この受信したデータで削除された件数がvalueに設定されている。
254
+ *
255
+ * [
256
+ * { status: 'fulfilled', value: 100 }, // 1バッチ目で100件削除
257
+ * { status: 'fulfilled', value: 80 } // 2バッチ目で80件削除
258
+ * ]
259
+ *
260
+ * 成功した件数は以下のようにして取得可能
261
+ *
262
+ * const delResults = await redisClient.deleteKeys('pattern');
263
+ * const delCount = delResults.filter(a => a.status === 'fulfilled')
264
+ * .reduce((acc, cur) => acc + (cur as PromiseFulfilledResult<number>).value, 0);
194
265
  *
195
266
  * @param {string} pattern
196
- * @returns {Promise<number>}
267
+ * @returns {Promise<PromiseSettledResult<number>>}
197
268
  */
198
269
  client.deleteKeys = async function (pattern) {
199
- let deletedCount = 0;
200
270
  const stream = this.scanStream({
201
271
  match: pattern,
202
272
  count: 1000 // 1度にスキャンする件数
@@ -206,24 +276,17 @@ class RedisPool {
206
276
  stream.on('data', async (keys) => {
207
277
  if (keys.length) {
208
278
  tasks.push((async () => {
209
- try {
210
- // UNLINK を使用し、現在のインスタンス (this) で実行
211
- const unlinkResult = await this.unlink(...keys);
212
- deletedCount += unlinkResult;
213
- console.debug(logHeader, `Deleted ${unlinkResult} keys in a batch for pattern '${pattern}'. Total: ${deletedCount}`);
214
- }
215
- catch (error) {
216
- process.emitWarning(`${logHeader} Error during UNLINK for pattern '${pattern}'. ${error.message}`);
217
- }
279
+ // UNLINK を使用し、現在のインスタンス (this) で実行
280
+ const unlinkResult = await this.unlink(...keys);
281
+ return unlinkResult;
218
282
  })());
219
283
  }
220
284
  });
221
285
  stream.on('end', async () => {
222
- await Promise.all(tasks);
223
- resolve(deletedCount);
286
+ const results = await Promise.allSettled(tasks);
287
+ resolve(results);
224
288
  });
225
289
  stream.on('error', (err) => {
226
- console.error(logHeader, `Error during deleteKeys scan for pattern '${pattern}'.`, err);
227
290
  reject(err);
228
291
  });
229
292
  });
@@ -252,30 +315,15 @@ class RedisPool {
252
315
  destroy: async (client) => {
253
316
  try {
254
317
  await client.quit();
255
- console.debug(logHeader, 'client quit');
318
+ this.debugLog(logHeader, 'client quit');
256
319
  }
257
320
  catch (error) {
258
321
  client.disconnect();
259
- console.debug(logHeader, 'client disconnected');
322
+ this.debugLog(logHeader, 'client disconnected');
260
323
  }
261
324
  },
262
325
  validate: async (client) => {
263
- try {
264
- console.debug(logHeader, 'start validate');
265
- const timeout = new Promise((_, reject) => {
266
- setTimeout(() => reject(new Error(`Redis PING timeout after ${REDIS_PING_TIMEOUT_MS}ms`)), REDIS_PING_TIMEOUT_MS);
267
- });
268
- await Promise.race([
269
- client.ping(),
270
- timeout
271
- ]);
272
- console.debug(logHeader, 'ping succeeded');
273
- return client.status === 'ready';
274
- }
275
- catch (error) {
276
- console.debug(logHeader, 'ping failed');
277
- return false;
278
- }
326
+ return await this.ping(client);
279
327
  }
280
328
  };
281
329
  return genericPool.createPool(factory, {
@@ -1 +1 @@
1
- {"version":3,"file":"redis-pooling.js","sourceRoot":"","sources":["../src/redis-pooling.ts"],"names":[],"mappings":"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"}
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.1.0",
3
+ "version": "1.1.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",
@@ -13,7 +13,7 @@ export interface RedisConfig {
13
13
 
14
14
  export interface RedisClient extends Redis {
15
15
  getKeys(pattern: string): Promise<string[]>;
16
- deleteKeys(pattern: string): Promise<number>;
16
+ deleteKeys(pattern: string): Promise<PromiseSettledResult<number>[]>;
17
17
  _originalDbIndex?: number; // 内部状態管理用変数
18
18
  }
19
19
 
@@ -31,11 +31,15 @@ export class RedisPool {
31
31
  private readonly max: number;
32
32
  private readonly min: number;
33
33
  private readonly testOnBorrow: boolean;
34
- private readonly enableTls?: boolean;
34
+ private readonly tls?: { rejectUnauthorized: false };
35
35
 
36
36
  private readonly poolMap = new Map<number, genericPool.Pool<RedisClient>>();
37
+ private initialized = false;
38
+ private readonly debug: boolean;
37
39
 
38
- constructor(config: RedisConfig) {
40
+ constructor(config: RedisConfig, options?: {
41
+ debug?: boolean;
42
+ }) {
39
43
  if (!config.url) {
40
44
  throw new Error(`${logHeader} Redis connection url is required.`);
41
45
  }
@@ -46,16 +50,30 @@ export class RedisPool {
46
50
  this.max = config.max ?? DEFAULT_MAX_POOLING_SIZE;
47
51
  this.min = config.min ?? DEFAULT_MIN_POOLING_SIZE;
48
52
  this.testOnBorrow = config.testOnBorrow ?? true;
49
- this.enableTls = config.enableTls;
53
+ this.tls = config.enableTls ? { rejectUnauthorized: false } : undefined;
54
+
55
+ this.debug = options?.debug ?? false;
50
56
  }
51
57
 
52
58
  public async acquire(dbIndex?: number): Promise<RedisClient> {
59
+ if (!this.initialized) {
60
+ // 初回acquire呼び出し時のみ接続チェックを行う
61
+ // ホスト不正やパスワード不正による接続不可等を検知する
62
+ // ※ generic-poolのfactoryの方に入ってしまうとエラーを呼び出し元に伝播させることが難しいため、プールとは別の接続でチェックする
63
+ await this.checkConnectivity(dbIndex ?? this.db);
64
+ this.initialized = true;
65
+ }
66
+
53
67
  const index = dbIndex ?? this.db;
54
68
  const pool = this.getPool(index);
55
- const client = await pool.acquire();
69
+ try {
70
+ const client = await pool.acquire();
56
71
 
57
- console.debug(logHeader, `Redis client ${index} has been acquired.`);
58
- return client;
72
+ this.debugLog(logHeader, `Redis client ${index} has been acquired.`);
73
+ return client;
74
+ } catch (error) {
75
+ throw error;
76
+ }
59
77
  }
60
78
 
61
79
  public async release(client?: RedisClient): Promise<void> {
@@ -86,18 +104,18 @@ export class RedisPool {
86
104
  if (needDestroy) {
87
105
  // Redisクライアントの破棄
88
106
  await pool.destroy(client);
89
- console.debug(logHeader, `Redis client ${dbIndex} destroyed due to invalid status.`);
107
+ this.debugLog(logHeader, `Redis client ${dbIndex} destroyed due to invalid status.`);
90
108
  } else {
91
109
  // Redisクライアントの返却
92
110
  await pool.release(client);
93
- console.debug(logHeader, `Redis client ${dbIndex} released.`);
111
+ this.debugLog(logHeader, `Redis client ${dbIndex} released.`);
94
112
  }
95
113
  }
96
114
  }
97
115
 
98
116
  public async destroy(timeoutMs = 5000): Promise<void> {
99
117
  for (const [dbIndex, pool] of this.poolMap.entries()) {
100
- console.debug(logHeader, `Destroying Redis pool for DB index ${dbIndex}...`);
118
+ this.debugLog(logHeader, `Destroying Redis pool for DB index ${dbIndex}...`);
101
119
  await Promise.race([
102
120
  (async () => {
103
121
  await pool.drain();
@@ -107,11 +125,66 @@ export class RedisPool {
107
125
  setTimeout(() => reject(new Error(`${logHeader} Timeout while draining Redis pool for DB index ${dbIndex}`)), timeoutMs);
108
126
  })
109
127
  ]);
110
- console.debug(logHeader, `Redis pool for DB index ${dbIndex} destroyed.`);
128
+ this.debugLog(logHeader, `Redis pool for DB index ${dbIndex} destroyed.`);
111
129
  this.poolMap.delete(dbIndex);
112
130
  }
113
131
  }
114
132
 
133
+ /**
134
+ * 初めてacquireが呼ばれた時に、指定された接続情報で接続できるかチェックする
135
+ *
136
+ * @param {number} dbIndex
137
+ */
138
+ private async checkConnectivity(dbIndex: number): Promise<void> {
139
+ const client = new Redis(this.url, {
140
+ db: dbIndex,
141
+ retryStrategy: () => null, // 再接続無効
142
+ reconnectOnError: () => false, // 再接続無効
143
+ connectTimeout: this.connectTimeout,
144
+ tls: this.tls,
145
+ });
146
+
147
+ return new Promise<void>((resolve, reject) => {
148
+ const cleanup = () => {
149
+ client.quit().catch(() => client.disconnect());
150
+ };
151
+
152
+ client.once('ready', () => {
153
+ cleanup();
154
+ resolve();
155
+ });
156
+
157
+ client.once('error', (error) => {
158
+ cleanup();
159
+ reject(error);
160
+ });
161
+ });
162
+ }
163
+
164
+ private async ping(client: Redis): Promise<boolean> {
165
+ try {
166
+ this.debugLog(logHeader, 'start validate');
167
+ const timeout = new Promise<void>((_, reject) => {
168
+ setTimeout(() => reject(new Error(`Redis PING timeout after ${REDIS_PING_TIMEOUT_MS}ms`)), REDIS_PING_TIMEOUT_MS);
169
+ });
170
+ await Promise.race([
171
+ client.ping(),
172
+ timeout
173
+ ]);
174
+ this.debugLog(logHeader, 'ping succeeded');
175
+ return client.status === 'ready';
176
+ } catch (error: any) {
177
+ this.debugLog(logHeader, 'ping failed');
178
+ return false;
179
+ }
180
+ }
181
+
182
+ public debugLog(...args: any[]): void {
183
+ if (this.debug) {
184
+ console.debug(...args);
185
+ }
186
+ }
187
+
115
188
  private getPool(dbIndex: number): genericPool.Pool<RedisClient> {
116
189
  let pool = this.poolMap.get(dbIndex);
117
190
  if (!pool) {
@@ -124,36 +197,33 @@ export class RedisPool {
124
197
  private createSingleDbPool(dbIndex: number): genericPool.Pool<RedisClient> {
125
198
  const factory: genericPool.Factory<RedisClient> = {
126
199
  create: async (): Promise<RedisClient> => {
127
- let client;
128
- try {
129
- client = new Redis(this.url, {
130
- db: dbIndex,
131
- connectTimeout: this.connectTimeout,
132
- keepAlive: 1,
133
- enableOfflineQueue: true,
134
- tls: this.enableTls ? { rejectUnauthorized: false } : undefined,
135
- retryStrategy: (times) => {
136
- const delay = Math.min(times * 50, 1000);
137
- if (process.env.NODE_ENV !== 'test') {
138
- console.debug(logHeader, `retry strategy called ${times} times. delaying ${delay}ms`);
139
- }
140
- return delay;
141
- },
142
- reconnectOnError: (error) => {
143
- process.emitWarning(`${logHeader} detected error (on reconnect). ${error.message}`);
144
- return true;
200
+ const client = new Redis(this.url, {
201
+ db: dbIndex,
202
+ connectTimeout: this.connectTimeout,
203
+ keepAlive: 1,
204
+ enableOfflineQueue: true,
205
+ tls: this.tls,
206
+ retryStrategy: (times) => {
207
+ const delay = Math.min(times * 50, 1000);
208
+ if (process.env.NODE_ENV !== 'test') {
209
+ this.debugLog(logHeader, `retry strategy called ${times} times. delaying ${delay}ms`);
145
210
  }
146
- }) as RedisClient;
147
- } catch (error) {
148
- console.error(error);
149
- throw error;
150
- }
211
+ return delay;
212
+ },
213
+ reconnectOnError: (error) => {
214
+ process.emitWarning(`${logHeader} detected error (on reconnectOnError). ${error.message}`);
215
+ return true;
216
+ }
217
+ }) as RedisClient;
151
218
 
152
219
  client._originalDbIndex = dbIndex;
153
220
  client.on('error', error => {
154
221
  process.emitWarning(`${logHeader} detected error (on error). ${error.message}`);
155
222
  });
156
223
 
224
+ // カスタムメソッド内の処理でthis.debugLogなどが参照できなくなるため、poolのインスタンスを変数キャプチャする
225
+ const poolInstance = this;
226
+
157
227
  // カスタムメソッド START
158
228
 
159
229
  /**
@@ -177,46 +247,50 @@ export class RedisPool {
177
247
  });
178
248
  stream.on('end', () => resolve(allKeys));
179
249
  stream.on('error', (err: Error) => {
180
- console.error(logHeader, `Error during getKeys scan for pattern '${pattern}'.`, err);
181
250
  reject(err);
182
251
  });
183
252
  });
184
253
  };
185
254
  /**
186
255
  * 指定されたパターンに一致するキーを Redis から全て削除する (UNLINKを使用)
256
+ * 返却値の配列サイズはscanStreamが'data'を受信した回数で、この受信したデータで削除された件数がvalueに設定されている。
257
+ *
258
+ * [
259
+ * { status: 'fulfilled', value: 100 }, // 1バッチ目で100件削除
260
+ * { status: 'fulfilled', value: 80 } // 2バッチ目で80件削除
261
+ * ]
262
+ *
263
+ * 成功した件数は以下のようにして取得可能
264
+ *
265
+ * const delResults = await redisClient.deleteKeys('pattern');
266
+ * const delCount = delResults.filter(a => a.status === 'fulfilled')
267
+ * .reduce((acc, cur) => acc + (cur as PromiseFulfilledResult<number>).value, 0);
187
268
  *
188
269
  * @param {string} pattern
189
- * @returns {Promise<number>}
270
+ * @returns {Promise<PromiseSettledResult<number>>}
190
271
  */
191
- client.deleteKeys = async function(pattern: string): Promise<number> {
192
- let deletedCount = 0;
272
+ client.deleteKeys = async function(pattern: string): Promise<PromiseSettledResult<number>[]> {
193
273
  const stream = this.scanStream({
194
274
  match: pattern,
195
275
  count: 1000 // 1度にスキャンする件数
196
276
  });
197
277
 
198
278
  return new Promise((resolve, reject) => {
199
- const tasks: Promise<void>[] = [];
279
+ const tasks: Promise<number>[] = [];
200
280
  stream.on('data', async (keys: string[]) => {
201
281
  if (keys.length) {
202
282
  tasks.push((async () => {
203
- try {
204
- // UNLINK を使用し、現在のインスタンス (this) で実行
205
- const unlinkResult = await this.unlink(...keys);
206
- deletedCount += unlinkResult;
207
- console.debug(logHeader, `Deleted ${unlinkResult} keys in a batch for pattern '${pattern}'. Total: ${deletedCount}`);
208
- } catch (error: any) {
209
- process.emitWarning(`${logHeader} Error during UNLINK for pattern '${pattern}'. ${error.message}`);
210
- }
283
+ // UNLINK を使用し、現在のインスタンス (this) で実行
284
+ const unlinkResult = await this.unlink(...keys);
285
+ return unlinkResult;
211
286
  })());
212
287
  }
213
288
  });
214
289
  stream.on('end', async () => {
215
- await Promise.all(tasks);
216
- resolve(deletedCount);
290
+ const results = await Promise.allSettled(tasks);
291
+ resolve(results);
217
292
  });
218
293
  stream.on('error', (err: Error) => {
219
- console.error(logHeader, `Error during deleteKeys scan for pattern '${pattern}'.`, err);
220
294
  reject(err);
221
295
  });
222
296
  });
@@ -247,28 +321,14 @@ export class RedisPool {
247
321
  destroy: async (client: Redis) => {
248
322
  try {
249
323
  await client.quit();
250
- console.debug(logHeader, 'client quit');
324
+ this.debugLog(logHeader, 'client quit');
251
325
  } catch (error) {
252
326
  client.disconnect();
253
- console.debug(logHeader, 'client disconnected');
327
+ this.debugLog(logHeader, 'client disconnected');
254
328
  }
255
329
  },
256
330
  validate: async (client: Redis) => {
257
- try {
258
- console.debug(logHeader, 'start validate');
259
- const timeout = new Promise<void>((_, reject) => {
260
- setTimeout(() => reject(new Error(`Redis PING timeout after ${REDIS_PING_TIMEOUT_MS}ms`)), REDIS_PING_TIMEOUT_MS);
261
- });
262
- await Promise.race([
263
- client.ping(),
264
- timeout
265
- ]);
266
- console.debug(logHeader, 'ping succeeded');
267
- return client.status === 'ready';
268
- } catch (error) {
269
- console.debug(logHeader, 'ping failed');
270
- return false;
271
- }
331
+ return await this.ping(client);
272
332
  }
273
333
  };
274
334