@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.
- package/dist/channel/index.types.d.ts +9 -5
- package/dist/channel/redis-direct.channel.d.ts +3 -3
- package/dist/channel/redis-direct.channel.js +1 -1
- package/dist/channel/redis.channel.d.ts +5 -5
- package/dist/config/index.types.d.ts +1 -1
- package/dist/config/redis-common.config.d.ts +1 -1
- package/dist/connection/index.types.d.ts +5 -16
- package/dist/connection/redis-connection.fn.d.ts +1 -1
- package/dist/connection/redis-direct.connection.d.ts +4 -4
- package/dist/connection/redis-direct.connection.js +1 -1
- package/dist/connection/redis.connection.d.ts +28 -14
- package/dist/connection/redis.connection.js +53 -24
- package/package.json +6 -5
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
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
|
|
4
|
-
import
|
|
5
|
-
import
|
|
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.
|
|
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
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
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
|
|
6
|
-
import
|
|
5
|
+
import { KeyValue } from "@leyyo/common";
|
|
6
|
+
import { RedisClientType } from "redis";
|
|
7
7
|
/**
|
|
8
8
|
* Redis abstract channel class
|
|
9
9
|
*
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
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
|
|
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,8 +1,8 @@
|
|
|
1
1
|
import { RedisConnection } from "./redis.connection";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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.
|
|
143
|
-
const err = new be_cache_common_1.CacheError('Maximum try county', { tryCount: this._props.
|
|
144
|
-
this.logger.error(
|
|
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.
|
|
152
|
-
props.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
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.
|
|
71
|
-
"@leyyo/env": "^1.
|
|
72
|
-
"@samet-it/be-base-common": "^1.1
|
|
73
|
-
"@samet-it/be-cache-common": "^1.1
|
|
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
|
}
|