This is an automated email from the ASF dual-hosted git repository. apkhmv 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 933cad608b IGNITE-20819 Use shared lock on HTTP server startup (#2823) 933cad608b is described below commit 933cad608b8ce71dad3ee70ec35b6663b4e96df3 Author: Aleksandr Pakhomov <apk...@gmail.com> AuthorDate: Thu Nov 9 15:54:58 2023 +0400 IGNITE-20819 Use shared lock on HTTP server startup (#2823) It happens because of the race conditions inside the micronaut. https://github.com/micronaut-projects/micronaut-core/issues/10091 --- .../apache/ignite/internal/rest/RestComponent.java | 45 +++++++++++++--------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/modules/rest/src/main/java/org/apache/ignite/internal/rest/RestComponent.java b/modules/rest/src/main/java/org/apache/ignite/internal/rest/RestComponent.java index 39f0569be2..e386fa65c0 100644 --- a/modules/rest/src/main/java/org/apache/ignite/internal/rest/RestComponent.java +++ b/modules/rest/src/main/java/org/apache/ignite/internal/rest/RestComponent.java @@ -51,6 +51,11 @@ import org.jetbrains.annotations.Nullable; * resources for the example. */ public class RestComponent implements IgniteComponent { + /** + * Lock for micronaut server startup. + * TODO: remove when fix https://github.com/micronaut-projects/micronaut-core/issues/10091 + */ + private static final Object SHARED_STARTUP_LOCK = new Object(); /** Unavailable port. */ private static final int UNAVAILABLE_PORT = -1; @@ -70,10 +75,10 @@ public class RestComponent implements IgniteComponent { private volatile ApplicationContext context; /** Server port. */ - private int httpPort = UNAVAILABLE_PORT; + private volatile int httpPort = UNAVAILABLE_PORT; /** Server SSL port. */ - private int httpsPort = UNAVAILABLE_PORT; + private volatile int httpsPort = UNAVAILABLE_PORT; /** * Creates a new instance of REST module. @@ -114,23 +119,27 @@ public class RestComponent implements IgniteComponent { * @param dualProtocol Dual protocol flag. * @return {@code True} if server was started successfully, {@code False} if couldn't bind one of the ports. */ - private synchronized boolean startServer(int httpPortCandidate, int httpsPortCandidate, boolean sslEnabled, boolean dualProtocol) { - try { - httpPort = httpPortCandidate; - httpsPort = httpsPortCandidate; - context = buildMicronautContext(httpPortCandidate, httpsPortCandidate) - .deduceEnvironment(false) - .environments(BARE_METAL) - .start(); - - logSuccessRestStart(sslEnabled, dualProtocol); - return true; - } catch (ApplicationStartupException e) { - BindException bindException = findBindException(e); - if (bindException != null) { - return false; + private boolean startServer(int httpPortCandidate, int httpsPortCandidate, boolean sslEnabled, boolean dualProtocol) { + // Workaround to avoid micronaut race condition on startup. + synchronized (SHARED_STARTUP_LOCK) { + try { + httpPort = httpPortCandidate; + httpsPort = httpsPortCandidate; + + context = buildMicronautContext(httpPortCandidate, httpsPortCandidate) + .deduceEnvironment(false) + .environments(BARE_METAL) + .start(); + + logSuccessRestStart(sslEnabled, dualProtocol); + return true; + } catch (ApplicationStartupException e) { + BindException bindException = findBindException(e); + if (bindException != null) { + return false; + } + throw new IgniteException(Common.COMPONENT_NOT_STARTED_ERR, e); } - throw new IgniteException(Common.COMPONENT_NOT_STARTED_ERR, e); } }