@samet-it/be-redis-common 1.1.9 → 1.3.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.
@@ -1,8 +1,8 @@
1
- import type { RedisConnectionLike, RedisExecOpt } from "../connection";
2
- import type { CacheChannelProps, CacheChannelLike, CacheChannelOpt } from "@samet-it/be-cache-common";
3
- import type { Entity } from "@samet-it/be-base-common";
4
- import type { RedisClientType } from "redis";
5
- import type { KeyValue } from "@leyyo/common";
1
+ import { RedisConnectionLike } from "../connection";
2
+ import { CacheChannelLike, CacheChannelOpt, CacheChannelProps, CacheExecOpt } from "@samet-it/be-cache-common";
3
+ import { Entity } from "@samet-it/be-base-common";
4
+ import { RedisClientType } from "redis";
5
+ import { KeyValue } from "@leyyo/common";
6
6
  /**
7
7
  * Redis channel interface
8
8
  *
@@ -39,3 +39,7 @@ export interface RedisDirectChannelOpt extends RedisChannelOpt {
39
39
  * */
40
40
  name?: string;
41
41
  }
42
+ /**
43
+ * Redis query option
44
+ * */
45
+ export type RedisExecOpt = CacheExecOpt;
@@ -1,8 +1,8 @@
1
1
  import { RedisChannel } from "./redis.channel";
2
2
  import { type Entity } from "@samet-it/be-base-common";
3
- import type { RedisConnectionLike } from "../connection";
4
- import type { RedisDirectChannelOpt } from "./index.types";
5
- import type { KeyValue } from "@leyyo/common";
3
+ import { RedisConnectionLike } from "../connection";
4
+ import { RedisDirectChannelOpt } from "./index.types";
5
+ import { KeyValue } from "@leyyo/common";
6
6
  /**
7
7
  * Redis direct channel class
8
8
  *
@@ -19,7 +19,7 @@ class RedisDirectChannel extends redis_channel_1.RedisChannel {
19
19
  * */
20
20
  constructor(conn, opt) {
21
21
  super(conn, opt);
22
- this.logger = be_base_common_1.logger.create(`RedisDirect${opt.name ? '#' + opt.name : ''}`);
22
+ this.logger = be_base_common_1.logger.of(`RedisDirect${opt.name ? '#' + opt.name : ''}`);
23
23
  }
24
24
  }
25
25
  exports.RedisDirectChannel = RedisDirectChannel;
@@ -1,9 +1,9 @@
1
- import type { RedisConnectionLike, RedisExecOpt } from "../connection";
2
- import type { RedisChannelProps, RedisChannelLike, RedisChannelOpt } from "./index.types";
3
- import { type Entity } from "@samet-it/be-base-common";
1
+ import { RedisConnectionLike } from "../connection";
2
+ import { RedisChannelLike, RedisChannelOpt, RedisChannelProps, RedisExecOpt } from "./index.types";
3
+ import { Entity } from "@samet-it/be-base-common";
4
4
  import { CacheChannel } from "@samet-it/be-cache-common";
5
- import type { KeyValue } from "@leyyo/common";
6
- import type { RedisClientType } from "redis";
5
+ import { KeyValue } from "@leyyo/common";
6
+ import { RedisClientType } from "redis";
7
7
  /**
8
8
  * Redis abstract channel class
9
9
  *
@@ -1,4 +1,4 @@
1
- import type { EnvBase } from "@leyyo/env";
1
+ import { EnvBase } from "@leyyo/env";
2
2
  export interface RedisCommonConf extends EnvBase {
3
3
  /**
4
4
  * Redis Enabled
@@ -1,4 +1,4 @@
1
- import type { RedisCommonConf } from "./index.types";
1
+ import { RedisCommonConf } from "./index.types";
2
2
  /**
3
3
  * Redis common config
4
4
  * */
