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)

Reply via email to