@eventista/ticketing-common 1.0.28 → 1.0.30
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.
|
@@ -19,7 +19,7 @@ const RedisClusterProvider = {
|
|
|
19
19
|
logger.log('Initializing Redis Cluster connection...');
|
|
20
20
|
const host = configService.get('REDIS_CLUSTER_HOST', 'localhost');
|
|
21
21
|
const port = configService.get('REDIS_CLUSTER_PORT', 6379);
|
|
22
|
-
logger.log(`Connecting to Redis Cluster at ${host}:${port}`);
|
|
22
|
+
logger.log(`Connecting to AWS ElastiCache Redis Cluster at ${host}:${port}`);
|
|
23
23
|
const cluster = new Redis.Cluster([
|
|
24
24
|
{
|
|
25
25
|
host: host,
|
|
@@ -35,37 +35,105 @@ const RedisClusterProvider = {
|
|
|
35
35
|
return delay;
|
|
36
36
|
},
|
|
37
37
|
redisOptions: {
|
|
38
|
-
tls:
|
|
38
|
+
tls: {
|
|
39
39
|
rejectUnauthorized: false,
|
|
40
|
-
}
|
|
41
|
-
connectTimeout: Number(configService.get('REDIS_CONNECT_TIMEOUT',
|
|
40
|
+
},
|
|
41
|
+
connectTimeout: Number(configService.get('REDIS_CONNECT_TIMEOUT', 5000)),
|
|
42
42
|
commandTimeout: Number(configService.get('REDIS_COMMAND_TIMEOUT', 20000)),
|
|
43
43
|
retryStrategy: (times) => {
|
|
44
44
|
logger.warn(`Redis node connection attempt ${times} failed. Retrying...`);
|
|
45
|
-
if (times >
|
|
46
|
-
logger.error('Redis node connection failed after
|
|
45
|
+
if (times > 5) {
|
|
46
|
+
logger.error('Redis node connection failed after 5 attempts. Giving up.');
|
|
47
47
|
return null;
|
|
48
48
|
}
|
|
49
|
-
const delay = Math.min(times * 50,
|
|
49
|
+
const delay = Math.min(times * 50, 2000);
|
|
50
50
|
logger.log(`Retrying Redis node connection in ${delay}ms`);
|
|
51
51
|
return delay;
|
|
52
52
|
},
|
|
53
53
|
},
|
|
54
|
-
enableReadyCheck:
|
|
54
|
+
enableReadyCheck: true,
|
|
55
55
|
enableOfflineQueue: true,
|
|
56
56
|
scaleReads: 'slave',
|
|
57
|
+
slotsRefreshTimeout: 10000,
|
|
58
|
+
slotsRefreshInterval: 30000,
|
|
57
59
|
maxRedirections: 16,
|
|
58
60
|
retryDelayOnFailover: 100,
|
|
59
|
-
retryDelayOnClusterDown:
|
|
61
|
+
retryDelayOnClusterDown: 1000,
|
|
60
62
|
retryDelayOnTryAgain: 100,
|
|
61
|
-
slotsRefreshTimeout: 2000,
|
|
62
|
-
slotsRefreshInterval: 5000,
|
|
63
63
|
});
|
|
64
64
|
cluster.on('connect', () => {
|
|
65
65
|
logger.log('Connected to Redis Cluster');
|
|
66
66
|
});
|
|
67
67
|
cluster.on('ready', () => {
|
|
68
68
|
logger.log('Redis Cluster is ready');
|
|
69
|
+
try {
|
|
70
|
+
const nodes = cluster.nodes();
|
|
71
|
+
logger.log(`Cluster has ${nodes.length} nodes`);
|
|
72
|
+
nodes.forEach(node => {
|
|
73
|
+
logger.log(`Node: ${node.options.host}:${node.options.port} (${node.options.role || 'unknown role'})`);
|
|
74
|
+
});
|
|
75
|
+
logger.log('Fetching detailed cluster info...');
|
|
76
|
+
cluster.cluster('NODES', (err, result) => {
|
|
77
|
+
if (err) {
|
|
78
|
+
logger.error('Failed to get CLUSTER NODES info', err);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const nodeLines = result.split('\n').filter(line => line.trim());
|
|
82
|
+
logger.log(`CLUSTER NODES returned ${nodeLines.length} nodes`);
|
|
83
|
+
const masterNodes = [];
|
|
84
|
+
const replicaNodes = [];
|
|
85
|
+
nodeLines.forEach(line => {
|
|
86
|
+
const parts = line.split(' ');
|
|
87
|
+
const nodeId = parts[0];
|
|
88
|
+
const endpoint = parts[1].split('@')[0];
|
|
89
|
+
const flags = parts[2];
|
|
90
|
+
const master = parts[3];
|
|
91
|
+
const slots = parts.slice(8).join(' ');
|
|
92
|
+
const nodeInfo = {
|
|
93
|
+
id: nodeId,
|
|
94
|
+
endpoint,
|
|
95
|
+
flags,
|
|
96
|
+
master: master === '-' ? 'is_master' : `replica_of_${master}`,
|
|
97
|
+
slots: slots || 'no_slots'
|
|
98
|
+
};
|
|
99
|
+
if (flags.includes('master')) {
|
|
100
|
+
masterNodes.push(nodeInfo);
|
|
101
|
+
}
|
|
102
|
+
else if (flags.includes('slave')) {
|
|
103
|
+
replicaNodes.push(nodeInfo);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
logger.log(`Cluster has ${masterNodes.length} masters and ${replicaNodes.length} replicas`);
|
|
107
|
+
masterNodes.forEach(node => {
|
|
108
|
+
logger.log(`Master: ${node.endpoint} (${node.id.substring(0, 8)}), Slots: ${node.slots}`);
|
|
109
|
+
});
|
|
110
|
+
replicaNodes.forEach(node => {
|
|
111
|
+
logger.log(`Replica: ${node.endpoint} (${node.id.substring(0, 8)}), ${node.master}`);
|
|
112
|
+
});
|
|
113
|
+
if (replicaNodes.length === 0) {
|
|
114
|
+
logger.warn('No replica nodes found! scaleReads: "slave" will not work as expected.');
|
|
115
|
+
logger.warn('All read commands will be sent to master nodes.');
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
cluster.cluster('SLOTS', (err, result) => {
|
|
119
|
+
if (err) {
|
|
120
|
+
logger.error('Failed to get CLUSTER SLOTS info', err);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
logger.log(`CLUSTER SLOTS returned ${result.length} slot ranges`);
|
|
124
|
+
result.forEach(slotInfo => {
|
|
125
|
+
const startSlot = slotInfo[0];
|
|
126
|
+
const endSlot = slotInfo[1];
|
|
127
|
+
const masterHost = slotInfo[2][0];
|
|
128
|
+
const masterPort = slotInfo[2][1];
|
|
129
|
+
const replicas = slotInfo.slice(3).map(replica => `${replica[0]}:${replica[1]}`);
|
|
130
|
+
logger.log(`Slots ${startSlot}-${endSlot} -> Master: ${masterHost}:${masterPort}, Replicas: ${replicas.length > 0 ? replicas.join(', ') : 'none'}`);
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
logger.error('Failed to get cluster nodes info', err);
|
|
136
|
+
}
|
|
69
137
|
});
|
|
70
138
|
cluster.on('error', (err) => {
|
|
71
139
|
logger.error(`Redis Cluster error: ${err.message}`, err.stack);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis.module.js","sourceRoot":"","sources":["../../../src/database/redis/redis.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA0D;AAC1D,2CAA6D;AAC7D,mDAA+C;AAC/C,8DAA0D;AAI1D,MAAM,oBAAoB,GAAa;IACrC,OAAO,EAAE,eAAe;IACxB,UAAU,EAAE,CAAC,aAA4B,EAAE,EAAE;QAC3C,MAAM,MAAM,GAAG,IAAI,4BAAY,CAAC,oBAAoB,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;QAEjC,MAAM,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;QAEvD,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAS,oBAAoB,EAAE,WAAW,CAAC,CAAC;QAC1E,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAS,oBAAoB,EAAE,IAAI,CAAC,CAAC;QAEnE,MAAM,CAAC,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"redis.module.js","sourceRoot":"","sources":["../../../src/database/redis/redis.module.ts"],"names":[],"mappings":"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"}
|