diff --git a/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java b/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java index e515d007ce38..a7d09ab548f2 100644 --- a/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java +++ b/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java @@ -63,7 +63,9 @@ public class BuiltInServer implements Disposable { return port; } - static ServerBootstrap createServerBootstrap(EventLoopGroup eventLoopGroup, final ChannelRegistrar channelRegistrar, @Nullable Map xmlRpcHandlers) { + static ServerBootstrap createServerBootstrap(@NotNull EventLoopGroup eventLoopGroup, + @NotNull final ChannelRegistrar channelRegistrar, + @Nullable Map xmlRpcHandlers) { ServerBootstrap bootstrap = NettyUtil.nioServerBootstrap(eventLoopGroup); if (xmlRpcHandlers == null) { final PortUnificationServerHandler portUnificationServerHandler = new PortUnificationServerHandler(); diff --git a/platform/platform-impl/src/org/jetbrains/io/NettyUtil.java b/platform/platform-impl/src/org/jetbrains/io/NettyUtil.java index a9913bbedc09..644cb35dacc6 100644 --- a/platform/platform-impl/src/org/jetbrains/io/NettyUtil.java +++ b/platform/platform-impl/src/org/jetbrains/io/NettyUtil.java @@ -22,6 +22,7 @@ import io.netty.bootstrap.Bootstrap; import io.netty.bootstrap.BootstrapUtil; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoop; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.oio.OioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; @@ -67,9 +68,29 @@ public final class NettyUtil { } @Nullable - public static Channel connect(Bootstrap bootstrap, InetSocketAddress remoteAddress, ActionCallback asyncResult, int maxAttemptCount) { + public static Channel connect(@NotNull Bootstrap bootstrap, @NotNull InetSocketAddress remoteAddress, @NotNull ActionCallback asyncResult, int maxAttemptCount) { try { int attemptCount = 0; + + if (bootstrap.group() instanceof NioEventLoop) { + while (true) { + ChannelFuture future = bootstrap.connect(remoteAddress).awaitUninterruptibly(); + if (future.isSuccess()) { + return future.channel(); + } + else if (++attemptCount < maxAttemptCount) { + //noinspection BusyWait + Thread.sleep(attemptCount * MIN_START_TIME); + } + else { + @SuppressWarnings("ThrowableResultOfMethodCallIgnored") + Throwable cause = future.cause(); + asyncResult.reject("Cannot connect: " + (cause == null ? "unknown error" : cause.getMessage())); + return null; + } + } + } + Socket socket; while (true) { try { @@ -123,7 +144,7 @@ public final class NettyUtil { } } - public static ServerBootstrap nioServerBootstrap(EventLoopGroup eventLoopGroup) { + public static ServerBootstrap nioServerBootstrap(@NotNull EventLoopGroup eventLoopGroup) { ServerBootstrap bootstrap = new ServerBootstrap().group(eventLoopGroup).channel(NioServerSocketChannel.class); bootstrap.childOption(ChannelOption.TCP_NODELAY, true).childOption(ChannelOption.SO_KEEPALIVE, true); return bootstrap; @@ -137,7 +158,11 @@ public final class NettyUtil { @SuppressWarnings("UnusedDeclaration") public static Bootstrap nioClientBootstrap() { - Bootstrap bootstrap = new Bootstrap().group(new NioEventLoopGroup(1, PooledThreadExecutor.INSTANCE)).channel(NioSocketChannel.class); + return nioClientBootstrap(new NioEventLoopGroup(1, PooledThreadExecutor.INSTANCE)); + } + + public static Bootstrap nioClientBootstrap(@NotNull EventLoopGroup eventLoopGroup) { + Bootstrap bootstrap = new Bootstrap().group(eventLoopGroup).channel(NioSocketChannel.class); bootstrap.option(ChannelOption.TCP_NODELAY, true).option(ChannelOption.SO_KEEPALIVE, true); return bootstrap; }