Skip to content

Commit ec1b0c3

Browse files
Flossyclaude
andcommitted
fix: Store and retrieve correct address/port for each cluster node in Redis
Fixes #199 Changed RedisClusterManager to store each node's address and port in Redis and retrieve them correctly instead of using local node's config for all nodes. Changes: - registerMember(): Store node info as JSON with timestamp, address, and port - getNodes(): Parse JSON to extract correct address and port for each node - Added helper methods: extractJsonString(), extractJsonInt(), extractJsonLong() for simple JSON parsing - Log parsing errors and skip malformed entries gracefully Before this fix, all nodes appeared to have the same address/port as the local node, breaking cluster communication and load balancing. Now each node reports its correct network location. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 90b763f commit ec1b0c3

1 file changed

Lines changed: 86 additions & 6 deletions

File tree

jplatform-cluster-redis/src/main/java/org/flossware/jplatform/cluster/redis/RedisClusterManager.java

Lines changed: 86 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,24 @@ public Set<ClusterNode> getNodes() {
140140

141141
for (Map.Entry<String, String> entry : members.entrySet()) {
142142
String memberId = entry.getKey();
143-
nodes.add(new ClusterNode(memberId,
144-
clusterConfig.getBindAddress(),
145-
clusterConfig.getBindPort(),
146-
ClusterNode.NodeState.ACTIVE,
147-
System.currentTimeMillis()));
143+
String nodeInfoJson = entry.getValue();
144+
145+
try {
146+
// Parse JSON to extract address, port, timestamp
147+
String address = extractJsonString(nodeInfoJson, "address");
148+
int port = extractJsonInt(nodeInfoJson, "port");
149+
long timestamp = extractJsonLong(nodeInfoJson, "timestamp");
150+
151+
nodes.add(new ClusterNode(
152+
memberId,
153+
address,
154+
port,
155+
ClusterNode.NodeState.ACTIVE,
156+
timestamp
157+
));
158+
} catch (Exception e) {
159+
logger.error("Failed to parse node info for: {}", memberId, e);
160+
}
148161
}
149162
} catch (Exception e) {
150163
logger.error("Failed to get nodes", e);
@@ -215,7 +228,14 @@ private void tryBecomeLeader() {
215228
private void registerMember() {
216229
try (Jedis jedis = pool.getResource()) {
217230
String memberKey = MEMBER_KEY_PREFIX + clusterConfig.getClusterName();
218-
jedis.hset(memberKey, nodeId, String.valueOf(System.currentTimeMillis()));
231+
// Store node info as JSON: {"timestamp": ..., "address": "...", "port": ...}
232+
String nodeInfo = String.format(
233+
"{\"timestamp\":%d,\"address\":\"%s\",\"port\":%d}",
234+
System.currentTimeMillis(),
235+
clusterConfig.getBindAddress(),
236+
clusterConfig.getBindPort()
237+
);
238+
jedis.hset(memberKey, nodeId, nodeInfo);
219239
jedis.expire(memberKey, config.getLeaseTtl() * 2);
220240
} catch (Exception e) {
221241
logger.error("Failed to register member", e);
@@ -264,6 +284,66 @@ public JedisPool getJedisPool() {
264284
return pool;
265285
}
266286

287+
/**
288+
* Extracts a string value from a simple JSON object.
289+
*
290+
* @param json the JSON string
291+
* @param key the key to extract
292+
* @return the extracted string value
293+
*/
294+
private String extractJsonString(String json, String key) {
295+
String pattern = "\"" + key + "\":\"";
296+
int start = json.indexOf(pattern);
297+
if (start == -1) {
298+
throw new IllegalArgumentException("Key not found in JSON: " + key);
299+
}
300+
start += pattern.length();
301+
int end = json.indexOf("\"", start);
302+
return json.substring(start, end);
303+
}
304+
305+
/**
306+
* Extracts an integer value from a simple JSON object.
307+
*
308+
* @param json the JSON string
309+
* @param key the key to extract
310+
* @return the extracted integer value
311+
*/
312+
private int extractJsonInt(String json, String key) {
313+
String pattern = "\"" + key + "\":";
314+
int start = json.indexOf(pattern);
315+
if (start == -1) {
316+
throw new IllegalArgumentException("Key not found in JSON: " + key);
317+
}
318+
start += pattern.length();
319+
int end = json.indexOf(",", start);
320+
if (end == -1) {
321+
end = json.indexOf("}", start);
322+
}
323+
return Integer.parseInt(json.substring(start, end).trim());
324+
}
325+
326+
/**
327+
* Extracts a long value from a simple JSON object.
328+
*
329+
* @param json the JSON string
330+
* @param key the key to extract
331+
* @return the extracted long value
332+
*/
333+
private long extractJsonLong(String json, String key) {
334+
String pattern = "\"" + key + "\":";
335+
int start = json.indexOf(pattern);
336+
if (start == -1) {
337+
throw new IllegalArgumentException("Key not found in JSON: " + key);
338+
}
339+
start += pattern.length();
340+
int end = json.indexOf(",", start);
341+
if (end == -1) {
342+
end = json.indexOf("}", start);
343+
}
344+
return Long.parseLong(json.substring(start, end).trim());
345+
}
346+
267347
/**
268348
* Returns the node ID.
269349
*

0 commit comments

Comments
 (0)