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