@levrbet/shared 0.2.85 → 0.2.87
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/core/config/urls.d.ts +4 -0
- package/dist/core/config/urls.js +4 -0
- package/dist/core/config/urls.js.map +1 -1
- package/dist/server/config/redis.d.ts +49 -23
- package/dist/server/config/redis.js +127 -57
- package/dist/server/config/redis.js.map +1 -1
- package/dist/server/config/urls.d.ts +4 -0
- package/package.json +1 -1
|
@@ -8,6 +8,7 @@ export declare const allUrls: {
|
|
|
8
8
|
relayer: string;
|
|
9
9
|
referrals: string;
|
|
10
10
|
liquidationEngine: string;
|
|
11
|
+
leaderboard: string;
|
|
11
12
|
indexers: {
|
|
12
13
|
10143: {
|
|
13
14
|
type: LevrIndexer;
|
|
@@ -23,6 +24,7 @@ export declare const allUrls: {
|
|
|
23
24
|
relayer: string;
|
|
24
25
|
referrals: string;
|
|
25
26
|
liquidationEngine: string;
|
|
27
|
+
leaderboard: string;
|
|
26
28
|
indexers: {
|
|
27
29
|
10143: {
|
|
28
30
|
type: LevrIndexer;
|
|
@@ -38,6 +40,7 @@ export declare const allUrls: {
|
|
|
38
40
|
relayer: string;
|
|
39
41
|
referrals: string;
|
|
40
42
|
liquidationEngine: string;
|
|
43
|
+
leaderboard: string;
|
|
41
44
|
indexers: {
|
|
42
45
|
10143: {
|
|
43
46
|
type: LevrIndexer;
|
|
@@ -53,6 +56,7 @@ export declare const allUrls: {
|
|
|
53
56
|
relayer: string;
|
|
54
57
|
referrals: string;
|
|
55
58
|
liquidationEngine: string;
|
|
59
|
+
leaderboard: string;
|
|
56
60
|
indexers: {
|
|
57
61
|
10143: {
|
|
58
62
|
type: LevrIndexer;
|
package/dist/core/config/urls.js
CHANGED
|
@@ -13,6 +13,7 @@ exports.allUrls = {
|
|
|
13
13
|
relayer: "https://relayers.dev.levr.bet",
|
|
14
14
|
referrals: "https://referrals.dev.levr.bet",
|
|
15
15
|
liquidationEngine: "https://liquidation-engine.dev.levr.bet",
|
|
16
|
+
leaderboard: "https://leaderboard.dev.levr.bet",
|
|
16
17
|
indexers: {
|
|
17
18
|
[types_1.LevrChain.MONAD_TESTNET]: [
|
|
18
19
|
{ type: indexers_types_1.LevrIndexer.ENVIO, url: "https://indexer.dev.hyperindex.xyz/a07fcc5/v1/graphql" },
|
|
@@ -28,6 +29,7 @@ exports.allUrls = {
|
|
|
28
29
|
relayer: "https://relayers.dev.levr.bet", //http://levr-v1-openzeppeline-1018367603.ap-south-1.elb.amazonaws.com",
|
|
29
30
|
referrals: "https://referrals.dev.levr.bet",
|
|
30
31
|
liquidationEngine: "https://liquidation-engine.dev.levr.bet",
|
|
32
|
+
leaderboard: "https://leaderboard.dev.levr.bet",
|
|
31
33
|
indexers: {
|
|
32
34
|
[types_1.LevrChain.MONAD_TESTNET]: [
|
|
33
35
|
{ type: indexers_types_1.LevrIndexer.ENVIO, url: "https://indexer.dev.hyperindex.xyz/a07fcc5/v1/graphql" },
|
|
@@ -43,6 +45,7 @@ exports.allUrls = {
|
|
|
43
45
|
relayer: "https://relayers.staging.levr.bet",
|
|
44
46
|
referrals: "https://referrals.staging.levr.bet",
|
|
45
47
|
liquidationEngine: "https://liquidation-engine.dev.levr.bet",
|
|
48
|
+
leaderboard: "https://leaderboard.staging.levr.bet",
|
|
46
49
|
indexers: {
|
|
47
50
|
[types_1.LevrChain.MONAD_TESTNET]: [
|
|
48
51
|
{ type: indexers_types_1.LevrIndexer.ENVIO, url: "https://indexer.staging.levr.app" },
|
|
@@ -58,6 +61,7 @@ exports.allUrls = {
|
|
|
58
61
|
relayer: "https://relayers.levr.app",
|
|
59
62
|
referrals: "https://referrals.levr.app",
|
|
60
63
|
liquidationEngine: "https://liquidation-engine.dev.levr.bet",
|
|
64
|
+
leaderboard: "https://leaderboard.levr.bet",
|
|
61
65
|
indexers: {
|
|
62
66
|
[types_1.LevrChain.MONAD_TESTNET]: [
|
|
63
67
|
{ type: indexers_types_1.LevrIndexer.ENVIO, url: "https://indexer.levr.app" },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"urls.js","sourceRoot":"","sources":["../../../src/core/config/urls.ts"],"names":[],"mappings":";;;AAAA,oCAA6C;AAC7C,4DAAqD;AAErD,sBAAsB;AAET,QAAA,OAAO,GAAG;IACnB,CAAC,eAAO,CAAC,KAAK,CAAC,EAAE;QACb,IAAI,EAAE,+BAA+B;QACrC,UAAU,EAAE,kCAAkC;QAC9C,eAAe,EAAE,uCAAuC;QACxD,gBAAgB,EAAE,uCAAuC;QACzD,OAAO,EAAE,+BAA+B;QACxC,SAAS,EAAE,gCAAgC;QAC3C,iBAAiB,EAAE,yCAAyC;QAC5D,QAAQ,EAAE;YACN,CAAC,iBAAS,CAAC,aAAa,CAAC,EAAE;gBACvB,EAAE,IAAI,EAAE,4BAAW,CAAC,KAAK,EAAE,GAAG,EAAE,uDAAuD,EAAE;gBACzF,EAAE,IAAI,EAAE,4BAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,gEAAgE,EAAE;aACxG;SACJ;KACJ;IACD,CAAC,eAAO,CAAC,GAAG,CAAC,EAAE;QACX,IAAI,EAAE,+BAA+B;QACrC,UAAU,EAAE,kCAAkC;QAC9C,eAAe,EAAE,uCAAuC;QACxD,gBAAgB,EAAE,uCAAuC;QACzD,OAAO,EAAE,+BAA+B,EAAE,wEAAwE;QAClH,SAAS,EAAE,gCAAgC;QAC3C,iBAAiB,EAAE,yCAAyC;QAC5D,QAAQ,EAAE;YACN,CAAC,iBAAS,CAAC,aAAa,CAAC,EAAE;gBACvB,EAAE,IAAI,EAAE,4BAAW,CAAC,KAAK,EAAE,GAAG,EAAE,uDAAuD,EAAE;gBACzF,EAAE,IAAI,EAAE,4BAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,wDAAwD,EAAE;aAChG;SACJ;KACJ;IACD,CAAC,eAAO,CAAC,OAAO,CAAC,EAAE;QACf,IAAI,EAAE,oCAAoC;QAC1C,UAAU,EAAE,sCAAsC;QAClD,eAAe,EAAE,2CAA2C;QAC5D,gBAAgB,EAAE,2CAA2C;QAC7D,OAAO,EAAE,mCAAmC;QAC5C,SAAS,EAAE,oCAAoC;QAC/C,iBAAiB,EAAE,yCAAyC;QAC5D,QAAQ,EAAE;YACN,CAAC,iBAAS,CAAC,aAAa,CAAC,EAAE;gBACvB,EAAE,IAAI,EAAE,4BAAW,CAAC,KAAK,EAAE,GAAG,EAAE,kCAAkC,EAAE;gBACpE,EAAE,IAAI,EAAE,4BAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,kCAAkC,EAAE;aAC1E;SACJ;KACJ;IACD,CAAC,eAAO,CAAC,IAAI,CAAC,EAAE;QACZ,IAAI,EAAE,2BAA2B;QACjC,UAAU,EAAE,8BAA8B;QAC1C,eAAe,EAAE,mCAAmC;QACpD,gBAAgB,EAAE,mCAAmC;QACrD,OAAO,EAAE,2BAA2B;QACpC,SAAS,EAAE,4BAA4B;QACvC,iBAAiB,EAAE,yCAAyC;QAC5D,QAAQ,EAAE;YACN,CAAC,iBAAS,CAAC,aAAa,CAAC,EAAE;gBACvB,EAAE,IAAI,EAAE,4BAAW,CAAC,KAAK,EAAE,GAAG,EAAE,0BAA0B,EAAE;gBAC5D,EAAE,IAAI,EAAE,4BAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,0BAA0B,EAAE;aAClE;SACJ;KACJ;CACJ,CAAA"}
|
|
1
|
+
{"version":3,"file":"urls.js","sourceRoot":"","sources":["../../../src/core/config/urls.ts"],"names":[],"mappings":";;;AAAA,oCAA6C;AAC7C,4DAAqD;AAErD,sBAAsB;AAET,QAAA,OAAO,GAAG;IACnB,CAAC,eAAO,CAAC,KAAK,CAAC,EAAE;QACb,IAAI,EAAE,+BAA+B;QACrC,UAAU,EAAE,kCAAkC;QAC9C,eAAe,EAAE,uCAAuC;QACxD,gBAAgB,EAAE,uCAAuC;QACzD,OAAO,EAAE,+BAA+B;QACxC,SAAS,EAAE,gCAAgC;QAC3C,iBAAiB,EAAE,yCAAyC;QAC5D,WAAW,EAAE,kCAAkC;QAC/C,QAAQ,EAAE;YACN,CAAC,iBAAS,CAAC,aAAa,CAAC,EAAE;gBACvB,EAAE,IAAI,EAAE,4BAAW,CAAC,KAAK,EAAE,GAAG,EAAE,uDAAuD,EAAE;gBACzF,EAAE,IAAI,EAAE,4BAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,gEAAgE,EAAE;aACxG;SACJ;KACJ;IACD,CAAC,eAAO,CAAC,GAAG,CAAC,EAAE;QACX,IAAI,EAAE,+BAA+B;QACrC,UAAU,EAAE,kCAAkC;QAC9C,eAAe,EAAE,uCAAuC;QACxD,gBAAgB,EAAE,uCAAuC;QACzD,OAAO,EAAE,+BAA+B,EAAE,wEAAwE;QAClH,SAAS,EAAE,gCAAgC;QAC3C,iBAAiB,EAAE,yCAAyC;QAC5D,WAAW,EAAE,kCAAkC;QAC/C,QAAQ,EAAE;YACN,CAAC,iBAAS,CAAC,aAAa,CAAC,EAAE;gBACvB,EAAE,IAAI,EAAE,4BAAW,CAAC,KAAK,EAAE,GAAG,EAAE,uDAAuD,EAAE;gBACzF,EAAE,IAAI,EAAE,4BAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,wDAAwD,EAAE;aAChG;SACJ;KACJ;IACD,CAAC,eAAO,CAAC,OAAO,CAAC,EAAE;QACf,IAAI,EAAE,oCAAoC;QAC1C,UAAU,EAAE,sCAAsC;QAClD,eAAe,EAAE,2CAA2C;QAC5D,gBAAgB,EAAE,2CAA2C;QAC7D,OAAO,EAAE,mCAAmC;QAC5C,SAAS,EAAE,oCAAoC;QAC/C,iBAAiB,EAAE,yCAAyC;QAC5D,WAAW,EAAE,sCAAsC;QACnD,QAAQ,EAAE;YACN,CAAC,iBAAS,CAAC,aAAa,CAAC,EAAE;gBACvB,EAAE,IAAI,EAAE,4BAAW,CAAC,KAAK,EAAE,GAAG,EAAE,kCAAkC,EAAE;gBACpE,EAAE,IAAI,EAAE,4BAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,kCAAkC,EAAE;aAC1E;SACJ;KACJ;IACD,CAAC,eAAO,CAAC,IAAI,CAAC,EAAE;QACZ,IAAI,EAAE,2BAA2B;QACjC,UAAU,EAAE,8BAA8B;QAC1C,eAAe,EAAE,mCAAmC;QACpD,gBAAgB,EAAE,mCAAmC;QACrD,OAAO,EAAE,2BAA2B;QACpC,SAAS,EAAE,4BAA4B;QACvC,iBAAiB,EAAE,yCAAyC;QAC5D,WAAW,EAAE,8BAA8B;QAC3C,QAAQ,EAAE;YACN,CAAC,iBAAS,CAAC,aAAa,CAAC,EAAE;gBACvB,EAAE,IAAI,EAAE,4BAAW,CAAC,KAAK,EAAE,GAAG,EAAE,0BAA0B,EAAE;gBAC5D,EAAE,IAAI,EAAE,4BAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,0BAA0B,EAAE;aAClE;SACJ;KACJ;CACJ,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "dotenv/config";
|
|
2
|
-
import
|
|
2
|
+
import { Cluster, type ClusterOptions, type RedisOptions } from "ioredis";
|
|
3
3
|
export declare enum RedisDb {
|
|
4
4
|
ORACLE = 0,
|
|
5
5
|
ORDERBOOK = 1,
|
|
@@ -9,49 +9,75 @@ export declare enum RedisDb {
|
|
|
9
9
|
LAB = 5
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
|
-
* Manages Redis client connections
|
|
12
|
+
* Manages Redis Cluster client connections.
|
|
13
13
|
*
|
|
14
|
-
* This manager provides a singleton-like pattern for initializing and accessing Redis clients.
|
|
15
|
-
* It
|
|
14
|
+
* This manager provides a singleton-like pattern for initializing and accessing Redis Cluster clients.
|
|
15
|
+
* It uses Redis Cluster mode for high availability and automatic sharding.
|
|
16
16
|
*
|
|
17
17
|
* **Note:** Not all services that use this package require Redis, so initialization is opt-in.
|
|
18
18
|
* Call `init()` explicitly before using any Redis clients.
|
|
19
19
|
*
|
|
20
|
+
* **Important:** Redis Cluster does not support database selection (SELECT command).
|
|
21
|
+
* All operations use database 0. Use key prefixes for logical separation instead.
|
|
22
|
+
*
|
|
20
23
|
* @example
|
|
21
24
|
* ```typescript
|
|
22
|
-
* redisClientManager.init({
|
|
23
|
-
*
|
|
24
|
-
* // Get primary client for write operations
|
|
25
|
-
* const primary = redisClientManager.primaryClient;
|
|
26
|
-
* await primary.set('key', 'value');
|
|
25
|
+
* redisClientManager.init({ keyPrefix: 'oracle:' });
|
|
27
26
|
*
|
|
28
|
-
* // Get
|
|
29
|
-
* const
|
|
30
|
-
*
|
|
27
|
+
* // Get cluster client for operations
|
|
28
|
+
* const client = redisClientManager.clusterClient;
|
|
29
|
+
* await client.set('key', 'value');
|
|
30
|
+
* const value = await client.get('key');
|
|
31
31
|
* ```
|
|
32
32
|
*/
|
|
33
33
|
declare class RedisClientManager {
|
|
34
|
-
private
|
|
35
|
-
private replicaClients;
|
|
34
|
+
private _clusterClient;
|
|
36
35
|
private initialized;
|
|
37
|
-
private dbIndex;
|
|
38
36
|
/**
|
|
39
|
-
* Initializes the Redis client manager
|
|
37
|
+
* Initializes the Redis Cluster client manager.
|
|
40
38
|
*
|
|
41
39
|
* **Note:** Not all services that use this package require Redis, so initialization is opt-in.
|
|
42
40
|
* Call this method explicitly before using any Redis clients to avoid initialization errors.
|
|
43
41
|
*
|
|
44
|
-
*
|
|
42
|
+
* **Important:** Redis Cluster does not support database selection. Use keyPrefix for logical separation.
|
|
43
|
+
*
|
|
44
|
+
* @param options - Optional Redis Cluster configuration options
|
|
45
45
|
* @example
|
|
46
46
|
* ```typescript
|
|
47
|
-
* // Initialize with a
|
|
48
|
-
* redisClientManager.init({
|
|
47
|
+
* // Initialize with a key prefix for logical separation
|
|
48
|
+
* redisClientManager.init({ keyPrefix: 'auth:' });
|
|
49
49
|
* ```
|
|
50
50
|
*/
|
|
51
|
-
init(options?:
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
init(options?: Omit<ClusterOptions, "redisOptions"> & {
|
|
52
|
+
redisOptions?: RedisOptions;
|
|
53
|
+
}): void;
|
|
54
|
+
/**
|
|
55
|
+
* Gets the Redis Cluster client.
|
|
56
|
+
* @throws Error if the client manager is not initialized
|
|
57
|
+
*/
|
|
58
|
+
get clusterClient(): Cluster;
|
|
59
|
+
/**
|
|
60
|
+
* Alias for clusterClient for backward compatibility.
|
|
61
|
+
* In cluster mode, all nodes handle both reads and writes automatically.
|
|
62
|
+
*/
|
|
63
|
+
get primaryClient(): Cluster;
|
|
64
|
+
/**
|
|
65
|
+
* Alias for clusterClient for backward compatibility.
|
|
66
|
+
* In cluster mode, reads are automatically distributed to replicas via scaleReads option.
|
|
67
|
+
*/
|
|
68
|
+
get replicaClient(): Cluster;
|
|
69
|
+
/**
|
|
70
|
+
* Creates a duplicate cluster client with the same configuration.
|
|
71
|
+
* Useful for pub/sub or blocking operations that need a dedicated connection.
|
|
72
|
+
*
|
|
73
|
+
* @param clientName - A descriptive name for logging purposes
|
|
74
|
+
* @returns A new Cluster client instance
|
|
75
|
+
*/
|
|
76
|
+
duplicateClient: (clientName: string) => Cluster;
|
|
77
|
+
/**
|
|
78
|
+
* Gracefully closes all Redis Cluster connections.
|
|
79
|
+
*/
|
|
80
|
+
disconnect(): Promise<void>;
|
|
55
81
|
}
|
|
56
82
|
export declare const redisClientManager: RedisClientManager;
|
|
57
83
|
export {};
|
|
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.redisClientManager = exports.RedisDb = void 0;
|
|
7
7
|
require("dotenv/config");
|
|
8
|
-
const ioredis_1 =
|
|
8
|
+
const ioredis_1 = require("ioredis");
|
|
9
9
|
const core_1 = require("../../core");
|
|
10
10
|
const _1 = require(".");
|
|
11
11
|
const dotenv_1 = require("./dotenv");
|
|
@@ -20,56 +20,80 @@ var RedisDb;
|
|
|
20
20
|
RedisDb[RedisDb["LAB"] = 5] = "LAB";
|
|
21
21
|
})(RedisDb || (exports.RedisDb = RedisDb = {}));
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* Parses a Redis URL and extracts connection details.
|
|
24
|
+
* Supports URLs in the format: redis://username:password@host:port
|
|
25
|
+
*/
|
|
26
|
+
function parseRedisUrl(url) {
|
|
27
|
+
const parsed = new URL(url);
|
|
28
|
+
return {
|
|
29
|
+
host: parsed.hostname,
|
|
30
|
+
port: Number.parseInt(parsed.port, 10) || 6379,
|
|
31
|
+
username: parsed.username || undefined,
|
|
32
|
+
password: parsed.password || undefined,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Manages Redis Cluster client connections.
|
|
24
37
|
*
|
|
25
|
-
* This manager provides a singleton-like pattern for initializing and accessing Redis clients.
|
|
26
|
-
* It
|
|
38
|
+
* This manager provides a singleton-like pattern for initializing and accessing Redis Cluster clients.
|
|
39
|
+
* It uses Redis Cluster mode for high availability and automatic sharding.
|
|
27
40
|
*
|
|
28
41
|
* **Note:** Not all services that use this package require Redis, so initialization is opt-in.
|
|
29
42
|
* Call `init()` explicitly before using any Redis clients.
|
|
30
43
|
*
|
|
44
|
+
* **Important:** Redis Cluster does not support database selection (SELECT command).
|
|
45
|
+
* All operations use database 0. Use key prefixes for logical separation instead.
|
|
46
|
+
*
|
|
31
47
|
* @example
|
|
32
48
|
* ```typescript
|
|
33
|
-
* redisClientManager.init({
|
|
49
|
+
* redisClientManager.init({ keyPrefix: 'oracle:' });
|
|
34
50
|
*
|
|
35
|
-
* // Get
|
|
36
|
-
* const
|
|
37
|
-
* await
|
|
38
|
-
*
|
|
39
|
-
* // Get replica client for read operations (load balanced)
|
|
40
|
-
* const replica = redisClientManager.replicaClient;
|
|
41
|
-
* const value = await replica.get('key');
|
|
51
|
+
* // Get cluster client for operations
|
|
52
|
+
* const client = redisClientManager.clusterClient;
|
|
53
|
+
* await client.set('key', 'value');
|
|
54
|
+
* const value = await client.get('key');
|
|
42
55
|
* ```
|
|
43
56
|
*/
|
|
44
57
|
class RedisClientManager {
|
|
45
58
|
constructor() {
|
|
46
|
-
this.
|
|
47
|
-
this.replicaClients = [];
|
|
59
|
+
this._clusterClient = null;
|
|
48
60
|
this.initialized = false;
|
|
49
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Creates a duplicate cluster client with the same configuration.
|
|
63
|
+
* Useful for pub/sub or blocking operations that need a dedicated connection.
|
|
64
|
+
*
|
|
65
|
+
* @param clientName - A descriptive name for logging purposes
|
|
66
|
+
* @returns A new Cluster client instance
|
|
67
|
+
*/
|
|
50
68
|
this.duplicateClient = (clientName) => {
|
|
51
|
-
|
|
52
|
-
|
|
69
|
+
if (!this._clusterClient)
|
|
70
|
+
throw new Error("RedisClientManager is not initialized. Call init() first.");
|
|
71
|
+
const client = this._clusterClient.duplicate();
|
|
53
72
|
client.on("error", (err) => {
|
|
54
|
-
winston_1.default.error(`Redis ${clientName} client error:`, err);
|
|
73
|
+
winston_1.default.error(`Redis Cluster ${clientName} client error:`, err);
|
|
55
74
|
});
|
|
56
75
|
client.on("connect", () => {
|
|
57
|
-
winston_1.default.info(`Connected to Redis ${clientName} client`);
|
|
76
|
+
winston_1.default.info(`Connected to Redis Cluster ${clientName} client`);
|
|
77
|
+
});
|
|
78
|
+
client.on("ready", () => {
|
|
79
|
+
winston_1.default.info(`Redis Cluster ${clientName} client is ready`);
|
|
58
80
|
});
|
|
59
81
|
return client;
|
|
60
82
|
};
|
|
61
83
|
}
|
|
62
84
|
/**
|
|
63
|
-
* Initializes the Redis client manager
|
|
85
|
+
* Initializes the Redis Cluster client manager.
|
|
64
86
|
*
|
|
65
87
|
* **Note:** Not all services that use this package require Redis, so initialization is opt-in.
|
|
66
88
|
* Call this method explicitly before using any Redis clients to avoid initialization errors.
|
|
67
89
|
*
|
|
68
|
-
*
|
|
90
|
+
* **Important:** Redis Cluster does not support database selection. Use keyPrefix for logical separation.
|
|
91
|
+
*
|
|
92
|
+
* @param options - Optional Redis Cluster configuration options
|
|
69
93
|
* @example
|
|
70
94
|
* ```typescript
|
|
71
|
-
* // Initialize with a
|
|
72
|
-
* redisClientManager.init({
|
|
95
|
+
* // Initialize with a key prefix for logical separation
|
|
96
|
+
* redisClientManager.init({ keyPrefix: 'auth:' });
|
|
73
97
|
* ```
|
|
74
98
|
*/
|
|
75
99
|
init(options) {
|
|
@@ -79,51 +103,97 @@ class RedisClientManager {
|
|
|
79
103
|
}
|
|
80
104
|
this.initialized = true;
|
|
81
105
|
const { REDIS_URL, REDIS_REPLICA_ENDPOINTS } = core_1.Config.init(_1.redisSchema);
|
|
106
|
+
// Parse primary node
|
|
107
|
+
const primaryNode = parseRedisUrl(REDIS_URL);
|
|
108
|
+
// Parse replica nodes
|
|
109
|
+
const replicaEndpoints = REDIS_REPLICA_ENDPOINTS.split(",").filter(Boolean);
|
|
110
|
+
const replicaNodes = replicaEndpoints.map((url) => parseRedisUrl(url));
|
|
111
|
+
// Build cluster nodes list
|
|
112
|
+
const clusterNodes = [
|
|
113
|
+
{ host: primaryNode.host, port: primaryNode.port },
|
|
114
|
+
...replicaNodes.map((node) => ({ host: node.host, port: node.port })),
|
|
115
|
+
];
|
|
82
116
|
// Enable TLS for non-dev/local environments
|
|
83
117
|
const shouldUseTls = dotenv_1.LEVR_ENV !== core_1.LevrEnv.DEV && dotenv_1.LEVR_ENV !== core_1.LevrEnv.LOCAL;
|
|
84
|
-
|
|
118
|
+
// Use credentials from the primary node URL
|
|
119
|
+
const clusterOptions = {
|
|
85
120
|
...options,
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
121
|
+
redisOptions: {
|
|
122
|
+
...options?.redisOptions,
|
|
123
|
+
username: primaryNode.username,
|
|
124
|
+
password: primaryNode.password,
|
|
125
|
+
...(shouldUseTls && {
|
|
126
|
+
tls: {},
|
|
127
|
+
}),
|
|
128
|
+
},
|
|
129
|
+
// Enable reading from replicas for load balancing
|
|
130
|
+
scaleReads: "slave",
|
|
131
|
+
// Retry strategy for cluster connection
|
|
132
|
+
clusterRetryStrategy: (times) => {
|
|
133
|
+
if (times > 10) {
|
|
134
|
+
winston_1.default.error("Redis Cluster: Max retry attempts reached");
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
return Math.min(times * 100, 3000);
|
|
138
|
+
},
|
|
139
|
+
// Enable NAT mapping if needed (useful for cloud environments)
|
|
140
|
+
enableReadyCheck: true,
|
|
141
|
+
// DNS lookup for cluster nodes
|
|
142
|
+
dnsLookup: (address, callback) => callback(null, address),
|
|
89
143
|
};
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
if (options?.db)
|
|
94
|
-
void this._primaryClient.select(options.db);
|
|
95
|
-
this._primaryClient.on("error", (err) => {
|
|
96
|
-
winston_1.default.error("Redis primary client error:", err);
|
|
144
|
+
this._clusterClient = new ioredis_1.Cluster(clusterNodes, clusterOptions);
|
|
145
|
+
this._clusterClient.on("error", (err) => {
|
|
146
|
+
winston_1.default.error("Redis Cluster client error:", err);
|
|
97
147
|
});
|
|
98
|
-
this.
|
|
99
|
-
winston_1.default.info("Connected to Redis
|
|
148
|
+
this._clusterClient.on("connect", () => {
|
|
149
|
+
winston_1.default.info("Connected to Redis Cluster");
|
|
100
150
|
});
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
});
|
|
112
|
-
return client;
|
|
151
|
+
this._clusterClient.on("ready", () => {
|
|
152
|
+
winston_1.default.info("Redis Cluster is ready");
|
|
153
|
+
});
|
|
154
|
+
this._clusterClient.on("node error", (err, address) => {
|
|
155
|
+
winston_1.default.error(`Redis Cluster node error at ${address}:`, err);
|
|
156
|
+
});
|
|
157
|
+
this._clusterClient.on("+node", (node) => {
|
|
158
|
+
winston_1.default.info(`Redis Cluster: New node added - ${node.options.host}:${node.options.port}`);
|
|
159
|
+
});
|
|
160
|
+
this._clusterClient.on("-node", (node) => {
|
|
161
|
+
winston_1.default.warn(`Redis Cluster: Node removed - ${node.options.host}:${node.options.port}`);
|
|
113
162
|
});
|
|
114
163
|
}
|
|
115
|
-
|
|
116
|
-
|
|
164
|
+
/**
|
|
165
|
+
* Gets the Redis Cluster client.
|
|
166
|
+
* @throws Error if the client manager is not initialized
|
|
167
|
+
*/
|
|
168
|
+
get clusterClient() {
|
|
169
|
+
if (!this._clusterClient)
|
|
117
170
|
throw new Error("RedisClientManager is not initialized. Call init() first.");
|
|
118
|
-
return this.
|
|
171
|
+
return this._clusterClient;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Alias for clusterClient for backward compatibility.
|
|
175
|
+
* In cluster mode, all nodes handle both reads and writes automatically.
|
|
176
|
+
*/
|
|
177
|
+
get primaryClient() {
|
|
178
|
+
return this.clusterClient;
|
|
119
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* Alias for clusterClient for backward compatibility.
|
|
182
|
+
* In cluster mode, reads are automatically distributed to replicas via scaleReads option.
|
|
183
|
+
*/
|
|
120
184
|
get replicaClient() {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
185
|
+
return this.clusterClient;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Gracefully closes all Redis Cluster connections.
|
|
189
|
+
*/
|
|
190
|
+
async disconnect() {
|
|
191
|
+
if (this._clusterClient) {
|
|
192
|
+
await this._clusterClient.quit();
|
|
193
|
+
this._clusterClient = null;
|
|
194
|
+
this.initialized = false;
|
|
195
|
+
winston_1.default.info("Redis Cluster disconnected");
|
|
196
|
+
}
|
|
127
197
|
}
|
|
128
198
|
}
|
|
129
199
|
exports.redisClientManager = new RedisClientManager();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis.js","sourceRoot":"","sources":["../../../src/server/config/redis.ts"],"names":[],"mappings":";;;;;;AAAA,yBAAsB;AACtB,
|
|
1
|
+
{"version":3,"file":"redis.js","sourceRoot":"","sources":["../../../src/server/config/redis.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,7 @@ export declare const urls: {
|
|
|
6
6
|
relayer: string;
|
|
7
7
|
referrals: string;
|
|
8
8
|
liquidationEngine: string;
|
|
9
|
+
leaderboard: string;
|
|
9
10
|
indexers: {
|
|
10
11
|
10143: {
|
|
11
12
|
type: import("../../core").LevrIndexer;
|
|
@@ -20,6 +21,7 @@ export declare const urls: {
|
|
|
20
21
|
relayer: string;
|
|
21
22
|
referrals: string;
|
|
22
23
|
liquidationEngine: string;
|
|
24
|
+
leaderboard: string;
|
|
23
25
|
indexers: {
|
|
24
26
|
10143: {
|
|
25
27
|
type: import("../../core").LevrIndexer;
|
|
@@ -34,6 +36,7 @@ export declare const urls: {
|
|
|
34
36
|
relayer: string;
|
|
35
37
|
referrals: string;
|
|
36
38
|
liquidationEngine: string;
|
|
39
|
+
leaderboard: string;
|
|
37
40
|
indexers: {
|
|
38
41
|
10143: {
|
|
39
42
|
type: import("../../core").LevrIndexer;
|
|
@@ -48,6 +51,7 @@ export declare const urls: {
|
|
|
48
51
|
relayer: string;
|
|
49
52
|
referrals: string;
|
|
50
53
|
liquidationEngine: string;
|
|
54
|
+
leaderboard: string;
|
|
51
55
|
indexers: {
|
|
52
56
|
10143: {
|
|
53
57
|
type: import("../../core").LevrIndexer;
|