From 79e157a32ec9f4ffaa8373658d289167b9d8e2a1 Mon Sep 17 00:00:00 2001 From: brido4125 Date: Tue, 2 Jul 2024 09:54:46 +0900 Subject: [PATCH] FIX: Concurrency problem in locator allNodes. --- .../java/net/spy/memcached/ArcusKetamaNodeLocator.java | 8 +++++--- .../net/spy/memcached/ArcusReplKetamaNodeLocator.java | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/spy/memcached/ArcusKetamaNodeLocator.java b/src/main/java/net/spy/memcached/ArcusKetamaNodeLocator.java index 66aa7be4b..70246ad76 100644 --- a/src/main/java/net/spy/memcached/ArcusKetamaNodeLocator.java +++ b/src/main/java/net/spy/memcached/ArcusKetamaNodeLocator.java @@ -41,7 +41,7 @@ public class ArcusKetamaNodeLocator extends SpyObject implements NodeLocator { private final TreeMap> ketamaNodes; - private final Collection allNodes; + private Collection allNodes; /* ENABLE_MIGRATION if */ private TreeMap> ketamaAlterNodes; @@ -206,15 +206,16 @@ public void update(Collection toAttach, Collection toDelete) { lock.lock(); try { + ArrayList newAllNodes = new ArrayList<>(allNodes); // Add memcached nodes. for (MemcachedNode node : toAttach) { - allNodes.add(node); + newAllNodes.add(node); insertHash(node); } // Remove memcached nodes. for (MemcachedNode node : toDelete) { - allNodes.remove(node); + newAllNodes.remove(node); removeHash(node); try { node.closeChannel(); @@ -223,6 +224,7 @@ public void update(Collection toAttach, "Failed to closeChannel the node : " + node); } } + allNodes = newAllNodes; } finally { /* ENABLE_MIGRATION if */ if (migrationInProgress && alterNodes.isEmpty()) { diff --git a/src/main/java/net/spy/memcached/ArcusReplKetamaNodeLocator.java b/src/main/java/net/spy/memcached/ArcusReplKetamaNodeLocator.java index a01259aca..55a721dbc 100644 --- a/src/main/java/net/spy/memcached/ArcusReplKetamaNodeLocator.java +++ b/src/main/java/net/spy/memcached/ArcusReplKetamaNodeLocator.java @@ -42,7 +42,7 @@ public class ArcusReplKetamaNodeLocator extends SpyObject implements NodeLocator private final TreeMap> ketamaGroups; private final HashMap allGroups; - private final Collection allNodes; + private Collection allNodes; /* ENABLE_MIGRATION if */ private TreeMap> ketamaAlterGroups; @@ -251,9 +251,10 @@ public void update(Collection toAttach, */ lock.lock(); try { + ArrayList newAllNodes = new ArrayList<>(allNodes); // Remove memcached nodes. for (MemcachedNode node : toDelete) { - allNodes.remove(node); + newAllNodes.remove(node); removeNodeFromGroup(node); try { node.closeChannel(); @@ -269,7 +270,7 @@ public void update(Collection toAttach, // Add memcached nodes. for (MemcachedNode node : toAttach) { - allNodes.add(node); + newAllNodes.add(node); insertNodeIntoGroup(node); } @@ -280,6 +281,7 @@ public void update(Collection toAttach, removeHash(group); } toDeleteGroups.clear(); + allNodes = newAllNodes; } finally { /* ENABLE_MIGRATION if */ if (migrationInProgress && alterNodes.isEmpty()) {