IGNITE-14473 Fixed IgniteRunner start flow. Fixes #83
Signed-off-by: Slava Koptilin <slava.koptilin@gmail.com>
diff --git a/modules/rest/src/main/java/org/apache/ignite/rest/RestModule.java b/modules/rest/src/main/java/org/apache/ignite/rest/RestModule.java
index 37580cb..4fdf732 100644
--- a/modules/rest/src/main/java/org/apache/ignite/rest/RestModule.java
+++ b/modules/rest/src/main/java/org/apache/ignite/rest/RestModule.java
@@ -21,6 +21,8 @@
import com.google.gson.JsonSyntaxException;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
@@ -28,6 +30,7 @@
import io.netty.handler.codec.http.HttpHeaderValues;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
+import java.net.BindException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
@@ -86,7 +89,7 @@
/**
*
*/
- public void start() throws InterruptedException {
+ public ChannelFuture start() throws InterruptedException {
var router = new Router();
router
.get(CONF_URL, (req, resp) -> {
@@ -145,11 +148,11 @@
}
});
- startRestEndpoint(router);
+ return startRestEndpoint(router);
}
/** */
- private void startRestEndpoint(Router router) throws InterruptedException {
+ private ChannelFuture startRestEndpoint(Router router) throws InterruptedException {
RestView restConfigurationView = sysConf.getConfiguration(RestConfiguration.KEY).value();
int desiredPort = restConfigurationView.port();
@@ -157,59 +160,55 @@
int port = 0;
- if (portRange == 0) {
- try {
- port = desiredPort;
- }
- catch (RuntimeException e) {
- log.warn("Failed to start REST endpoint: ", e);
+ Channel ch = null;
- throw e;
- }
- }
- else {
- int startPort = desiredPort;
+ EventLoopGroup parentGrp = new NioEventLoopGroup();
+ EventLoopGroup childGrp = new NioEventLoopGroup();
- for (int portCandidate = startPort; portCandidate < startPort + portRange; portCandidate++) {
- try {
- port = (portCandidate);
- }
- catch (RuntimeException ignored) {
- // No-op.
- }
- }
-
- if (port == 0) {
- String msg = "Cannot start REST endpoint. " +
- "All ports in range [" + startPort + ", " + (startPort + portRange) + "] are in use.";
-
- log.warn(msg);
-
- throw new RuntimeException(msg);
- }
- }
-
- EventLoopGroup bossGrp = new NioEventLoopGroup(1);
- EventLoopGroup workerGrp = new NioEventLoopGroup();
var hnd = new RestApiInitializer(router);
- try {
- ServerBootstrap b = new ServerBootstrap();
- b.option(ChannelOption.SO_BACKLOG, 1024);
- b.group(bossGrp, workerGrp)
- .channel(NioServerSocketChannel.class)
- .handler(new LoggingHandler(LogLevel.INFO))
- .childHandler(hnd);
- Channel ch = b.bind(port).sync().channel();
+ ServerBootstrap b = new ServerBootstrap();
+ b.option(ChannelOption.SO_BACKLOG, 1024);
+ b.group(parentGrp, childGrp)
+ .channel(NioServerSocketChannel.class)
+ .handler(new LoggingHandler(LogLevel.INFO))
+ .childHandler(hnd);
- if (log.isInfoEnabled())
- log.info("REST protocol started successfully on port " + port);
+ for (int portCandidate = desiredPort; portCandidate < desiredPort + portRange; portCandidate++) {
+ ChannelFuture bindRes = b.bind(portCandidate).await();
+ if (bindRes.isSuccess()) {
+ ch = bindRes.channel();
- ch.closeFuture().sync();
+ ch.closeFuture().addListener(new ChannelFutureListener() {
+ @Override public void operationComplete(ChannelFuture fut) {
+ parentGrp.shutdownGracefully();
+ childGrp.shutdownGracefully();
+ }
+ });
+ port = portCandidate;
+ break;
+ }
+ else if (!(bindRes.cause() instanceof BindException)) {
+ parentGrp.shutdownGracefully();
+ childGrp.shutdownGracefully();
+ throw new RuntimeException(bindRes.cause());
+ }
}
- finally {
- bossGrp.shutdownGracefully();
- workerGrp.shutdownGracefully();
+
+ if (ch == null) {
+ String msg = "Cannot start REST endpoint. " +
+ "All ports in range [" + desiredPort + ", " + (desiredPort + portRange) + "] are in use.";
+
+ log.error(msg);
+
+ parentGrp.shutdownGracefully();
+ childGrp.shutdownGracefully();
+
+ throw new RuntimeException(msg);
}
+
+ log.info("REST protocol started successfully on port " + port);
+
+ return ch.closeFuture();
}
}
diff --git a/modules/runner/src/main/java/org/apache/ignite/app/IgniteRunner.java b/modules/runner/src/main/java/org/apache/ignite/app/IgniteRunner.java
index 15854b9..d741fb7 100644
--- a/modules/runner/src/main/java/org/apache/ignite/app/IgniteRunner.java
+++ b/modules/runner/src/main/java/org/apache/ignite/app/IgniteRunner.java
@@ -17,6 +17,7 @@
package org.apache.ignite.app;
+import io.netty.channel.ChannelFuture;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
@@ -98,9 +99,8 @@
String str;
- while ((str = confReader.readLine()) != null) {
+ while ((str = confReader.readLine()) != null)
bldr.append(str);
- }
restModule.prepareStart(confModule.configurationRegistry());
@@ -111,9 +111,11 @@
confReader.close();
}
- restModule.start();
+ ChannelFuture restChFut = restModule.start();
ackSuccessStart();
+
+ restChFut.sync();
}
/** */