@@ -1,13 +1,12 @@
1
- import type { CacheConnectionLike, CacheConnOpt, CacheExecOpt } from "@samet-it/be-cache-common";
2
- import type { RedisClientType } from "redis";
3
- import type { Entity } from "@samet-it/be-base-common";
4
- import type { RedisDirectChannelOpt, RedisChannelLike } from "../channel";
5
- import type { CacheConnProps } from "@samet-it/be-cache-common";
1
+ import { CacheConnectionLike, CacheConnOpt, CacheConnProps } from "@samet-it/be-cache-common";
2
+ import { RedisClientType } from "redis";
3
+ import { Entity } from "@samet-it/be-base-common";
4
+ import { RedisChannelLike, RedisDirectChannelOpt } from "../channel";
6
5
  import { KeyValue } from "@leyyo/common";
7
6
  /**
8
7
  * Redis connection interface
9
8
  * */
10
- export interface RedisConnectionLike extends CacheConnectionLike<RedisExecOpt> {
9
+ export interface RedisConnectionLike extends CacheConnectionLike {
11
10
  /** @inheritDoc */
12
11
  get props(): Readonly<RedisConnProps>;
13
12
  /**
@@ -63,12 +62,6 @@ export interface RedisConnProps extends CacheConnProps, RedisConnOpt {
63
62
  * @type {RedisClientType}
64
63
  * */
65
64
  client: RedisClientType;
66
- /**
67
- * Connection try count
68
- *
69
- * @type {number}
70
- * */
71
- tryCount: number;
72
65
  /**
73
66
  * Connection url
74
67
  *
@@ -76,7 +69,3 @@ export interface RedisConnProps extends CacheConnProps, RedisConnOpt {
76
69
  * */
77
70
  producedUrl: string;
78
71
  }
79
- /**
80
- * Redis query option
81
- * */
82
- export type RedisExecOpt = CacheExecOpt;
@@ -1,4 +1,4 @@
1
- import type { RedisConnDirectOpt, RedisDirectConnectionLike } from "./index.types";
1
+ import { RedisConnDirectOpt, RedisDirectConnectionLike } from "./index.types";
2
2
  /**
3
3
  * Crete new redis connection
4
4
  *
@@ -1,8 +1,8 @@
1
1
  import { RedisConnection } from "./redis.connection";
2
- import { type Entity } from "@samet-it/be-base-common";
3
- import { type RedisDirectChannelOpt, type RedisChannelLike } from "../channel";
4
- import type { RedisConnDirectOpt, RedisDirectConnectionLike } from "./index.types";
5
- import type { KeyValue } from "@leyyo/common";
2
+ import { Entity } from "@samet-it/be-base-common";
3
+ import { RedisChannelLike, RedisDirectChannelOpt } from "../channel";
4
+ import { RedisConnDirectOpt, RedisDirectConnectionLike } from "./index.types";
5
+ import { KeyValue } from "@leyyo/common";
6
6
  /**
7
7
  * Redis connection direct class
8
8
  * */
@@ -15,7 +15,7 @@ class RedisDirectConnection extends redis_connection_1.RedisConnection {
15
15
  * */
16
16
  constructor(opt) {
17
17
  super(opt);
18
- this.logger = be_base_common_1.logger.create(`RedisConnection${(opt === null || opt === void 0 ? void 0 : opt.name) ? '#' + (opt === null || opt === void 0 ? void 0 : opt.name) : ''}`);
18
+ this.logger = be_base_common_1.logger.of(`RedisConnection${(opt === null || opt === void 0 ? void 0 : opt.name) ? '#' + (opt === null || opt === void 0 ? void 0 : opt.name) : ''}`);
19
19
  }
20
20
  /** @inheritDoc */
21
21
  newChannel(opt) {
@@ -1,28 +1,46 @@
1
- import type { RedisConnectionLike, RedisExecOpt, RedisConnProps, RedisConnOpt } from "./index.types";
1
+ import { RedisClientType } from 'redis';
2
+ import { RedisConnectionLike, RedisConnOpt, RedisConnProps } from "./index.types";
2
3
  import { CacheConnection } from "@samet-it/be-cache-common";
3
- import type { RedisClientType } from "redis";
4
4
  /**
5
5
  * Redis connection abstract class
6
6
  * */
7
- export declare abstract class RedisConnection extends CacheConnection<RedisExecOpt> implements RedisConnectionLike {
7
+ export declare abstract class RedisConnection extends CacheConnection implements RedisConnectionLike {
8
8
  /**
9
- * Base/starting/min delay
9
+ * Base/starting/min delay for connection
10
10
  *
11
11
  * @type {number} - as seconds
12
12
  * */
13
- private static readonly BASE_DELAY;
13
+ private static readonly CONN_BASE_DELAY;
14
14
  /**
15
- * Last/max delay
15
+ * Last/max delay for connection
16
16
  *
17
17
  * @type {number} - as seconds
18
18
  * */
19
- private static readonly MAX_DELAY;
19
+ private static readonly CONN_MAX_DELAY;
20
20
  /**
21
21
  * Try count
22
22
  *
23
23
  * @type {number} - times
24
24
  * */
25
- private static readonly TRY_COUNT;
25
+ private static readonly CONN_TRY_COUNT;
26
+ /**
27
+ * Base/starting/min delay for ping
28
+ *
29
+ * @type {number} - as seconds
30
+ * */
31
+ private static readonly PING_BASE_DELAY;
32
+ /**
33
+ * Last/max delay ping
34
+ *
35
+ * @type {number} - as seconds
36
+ * */
37
+ private static readonly PING_MAX_DELAY;
38
+ /**
39
+ * Try count
40
+ *
41
+ * @type {number} - times
42
+ * */
43
+ private static readonly PING_TRY_COUNT;
26
44
  /** {@inheritDoc} */
27
45
  protected _props: RedisConnProps;
28
46
  /**
@@ -43,12 +61,8 @@ export declare abstract class RedisConnection extends CacheConnection<RedisExecO
43
61
  * Build url from credentials
44
62
  * */
45
63
  protected _buildUrl(): void;
46
- /**
47
- * Generate next delay time with exponential & randomized manner
48
- *
49
- * @return {number}
50
- * */
51
- protected _delayWithJitter(): number;
64
+ protected get _connectionDelay(): number;
65
+ protected get _pingDelay(): number;
52
66
  /** {@inheritDoc} */
53
67
  connect(): Promise<boolean>;
54
68
  /** {@inheritDoc} */
@@ -47,6 +47,7 @@ const redis = __importStar(require("redis"));
47
47
  const config_1 = require("../config");
48
48
  const be_cache_common_1 = require("@samet-it/be-cache-common");
49
49
  const be_base_common_1 = require("@samet-it/be-base-common");
50
+ const common_1 = require("@leyyo/common");
50
51
  /**
51
52
  * Redis connection abstract class
52
53
  * */
@@ -60,9 +61,8 @@ class RedisConnection extends be_cache_common_1.CacheConnection {
60
61
  constructor(opt) {
61
62
  super(opt);
62
63
  if (!this.logger) {
63
- this.logger = be_base_common_1.logger.create(this);
64
+ this.logger = be_base_common_1.logger.of(this);
64
65
  }
65
- this._props.tryCount = 0;
66
66
  this._readFromEnv();
67
67
  this._buildUrl();
68
68
  }
@@ -118,14 +118,11 @@ class RedisConnection extends be_cache_common_1.CacheConnection {
118
118
  }
119
119
  this._props.producedUrl = `${protocol}://${_secure}${host}${_port}${_db}`;
120
120
  }
121
- /**
122
- * Generate next delay time with exponential & randomized manner
123
- *
124
- * @return {number}
125
- * */
126
- _delayWithJitter() {
127
- const exp = Math.min(RedisConnection.BASE_DELAY * Math.pow(2, this._props.tryCount), RedisConnection.MAX_DELAY);
128
- return exp / 2 + Math.random() * (exp / 2);
121
+ get _connectionDelay() {
122
+ return this._delayWithJitter(this._props.connectTryCount, RedisConnection.CONN_BASE_DELAY, RedisConnection.CONN_MAX_DELAY);
123
+ }
124
+ get _pingDelay() {
125
+ return this._delayWithJitter(this._props.pingTryCount, RedisConnection.PING_BASE_DELAY, RedisConnection.PING_MAX_DELAY);
129
126
  }
130
127
  // endregion protected-method
131
128
  // region connect
@@ -139,33 +136,38 @@ class RedisConnection extends be_cache_common_1.CacheConnection {
139
136
  if (this.isConnected) {
140
137
  return true;
141
138
  }
142
- if (this._props.tryCount > RedisConnection.TRY_COUNT) {
143
- const err = new be_cache_common_1.CacheError('Maximum try county', { tryCount: this._props.tryCount });
144
- this.logger.error(be_base_common_1.errorHandler.common.logText(err, 'connect', 'try', this._props.tryCount));
139
+ if (this._props.connectTryCount > RedisConnection.CONN_TRY_COUNT) {
140
+ const err = new be_cache_common_1.CacheError('Maximum try county', { tryCount: this._props.connectTryCount });
141
+ this.logger.error(common_1.errorCommon.text(err, 'connect'));
145
142
  return false;
146
143
  }
147
144
  try {
148
145
  props.client = redis.createClient({ url: this._props.producedUrl });
149
146
  props.client
150
147
  .on("error", err => {
151
- this.checkError(err, { silent: true, name: 'connection' });
152
- props.tryCount++;
148
+ this.logger.warn(common_1.errorCommon.text(err, 'connection', this._props.connectTryCount));
149
+ props.connectTryCount++;
153
150
  const old = this.isConnected;
154
151
  props.isConnected = false;
155
152
  if (old) {
156
153
  this._triggerOnCase('disconnected', this._onDisconnected, false);
157
154
  }
158
- setTimeout(() => this.connect().then(), this._delayWithJitter());
155
+ setTimeout(() => this.connect().then(), this._connectionDelay);
159
156
  })
160
157
  .on('connect', () => {
161
158
  this.logger.info(`on[connect]`);
162
159
  props.isConnected = true;
163
- props.tryCount = 0;
160
+ props.connectTryCount = 0;
164
161
  this._triggerOnCase('connected', this._onConnected, false);
165
162
  if (props.isFirst === undefined) {
166
163
  this._triggerOnCase('first-connected', this._onFirstConnected, true);
167
164
  props.isFirst = false;
168
165
  }
166
+ // clear stopped ping
167
+ if (this._props.pingTryCount > RedisConnection.PING_TRY_COUNT) {
168
+ this._props.pingTryCount = 0;
169
+ setTimeout(() => this.ping(true).then(), 30000);
170
+ }
169
171
  })
170
172
  .on('ready', () => this.logger.info('on[ready]'))
171
173
  .on('close', () => this.logger.info('on[close]'))
@@ -176,7 +178,7 @@ class RedisConnection extends be_cache_common_1.CacheConnection {
176
178
  setTimeout(() => this.ping(true).then(), 30000);
177
179
  }
178
180
  catch (e) {
179
- this.checkError(e, { name: 'connection' });
181
+ this.logger.warn(common_1.errorCommon.text(e, 'connection', this._props.connectTryCount));
180
182
  }
181
183
  return true;
182
184
  });
@@ -187,14 +189,23 @@ class RedisConnection extends be_cache_common_1.CacheConnection {
187
189
  if (!this.isEnabled) {
188
190
  return false;
189
191
  }
192
+ if (this._props.pingTryCount > RedisConnection.PING_TRY_COUNT) {
193
+ const err = new be_cache_common_1.CacheError('Maximum try county', { tryCount: this._props.pingTryCount });
194
+ this.logger.error(common_1.errorCommon.text(err, 'connect'));
195
+ return false;
196
+ }
190
197
  let result = false;
191
198
  if (this.isConnected) {
192
199
  try {
193
200
  yield this.client.ping();
201
+ this._props.pingTryCount = 0;
194
202
  result = true;
195
203
  }
196
204
  catch (err) {
197
- this.checkError(err, { silent: true, name: 'ping' });
205
+ this._props.pingTryCount++;
206
+ this.logger.warn(common_1.errorCommon.text(err, 'ping', this._props.pingTryCount));
207
+ setTimeout(() => this.ping(true).then(), this._pingDelay);
208
+ next = false;
198
209
  }
199
210
  }
200
211
  if (next) {
@@ -207,20 +218,38 @@ class RedisConnection extends be_cache_common_1.CacheConnection {
207
218
  exports.RedisConnection = RedisConnection;
208
219
  // region private-property
209
220
  /**
210
- * Base/starting/min delay
221
+ * Base/starting/min delay for connection
222
+ *
223
+ * @type {number} - as seconds
224
+ * */
225
+ RedisConnection.CONN_BASE_DELAY = 500; // 0.5 sec
226
+ /**
227
+ * Last/max delay for connection
228
+ *
229
+ * @type {number} - as seconds
230
+ * */
231
+ RedisConnection.CONN_MAX_DELAY = 1000 * 60 * 60; // 60 minutes
232
+ /**
233
+ * Try count
234
+ *
235
+ * @type {number} - times
236
+ * */
237
+ RedisConnection.CONN_TRY_COUNT = 100; // 100 times
238
+ /**
239
+ * Base/starting/min delay for ping
211
240
  *
212
241
  * @type {number} - as seconds
213
242
  * */
214
- RedisConnection.BASE_DELAY = 500; // 0.5 sec
243
+ RedisConnection.PING_BASE_DELAY = 200; // 0.2 sec
215
244
  /**
216
- * Last/max delay
245
+ * Last/max delay ping
217
246
  *
218
247
  * @type {number} - as seconds
219
248
  * */
220
- RedisConnection.MAX_DELAY = 1000 * 60 * 60; // 1 hour
249
+ RedisConnection.PING_MAX_DELAY = 1000 * 60 * 10; // 10 minutes
221
250
  /**
222
251
  * Try count
223
252
  *
224
253
  * @type {number} - times
225
254
  * */
226
- RedisConnection.TRY_COUNT = 100; // 100 times
255
+ RedisConnection.PING_TRY_COUNT = 100; // 100 times
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@samet-it/be-redis-common",
3
- "version": "1.1.9",
3
+ "version": "1.3.1",
4
4
  "description": "Redis common component",
5
5
  "keywords": [
6
6
  "redis",
@@ -41,6 +41,7 @@
41
41
  "@babel/preset-env": "^7.28.0",
42
42
  "@babel/preset-typescript": "^7.27.1",
43
43
  "@eslint/js": "^9.33.0",
44
+ "@types/express": "^5.0.6",
44
45
  "@types/jest": "^30.0.0",
45
46
  "@types/node": "^24.2.1",
46
47
  "@typescript-eslint/eslint-plugin": "^8.39.1",
@@ -67,10 +68,10 @@
67
68
  }
68
69
  },
69
70
  "dependencies": {
70
- "@leyyo/common": "^1.2.4",
71
- "@leyyo/env": "^1.2.5",
72
- "@samet-it/be-base-common": "^1.1.5",
73
- "@samet-it/be-cache-common": "^1.1.8",
71
+ "@leyyo/common": "^1.3.7",
72
+ "@leyyo/env": "^1.3.4",
73
+ "@samet-it/be-base-common": "^1.3.1",
74
+ "@samet-it/be-cache-common": "^1.3.1",
74
75
  "redis": "^5.10.0"
75
76
  }
76
77
  }