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

mpochatkin 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 eace6b1c681 IGNITE-26579 Wait for join after start automatically 
(#6700)
eace6b1c681 is described below

commit eace6b1c681be04adec4bbc9f12b83660f878b77
Author: Vadim Pakhnushev <[email protected]>
AuthorDate: Thu Oct 9 10:04:42 2025 +0300

    IGNITE-26579 Wait for join after start automatically (#6700)
---
 .../internal/runner/app/ItIgniteServerTest.java    | 26 +++++++++--
 .../ignite/internal/app/IgniteServerImpl.java      | 54 ++++++++++------------
 2 files changed, 47 insertions(+), 33 deletions(-)

diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItIgniteServerTest.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItIgniteServerTest.java
index 158ce22cbe9..52ad2387602 100644
--- 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItIgniteServerTest.java
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItIgniteServerTest.java
@@ -150,7 +150,7 @@ class ItIgniteServerTest extends BaseIgniteAbstractTest {
     }
 
     /**
-     * Check that EmbeddedNode.start() with bootstrap configuration returns a 
node and its api() method returns Ignite instance after init.
+     * Check that IgniteServer.start() with bootstrap configuration returns a 
node and its api() method returns Ignite instance after init.
      */
     @Test
     void testNodesStartWithBootstrapConfigurationInitializedCluster() {
@@ -171,14 +171,32 @@ class ItIgniteServerTest extends BaseIgniteAbstractTest {
         assertThat(igniteServer.api(), notNullValue());
 
         startedIgniteServers.forEach(node -> {
-            if (node != igniteServer) {
-                assertThrowsWithCause(node::api, 
ClusterNotInitializedException.class, "Cluster is not initialized.");
-            }
             assertThat(node.waitForInitAsync(), willCompleteSuccessfully());
             assertThat(node.api(), notNullValue());
         });
     }
 
+    /**
+     * Check that cluster can be initialized even if nodes in the metastorage 
group doesn't call waitForInitAsync.
+     */
+    @Test
+    void testClusterInitWithoutWait() {
+        for (Map.Entry<String, String> e : nodesBootstrapCfg.entrySet()) {
+            startAndRegisterNode(e.getKey(), name -> startNode(name, 
e.getValue()));
+        }
+
+        assertThat(startedIgniteServers, hasSize(3));
+
+        IgniteServer igniteServer = startedIgniteServers.get(0);
+
+        // Initialize the cluster with all nodes in the metastorage group
+        InitParameters initParameters = InitParameters.builder()
+                .metaStorageNodes(startedIgniteServers)
+                .clusterName("cluster")
+                .build();
+        assertThat(igniteServer.initClusterAsync(initParameters), 
willCompleteSuccessfully());
+    }
+
     /**
      * Tests scenario when we try to start node with invalid configuration.
      */
diff --git 
a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteServerImpl.java
 
b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteServerImpl.java
index 264fe726a90..2e85d361750 100644
--- 
a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteServerImpl.java
+++ 
b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteServerImpl.java
@@ -19,9 +19,7 @@ package org.apache.ignite.internal.app;
 
 import static java.lang.System.lineSeparator;
 import static java.util.Objects.requireNonNull;
-import static java.util.concurrent.CompletableFuture.completedFuture;
 import static java.util.concurrent.CompletableFuture.failedFuture;
-import static java.util.function.Function.identity;
 import static 
org.apache.ignite.internal.util.CompletableFutures.nullCompletedFuture;
 import static 
org.apache.ignite.internal.util.ExceptionUtils.copyExceptionWithCause;
 import static org.apache.ignite.internal.util.ExceptionUtils.sneakyThrow;
@@ -228,29 +226,11 @@ public class IgniteServerImpl implements IgniteServer {
 
     @Override
     public CompletableFuture<Void> waitForInitAsync() {
-        IgniteImpl instance = ignite;
-        if (instance == null) {
-            throw new NodeNotStartedException();
-        }
-
         CompletableFuture<Void> joinFuture = this.joinFuture;
         if (joinFuture == null) {
-            try {
-                joinFuture = instance.joinClusterAsync()
-                        .handle((ignite, e) -> {
-                            if (e == null) {
-                                ackSuccessStart();
-
-                                return null;
-                            } else {
-                                throw handleStartException(e);
-                            }
-                        });
-            } catch (Exception e) {
-                throw handleStartException(e);
-            }
-            this.joinFuture = joinFuture;
+            throw new NodeNotStartedException();
         }
+
         return joinFuture;
     }
 
@@ -401,11 +381,7 @@ public class IgniteServerImpl implements IgniteServer {
 
         ackRemoteManagement();
 
-        return instance.startAsync().handle((result, throwable) -> {
-            if (throwable != null) {
-                return CompletableFuture.<Void>failedFuture(throwable);
-            }
-
+        return instance.startAsync().thenCompose(unused -> {
             synchronized (igniteChangeMutex) {
                 if (shutDown) {
                     LOG.info("A new Ignite instance has started, but a 
shutdown is requested, so not setting it, stopping it instead "
@@ -414,12 +390,32 @@ public class IgniteServerImpl implements IgniteServer {
                     return instance.stopAsync();
                 }
 
+                LOG.info("Initiating join process [name={}]", nodeName);
+                doWaitForInitAsync(instance);
+
                 LOG.info("Setting Ignite ref to new instance as it has started 
[name={}]", nodeName);
                 ignite = instance;
             }
 
-            return completedFuture(result);
-        }).thenCompose(identity());
+            return nullCompletedFuture();
+        });
+    }
+
+    private void doWaitForInitAsync(IgniteImpl instance) {
+        try {
+            joinFuture = instance.joinClusterAsync()
+                    .handle((ignite, e) -> {
+                        if (e == null) {
+                            ackSuccessStart();
+
+                            return null;
+                        } else {
+                            throw handleStartException(e);
+                        }
+                    });
+        } catch (Exception e) {
+            throw handleStartException(e);
+        }
     }
 
     @Override

Reply via email to