IGNITE-8858 Fixed client node hanging on stop() method - Fixes #4247. Signed-off-by: Alexey Goncharuk <alexey.goncha...@gmail.com>
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/1caebb8b Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/1caebb8b Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/1caebb8b Branch: refs/heads/ignite-8900-repro Commit: 1caebb8b69e55afe4c7a10329b6314419b2906da Parents: ededf0e Author: dkarachentsev <dkarachent...@gridgain.com> Authored: Fri Jun 29 18:54:54 2018 +0300 Committer: Alexey Goncharuk <alexey.goncha...@gmail.com> Committed: Fri Jun 29 18:54:54 2018 +0300 ---------------------------------------------------------------------- .../ignite/internal/util/IgniteUtils.java | 20 +++++++++++++++++--- .../ignite/spi/discovery/tcp/ClientImpl.java | 12 +++++++++++- 2 files changed, 28 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/1caebb8b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java index e02fe43..62d1117 100755 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java @@ -4603,11 +4603,24 @@ public abstract class IgniteUtils { * @return {@code true} if thread has finished, {@code false} otherwise. */ public static boolean join(@Nullable Thread t, @Nullable IgniteLogger log) { - if (t != null) + return join(t, log, 0); + } + + /** + * Waits for completion of a given thread. If thread is {@code null} then + * this method returns immediately returning {@code true} + * + * @param t Thread to join. + * @param log Logger for logging errors. + * @param timeout Join timeout. + * @return {@code true} if thread has finished, {@code false} otherwise. + */ + public static boolean join(@Nullable Thread t, @Nullable IgniteLogger log, long timeout) { + if (t != null) { try { - t.join(); + t.join(timeout); - return true; + return !t.isAlive(); } catch (InterruptedException ignore) { warn(log, "Got interrupted while waiting for completion of a thread: " + t); @@ -4616,6 +4629,7 @@ public abstract class IgniteUtils { return false; } + } return true; } http://git-wip-us.apache.org/repos/asf/ignite/blob/1caebb8b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index dc62bf3..edb2ce8 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -20,6 +20,7 @@ package org.apache.ignite.spi.discovery.tcp; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.InterruptedIOException; import java.io.StreamCorruptedException; import java.net.InetSocketAddress; import java.net.Socket; @@ -51,6 +52,7 @@ import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteClientDisconnectedException; import org.apache.ignite.IgniteException; +import org.apache.ignite.IgniteInterruptedException; import org.apache.ignite.IgniteLogger; import org.apache.ignite.IgniteSystemProperties; import org.apache.ignite.cache.CacheMetrics; @@ -326,7 +328,10 @@ class ClientImpl extends TcpDiscoveryImpl { U.join(msgWorker.runner(), log); U.join(sockWriter, log); - U.join(sockReader, log); + + // SocketReader may loose interruption, this hack is made to overcome that case. + while (!U.join(sockReader, log, 200)) + U.interrupt(sockReader); timer.cancel(); @@ -1071,6 +1076,11 @@ class ClientImpl extends TcpDiscoveryImpl { U.error(log, "Failed to read message [sock=" + sock + ", " + "locNodeId=" + getLocalNodeId() + ", rmtNodeId=" + rmtNodeId + ']', e); + // Exists possibility that exception raised on interruption. + if (X.hasCause(e, InterruptedException.class, InterruptedIOException.class, + IgniteInterruptedCheckedException.class, IgniteInterruptedException.class)) + interrupt(); + IOException ioEx = X.cause(e, IOException.class); if (ioEx != null)