From 43e855ab8c60a952c1f56038b396c82185836006 Mon Sep 17 00:00:00 2001 From: olim7t Date: Fri, 27 Oct 2017 10:54:36 -0700 Subject: [PATCH] Fix bug in DefaultSession If a node's distance was set to IGNORED but it was already IGNORED, the session would open a new pool. --- .../internal/core/session/DefaultSession.java | 2 +- .../core/session/DefaultSessionTest.java | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/session/DefaultSession.java b/core/src/main/java/com/datastax/oss/driver/internal/core/session/DefaultSession.java index fc9363c15bd..23c3d7d301c 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/session/DefaultSession.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/session/DefaultSession.java @@ -326,7 +326,7 @@ private void processDistanceEvent(DistanceEvent event) { NodeDistance newDistance = event.distance; if (pending.containsKey(node)) { pendingDistanceEvents.put(node, event); - } else if (newDistance == NodeDistance.IGNORED && pools.containsKey(node)) { + } else if (newDistance == NodeDistance.IGNORED) { ChannelPool pool = pools.remove(node); if (pool != null) { LOG.debug("[{}] {} became IGNORED, destroying pool", logPrefix, node); diff --git a/core/src/test/java/com/datastax/oss/driver/internal/core/session/DefaultSessionTest.java b/core/src/test/java/com/datastax/oss/driver/internal/core/session/DefaultSessionTest.java index 7aceff1ec83..d6240d99bd8 100644 --- a/core/src/test/java/com/datastax/oss/driver/internal/core/session/DefaultSessionTest.java +++ b/core/src/test/java/com/datastax/oss/driver/internal/core/session/DefaultSessionTest.java @@ -365,6 +365,38 @@ public void should_remove_pool_if_node_becomes_ignored() { assertThat(((DefaultSession) session).getPools()).containsValues(pool1, pool3); } + @Test + public void should_do_nothing_if_node_becomes_ignored_but_was_already_ignored() { + ChannelPool pool1 = mockPool(node1); + ChannelPool pool2 = mockPool(node2); + ChannelPool pool3 = mockPool(node3); + MockChannelPoolFactoryHelper factoryHelper = + MockChannelPoolFactoryHelper.builder(channelPoolFactory) + .success(node1, KEYSPACE, NodeDistance.LOCAL, pool1) + .success(node2, KEYSPACE, NodeDistance.LOCAL, pool2) + .success(node3, KEYSPACE, NodeDistance.LOCAL, pool3) + .build(); + + CompletionStage initFuture = DefaultSession.init(context, KEYSPACE, "test"); + + factoryHelper.waitForCall(node1, KEYSPACE, NodeDistance.LOCAL); + factoryHelper.waitForCall(node2, KEYSPACE, NodeDistance.LOCAL); + factoryHelper.waitForCall(node3, KEYSPACE, NodeDistance.LOCAL); + waitForPendingAdminTasks(); + assertThat(initFuture).isSuccess(); + + eventBus.fire(new DistanceEvent(NodeDistance.IGNORED, node2)); + Mockito.verify(pool2, timeout(100)).closeAsync(); + + Session session = CompletableFutures.getCompleted(initFuture.toCompletableFuture()); + assertThat(((DefaultSession) session).getPools()).containsValues(pool1, pool3); + + // Fire the same event again, nothing should happen + eventBus.fire(new DistanceEvent(NodeDistance.IGNORED, node2)); + waitForPendingAdminTasks(); + factoryHelper.verifyNoMoreCalls(); + } + @Test public void should_recreate_pool_if_node_becomes_not_ignored() { Mockito.when(node2.getDistance()).thenReturn(NodeDistance.IGNORED);