You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sk...@apache.org on 2021/04/16 14:37:25 UTC

[ignite-3] branch main updated: IGNITE-14473 Fixed IgniteRunner start flow. Fixes #83

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

sk0x50 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 346865b  IGNITE-14473 Fixed IgniteRunner start flow. Fixes #83
346865b is described below

commit 346865b7e04a0f70944fea8ed8c895b2aa353561
Author: Kirill Gusakov <kg...@gmail.com>
AuthorDate: Fri Apr 16 17:36:26 2021 +0300

    IGNITE-14473 Fixed IgniteRunner start flow. Fixes #83
    
    Signed-off-by: Slava Koptilin <sl...@gmail.com>
---
 .../java/org/apache/ignite/rest/RestModule.java    | 93 +++++++++++-----------
 .../java/org/apache/ignite/app/IgniteRunner.java   |  8 +-
 2 files changed, 51 insertions(+), 50 deletions(-)

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.JsonElement;
 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.channel.socket.nio.NioServerSocketChannel;
 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 class RestModule {
     /**
      *
      */
-    public void start() throws InterruptedException {
+    public ChannelFuture start() throws InterruptedException {
         var router = new Router();
         router
             .get(CONF_URL, (req, resp) -> {
@@ -145,11 +148,11 @@ public class RestModule {
                 }
             });
 
-        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 @@ public class RestModule {
 
         int port = 0;
 
-        if (portRange == 0) {
-            try {
-                port = desiredPort;
-            }
-            catch (RuntimeException e) {
-                log.warn("Failed to start REST endpoint: ", e);
-
-                throw e;
-            }
-        }
-        else {
-            int startPort = desiredPort;
+        Channel ch = null;
 
-            for (int portCandidate = startPort; portCandidate < startPort + portRange; portCandidate++) {
-                try {
-                    port = (portCandidate);
-                }
-                catch (RuntimeException ignored) {
-                    // No-op.
-                }
-            }
+        EventLoopGroup parentGrp = new NioEventLoopGroup();
+        EventLoopGroup childGrp = new NioEventLoopGroup();
 
-            if (port == 0) {
-                String msg = "Cannot start REST endpoint. " +
-                    "All ports in range [" + startPort + ", " + (startPort + portRange) + "] are in use.";
-
-                log.warn(msg);
+        var hnd = new RestApiInitializer(router);
 
-                throw new RuntimeException(msg);
+        ServerBootstrap b = new ServerBootstrap();
+        b.option(ChannelOption.SO_BACKLOG, 1024);
+        b.group(parentGrp, childGrp)
+            .channel(NioServerSocketChannel.class)
+            .handler(new LoggingHandler(LogLevel.INFO))
+            .childHandler(hnd);
+
+        for (int portCandidate = desiredPort; portCandidate < desiredPort + portRange; portCandidate++) {
+            ChannelFuture bindRes = b.bind(portCandidate).await();
+            if (bindRes.isSuccess()) {
+                ch = bindRes.channel();
+
+                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());
             }
         }
 
-        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);
+        if (ch == null) {
+            String msg = "Cannot start REST endpoint. " +
+                "All ports in range [" + desiredPort + ", " + (desiredPort + portRange) + "] are in use.";
 
-            Channel ch = b.bind(port).sync().channel();
+            log.error(msg);
 
-            if (log.isInfoEnabled())
-                log.info("REST protocol started successfully on port " + port);
+            parentGrp.shutdownGracefully();
+            childGrp.shutdownGracefully();
 
-            ch.closeFuture().sync();
-        }
-        finally {
-            bossGrp.shutdownGracefully();
-            workerGrp.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 @@ public class IgniteRunner {
 
             String str;
 
-            while ((str = confReader.readLine()) != null) {
+            while ((str = confReader.readLine()) != null)
                 bldr.append(str);
-            }
 
             restModule.prepareStart(confModule.configurationRegistry());
 
@@ -111,9 +111,11 @@ public class IgniteRunner {
                 confReader.close();
         }
 
-        restModule.start();
+        ChannelFuture restChFut = restModule.start();
 
         ackSuccessStart();
+
+        restChFut.sync();
     }
 
     /** */