This is an automated email from the ASF dual-hosted git repository.

sdanilov pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new c9bff85d94 IGNITE-19420 Remove a node from Logical Topology  as soon 
as it leaves Physical Topology (#2026)
c9bff85d94 is described below

commit c9bff85d94b9cd0fcc6eb3812bf32e1511bf8afe
Author: Roman Puchkovskiy <[email protected]>
AuthorDate: Mon May 8 10:09:11 2023 +0400

    IGNITE-19420 Remove a node from Logical Topology  as soon as it leaves 
Physical Topology (#2026)
---
 .../internal/cli/CliIntegrationTestBase.java       |  5 +--
 .../call/CallInitializedIntegrationTestBase.java   |  2 +-
 .../management/ClusterManagementGroupManager.java  | 12 +-----
 .../ClusterManagementConfigurationSchema.java      |  8 ----
 .../management/BaseItClusterManagementTest.java    |  4 +-
 .../impl/ItMetaStorageMultipleNodesTest.java       |  2 +-
 .../ignite/internal/rest/cluster/RestTestBase.java |  2 +-
 .../internal/ClusterPerTestIntegrationTest.java    | 32 +++-----------
 .../internal/compute/ItLogicalTopologyTest.java    | 49 ++++++++++------------
 9 files changed, 36 insertions(+), 80 deletions(-)

diff --git 
a/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/CliIntegrationTestBase.java
 
b/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/CliIntegrationTestBase.java
index 286ca728b8..df3508ef39 100644
--- 
a/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/CliIntegrationTestBase.java
+++ 
b/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/CliIntegrationTestBase.java
@@ -43,7 +43,7 @@ import org.junit.jupiter.api.TestInstance;
  */
 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
 @MicronautTest(rebuildContext = true)
-public class CliIntegrationTestBase extends IntegrationTestBase {
+public abstract class CliIntegrationTestBase extends IntegrationTestBase {
     /**
      * Template for node bootstrap config with Scalecube and Logical Topology 
settings for fast failure detection.
      */
@@ -62,8 +62,7 @@ public class CliIntegrationTestBase extends 
IntegrationTestBase {
             + "        gossipInterval: 10\n"
             + "      },\n"
             + "    }\n"
-            + "  },"
-            + "  cluster.failoverTimeout: 100\n"
+            + "  }\n"
             + "}";
 
 
diff --git 
a/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/call/CallInitializedIntegrationTestBase.java
 
b/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/call/CallInitializedIntegrationTestBase.java
index 7f6ee95d3d..eab6b86a97 100644
--- 
a/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/call/CallInitializedIntegrationTestBase.java
+++ 
b/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/call/CallInitializedIntegrationTestBase.java
@@ -28,7 +28,7 @@ import org.junit.jupiter.api.TestInfo;
 /**
  * Base class for call integration tests that needs initialized ignite 
cluster. Contains common methods and useful assertions.
  */
-public class CallInitializedIntegrationTestBase extends CliIntegrationTestBase 
{
+public abstract class CallInitializedIntegrationTestBase extends 
CliIntegrationTestBase {
     protected UrlCallInput urlInput;
 
     @BeforeAll
diff --git 
a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/ClusterManagementGroupManager.java
 
b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/ClusterManagementGroupManager.java
index 93a4bf7352..4b737de7bc 100644
--- 
a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/ClusterManagementGroupManager.java
+++ 
b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/ClusterManagementGroupManager.java
@@ -634,21 +634,11 @@ public class ClusterManagementGroupManager implements 
IgniteComponent {
 
             @Override
             public void onDisappeared(ClusterNode member) {
-                scheduleRemoveFromLogicalTopology(raftService, member);
+                raftService.removeFromCluster(Set.of(member));
             }
         };
     }
 
-    private void scheduleRemoveFromLogicalTopology(CmgRaftService raftService, 
ClusterNode node) {
-        scheduledExecutor.schedule(() -> {
-            ClusterNode physicalTopologyNode = 
clusterService.topologyService().getByConsistentId(node.name());
-
-            if (physicalTopologyNode == null || 
!physicalTopologyNode.id().equals(node.id())) {
-                raftService.removeFromCluster(Set.of(node));
-            }
-        }, configuration.failoverTimeout().value(), TimeUnit.MILLISECONDS);
-    }
-
     private void sendClusterState(CmgRaftService raftService, ClusterNode 
node) {
         sendClusterState(raftService, List.of(node));
     }
diff --git 
a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/configuration/ClusterManagementConfigurationSchema.java
 
b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/configuration/ClusterManagementConfigurationSchema.java
index 7482bbed5c..33a9ab64db 100644
--- 
a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/configuration/ClusterManagementConfigurationSchema.java
+++ 
b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/configuration/ClusterManagementConfigurationSchema.java
@@ -17,7 +17,6 @@
 
 package org.apache.ignite.internal.cluster.management.configuration;
 
-import java.util.concurrent.TimeUnit;
 import org.apache.ignite.configuration.annotation.ConfigurationRoot;
 import org.apache.ignite.configuration.annotation.ConfigurationType;
 import org.apache.ignite.configuration.annotation.Value;
@@ -32,11 +31,4 @@ public class ClusterManagementConfigurationSchema {
     @Value(hasDefault = true)
     @Range(min = 1)
     public long networkInvokeTimeout = 500;
-
-    /**
-     * Delay between a moment a node drops out from the physical topology and 
when it gets removed from the logical topology (ms).
-     */
-    @Value(hasDefault = true)
-    @Range(min = 0)
-    public long failoverTimeout = TimeUnit.SECONDS.toMillis(30);
 }
diff --git 
a/modules/cluster-management/src/testFixtures/java/org/apache/ignite/internal/cluster/management/BaseItClusterManagementTest.java
 
b/modules/cluster-management/src/testFixtures/java/org/apache/ignite/internal/cluster/management/BaseItClusterManagementTest.java
index 9d2ba11566..0750ebb6fc 100644
--- 
a/modules/cluster-management/src/testFixtures/java/org/apache/ignite/internal/cluster/management/BaseItClusterManagementTest.java
+++ 
b/modules/cluster-management/src/testFixtures/java/org/apache/ignite/internal/cluster/management/BaseItClusterManagementTest.java
@@ -43,10 +43,10 @@ import org.junit.jupiter.api.extension.ExtendWith;
  * Base class for integration tests that use a cluster of {@link MockNode}s.
  */
 @ExtendWith(ConfigurationExtension.class)
-public class BaseItClusterManagementTest extends BaseIgniteAbstractTest {
+public abstract class BaseItClusterManagementTest extends 
BaseIgniteAbstractTest {
     private static final int PORT_BASE = 10000;
 
-    @InjectConfiguration("mock.failoverTimeout: 100")
+    @InjectConfiguration
     private static ClusterManagementConfiguration cmgConfiguration;
 
     @InjectConfiguration
diff --git 
a/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageMultipleNodesTest.java
 
b/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageMultipleNodesTest.java
index a094d4f880..5193d59a95 100644
--- 
a/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageMultipleNodesTest.java
+++ 
b/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageMultipleNodesTest.java
@@ -95,7 +95,7 @@ public class ItMetaStorageMultipleNodesTest extends 
IgniteAbstractTest {
     @InjectConfiguration
     private static RaftConfiguration raftConfiguration;
 
-    @InjectConfiguration("mock.failoverTimeout=0")
+    @InjectConfiguration
     private static ClusterManagementConfiguration cmgConfiguration;
 
     @InjectConfiguration
diff --git 
a/modules/rest/src/integrationTest/java/org/apache/ignite/internal/rest/cluster/RestTestBase.java
 
b/modules/rest/src/integrationTest/java/org/apache/ignite/internal/rest/cluster/RestTestBase.java
index e6994bb7f7..bfefa4067f 100644
--- 
a/modules/rest/src/integrationTest/java/org/apache/ignite/internal/rest/cluster/RestTestBase.java
+++ 
b/modules/rest/src/integrationTest/java/org/apache/ignite/internal/rest/cluster/RestTestBase.java
@@ -41,7 +41,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
  */
 @MicronautTest
 @ExtendWith(WorkDirectoryExtension.class)
-public class RestTestBase extends BaseItClusterManagementTest {
+public abstract class RestTestBase extends BaseItClusterManagementTest {
     static final List<MockNode> cluster = new ArrayList<>();
 
     static ClusterService clusterService;
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/ClusterPerTestIntegrationTest.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/ClusterPerTestIntegrationTest.java
index 3a38180d73..059c26d582 100644
--- 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/ClusterPerTestIntegrationTest.java
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/ClusterPerTestIntegrationTest.java
@@ -19,8 +19,6 @@ package org.apache.ignite.internal;
 
 import static 
org.apache.ignite.internal.sql.engine.util.CursorUtils.getAllFromCursor;
 
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
 import java.nio.file.Path;
 import java.util.List;
 import org.apache.ignite.Ignite;
@@ -38,7 +36,6 @@ import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.TestInfo;
 import org.junit.jupiter.api.Timeout;
-import org.junit.platform.commons.support.ReflectionSupport;
 
 /**
  * Abstract integration test that starts and stops a cluster per test method.
@@ -76,8 +73,7 @@ public abstract class ClusterPerTestIntegrationTest extends 
IgniteIntegrationTes
             + "        gossipInterval: 10\n"
             + "      },\n"
             + "    }\n"
-            + "  },"
-            + "  cluster.failoverTimeout: 100\n"
+            + "  }\n"
             + "}";
 
     protected Cluster cluster;
@@ -95,6 +91,10 @@ public abstract class ClusterPerTestIntegrationTest extends 
IgniteIntegrationTes
     @BeforeEach
     public void setup(TestInfo testInfo) throws Exception {
         setupBase(testInfo, workDir);
+
+        cluster = new Cluster(testInfo, workDir, 
getNodeBootstrapConfigTemplate());
+
+        cluster.startAndInit(initialNodes());
     }
 
     /**
@@ -104,30 +104,10 @@ public abstract class ClusterPerTestIntegrationTest 
extends IgniteIntegrationTes
      * @throws Exception If failed.
      */
     @AfterEach
+    @Timeout(60)
     public void tearDown(TestInfo testInfo) throws Exception {
         tearDownBase(testInfo);
-    }
-
-    @BeforeEach
-    void startAndInitCluster(TestInfo testInfo) {
-        cluster = new Cluster(testInfo, workDir, 
getNodeBootstrapConfigTemplate());
 
-        cluster.startAndInit(initialNodes());
-    }
-
-    private String invokeArglessMethod(Class<?> testClass, String methodName) {
-        Method method = ReflectionSupport.findMethod(testClass, 
methodName).orElseThrow();
-
-        if (!Modifier.isStatic(method.getModifiers())) {
-            throw new IllegalStateException(methodName + " is expected to be 
static");
-        }
-
-        return (String) ReflectionSupport.invokeMethod(method, null);
-    }
-
-    @AfterEach
-    @Timeout(60)
-    void shutdownCluster() {
         cluster.shutdown();
     }
 
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/compute/ItLogicalTopologyTest.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/compute/ItLogicalTopologyTest.java
index ad323a3463..e053ae4cf4 100644
--- 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/compute/ItLogicalTopologyTest.java
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/compute/ItLogicalTopologyTest.java
@@ -23,7 +23,6 @@ import static org.hamcrest.Matchers.empty;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.not;
 import static org.hamcrest.Matchers.notNullValue;
-import static org.hamcrest.Matchers.nullValue;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -41,10 +40,10 @@ import org.apache.ignite.Ignite;
 import org.apache.ignite.IgnitionManager;
 import org.apache.ignite.internal.ClusterPerTestIntegrationTest;
 import org.apache.ignite.internal.app.IgniteImpl;
-import 
org.apache.ignite.internal.cluster.management.configuration.ClusterManagementConfiguration;
 import org.apache.ignite.internal.cluster.management.topology.api.LogicalNode;
 import 
org.apache.ignite.internal.cluster.management.topology.api.LogicalTopologyEventListener;
 import 
org.apache.ignite.internal.cluster.management.topology.api.LogicalTopologySnapshot;
+import org.apache.ignite.internal.network.configuration.NetworkConfiguration;
 import org.apache.ignite.internal.network.message.ScaleCubeMessage;
 import org.apache.ignite.internal.tostring.S;
 import org.intellij.lang.annotations.Language;
@@ -72,8 +71,7 @@ class ItLogicalTopologyTest extends 
ClusterPerTestIntegrationTest {
             + "  },"
             + "  nodeAttributes: {\n"
             + "    nodeAttributes: " + NODE_ATTRIBUTES
-            + "  },\n"
-            + "  cluster.failoverTimeout: 100\n"
+            + "  }\n"
             + "}";
 
     private final LogicalTopologyEventListener listener = new 
LogicalTopologyEventListener() {
@@ -280,23 +278,21 @@ class ItLogicalTopologyTest extends 
ClusterPerTestIntegrationTest {
     }
 
     @Test
-    void nodeDoesNotLeaveLogicalTopologyImmediatelyAfterBeingLostBySwim() 
throws Exception {
+    void nodeLeavesLogicalTopologyImmediatelyAfterBeingLostBySwim() throws 
Exception {
         IgniteImpl entryNode = node(0);
 
-        setInfiniteClusterFailoverTimeout(entryNode);
-
-        startNode(1);
+        IgniteImpl secondNode = startNode(1);
 
         entryNode.logicalTopologyService().addEventListener(listener);
 
         // Knock the node out without allowing it to say good bye.
         cluster.simulateNetworkPartitionOf(1);
 
-        // 1 second is usually insufficient on my machine to get an event, 
even if it's produced. On the CI we
-        // should probably account for spurious delays due to other processes, 
hence 2 seconds.
-        Event event = events.poll(2, TimeUnit.SECONDS);
+        Event leaveEvent = events.poll(10, TimeUnit.SECONDS);
 
-        assertThat(event, is(nullValue()));
+        assertThat(leaveEvent, is(notNullValue()));
+        assertThat(leaveEvent.node.name(), is(secondNode.name()));
+        assertThat(leaveEvent.eventType, is(EventType.LEFT));
     }
 
     @Test
@@ -314,9 +310,6 @@ class ItLogicalTopologyTest extends 
ClusterPerTestIntegrationTest {
             }
         });
 
-        // Disable the failover timeout so that the CMG Raft group is 
immediately notified of a node leaving Physical Topology.
-        setZeroClusterFailoverTimeout(entryNode);
-
         cluster.startClusterNode(1);
 
         try {
@@ -338,9 +331,11 @@ class ItLogicalTopologyTest extends 
ClusterPerTestIntegrationTest {
     }
 
     @Test
-    void nodeLeavesLogicalTopologyOnStop() throws Exception {
+    void nodeLeavesLogicalTopologyImmediatelyOnGracefulStop() throws Exception 
{
         IgniteImpl entryNode = node(0);
 
+        disableNetworkFailureDetection(entryNode);
+
         IgniteImpl secondIgnite = startNode(1);
 
         entryNode.logicalTopologyService().addEventListener(listener);
@@ -357,17 +352,17 @@ class ItLogicalTopologyTest extends 
ClusterPerTestIntegrationTest {
         assertThat(leaveEvent.node.name(), is(secondIgnite.name()));
     }
 
-    private static void setInfiniteClusterFailoverTimeout(IgniteImpl node) 
throws Exception {
-        
node.nodeConfiguration().getConfiguration(ClusterManagementConfiguration.KEY)
-                .failoverTimeout()
-                .update(Long.MAX_VALUE)
-                .get(10, TimeUnit.SECONDS);
-    }
-
-    private static void setZeroClusterFailoverTimeout(IgniteImpl node) throws 
Exception {
-        
node.nodeConfiguration().getConfiguration(ClusterManagementConfiguration.KEY)
-                .failoverTimeout()
-                .update(0L)
+    /**
+     * Configures the given Ignite instance in a way that makes it impossible 
to notice (by itself) that another
+     * node has gone and is not reachable on the network anymore.
+     *
+     * @param node Ignite node to disable network failure detection at.
+     * @throws Exception If something goes wrong.
+     */
+    private static void disableNetworkFailureDetection(IgniteImpl node) throws 
Exception {
+        node.nodeConfiguration().getConfiguration(NetworkConfiguration.KEY)
+                .membership()
+                .change(membershipChange -> 
membershipChange.changeFailurePingInterval(Integer.MAX_VALUE))
                 .get(10, TimeUnit.SECONDS);
     }
 

Reply via email to