You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2015/07/03 12:27:53 UTC

incubator-ignite git commit: # ignite-901 WIP

Repository: incubator-ignite
Updated Branches:
  refs/heads/ignite-901 623ddd9bc -> 807ceb380


# ignite-901 WIP


Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/807ceb38
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/807ceb38
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/807ceb38

Branch: refs/heads/ignite-901
Commit: 807ceb380b4d3476b4239ebfa7660c3bb80e0bf6
Parents: 623ddd9
Author: sboikov <sb...@gridgain.com>
Authored: Fri Jul 3 12:22:22 2015 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Fri Jul 3 13:14:24 2015 +0300

----------------------------------------------------------------------
 .../IgniteClientDisconnectedException.java      |  21 +++-
 .../java/org/apache/ignite/IgniteCluster.java   |   5 +
 .../apache/ignite/internal/GridComponent.java   |   8 +-
 .../ignite/internal/GridKernalGateway.java      |   6 +-
 .../ignite/internal/GridKernalGatewayImpl.java  |  79 +++++++-------
 .../ignite/internal/GridPluginComponent.java    |   3 +-
 ...gniteClientDisconnectedCheckedException.java |  16 ++-
 .../apache/ignite/internal/IgniteKernal.java    |  82 ++++++++++----
 .../cluster/IgniteClusterAsyncImpl.java         |   5 +
 .../internal/cluster/IgniteClusterImpl.java     |  15 +++
 .../internal/managers/GridManagerAdapter.java   |   2 +-
 .../deployment/GridDeploymentManager.java       |   2 +-
 .../discovery/GridDiscoveryManager.java         |   2 +-
 .../processors/GridProcessorAdapter.java        |   3 +-
 .../processors/cache/GridCacheGateway.java      |  82 +++++---------
 .../processors/cache/GridCacheMvccManager.java  |   9 +-
 .../GridCachePartitionExchangeManager.java      |  74 ++++++-------
 .../processors/cache/GridCacheProcessor.java    |  10 +-
 .../processors/cache/GridCacheUtils.java        |   8 ++
 .../continuous/GridContinuousProcessor.java     |   2 +-
 .../service/GridServiceProcessor.java           |   9 +-
 .../ignite/internal/util/IgniteUtils.java       |   5 +-
 .../internal/GridUpdateNotifierSelfTest.java    |   5 +-
 .../IgniteClientReconnectCacheTest.java         |  29 +++--
 .../internal/IgniteClientReconnectStopTest.java | 107 +++++++++++++++++++
 .../IgniteClientReconnectTestSuite.java         |   1 +
 26 files changed, 397 insertions(+), 193 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/main/java/org/apache/ignite/IgniteClientDisconnectedException.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteClientDisconnectedException.java b/modules/core/src/main/java/org/apache/ignite/IgniteClientDisconnectedException.java
index 9500ac2..cf04e95 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteClientDisconnectedException.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteClientDisconnectedException.java
@@ -17,17 +17,36 @@
 
 package org.apache.ignite;
 
+import org.apache.ignite.lang.*;
 import org.jetbrains.annotations.*;
 
 /**
  *
  */
 public class IgniteClientDisconnectedException extends IgniteException {
+    /** */
+    private final IgniteFuture<?> reconnectFut;
+
     /**
+     * @param reconnectFut Reconnect future.
      * @param msg Error message.
      * @param cause Optional nested exception (can be {@code null}).
      */
-    public IgniteClientDisconnectedException(String msg, @Nullable Throwable cause) {
+    public IgniteClientDisconnectedException(
+        IgniteFuture<?> reconnectFut,
+        String msg,
+        @Nullable Throwable cause) {
         super(msg, cause);
+
+        assert reconnectFut != null;
+
+        this.reconnectFut = reconnectFut;
+    }
+
+    /**
+     * @return Future that will be completed when client reconnected.
+     */
+    public IgniteFuture<?> reconnectFuture() {
+        return reconnectFut;
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/main/java/org/apache/ignite/IgniteCluster.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteCluster.java b/modules/core/src/main/java/org/apache/ignite/IgniteCluster.java
index 72be3fb..d3ce0e7 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteCluster.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteCluster.java
@@ -328,6 +328,11 @@ public interface IgniteCluster extends ClusterGroup, IgniteAsyncSupport {
      */
     public void resetMetrics();
 
+    /**
+     * @return Future that will be completed when client reconnected.
+     */
+    @Nullable public IgniteFuture<?> clientReconnectFuture();
+
     /** {@inheritDoc} */
     @Override public IgniteCluster withAsync();
 }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/main/java/org/apache/ignite/internal/GridComponent.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridComponent.java b/modules/core/src/main/java/org/apache/ignite/internal/GridComponent.java
index 7f0f1b8..705576e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/GridComponent.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/GridComponent.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal;
 
 import org.apache.ignite.*;
 import org.apache.ignite.cluster.*;
+import org.apache.ignite.lang.*;
 import org.apache.ignite.spi.*;
 import org.jetbrains.annotations.*;
 
@@ -119,12 +120,13 @@ public interface GridComponent {
     @Nullable public DiscoveryDataExchangeType discoveryDataType();
 
     /**
-     *
+     * @param reconnectFut Reconnect future.
+     * @throws IgniteCheckedException If failed.
      */
-    public void onDisconnected() throws IgniteCheckedException;
+    public void onDisconnected(IgniteFuture<?> reconnectFut) throws IgniteCheckedException;
 
     /**
-     *
+     * @throws IgniteCheckedException If failed.
      */
     public void onReconnected() throws IgniteCheckedException;
 }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/main/java/org/apache/ignite/internal/GridKernalGateway.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalGateway.java b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalGateway.java
index 20d81de..957174a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalGateway.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalGateway.java
@@ -17,8 +17,10 @@
 
 package org.apache.ignite.internal;
 
+import org.apache.ignite.*;
 import org.apache.ignite.internal.util.future.*;
 import org.apache.ignite.internal.util.tostring.*;
+import org.jetbrains.annotations.*;
 
 /**
  * This interface guards access to implementations of public methods that access kernal
@@ -113,8 +115,10 @@ public interface GridKernalGateway {
 
     /**
      * Disconnected callback.
+     *
+     * @return  Reconnect future.
      */
-    public void onDisconnected();
+    @Nullable public GridFutureAdapter<?> onDisconnected();
 
     /**
      * Reconnected callback.

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/main/java/org/apache/ignite/internal/GridKernalGatewayImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalGatewayImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalGatewayImpl.java
index ef894cf..b1f4df8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalGatewayImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalGatewayImpl.java
@@ -39,6 +39,10 @@ public class GridKernalGatewayImpl implements GridKernalGateway, Serializable {
     private final GridSpinReadWriteLock rwLock = new GridSpinReadWriteLock();
 
     /** */
+    @GridToStringExclude
+    private IgniteFutureImpl<?> reconnectFut;
+
+    /** */
     private volatile GridKernalState state = GridKernalState.STOPPED;
 
     /** */
@@ -67,7 +71,17 @@ public class GridKernalGatewayImpl implements GridKernalGateway, Serializable {
 
         rwLock.readLock();
 
-        checkState(true);
+        GridKernalState state = this.state;
+
+        if (state != GridKernalState.STARTED) {
+            // Unlock just acquired lock.
+            rwLock.readUnlock();
+
+            if (state == GridKernalState.DISCONNECTED)
+                throw new IgniteClientDisconnectedException(reconnectFut, "Client node disconnected.", null);
+
+            throw illegalState();
+        }
     }
 
     /** {@inheritDoc} */
@@ -77,7 +91,8 @@ public class GridKernalGatewayImpl implements GridKernalGateway, Serializable {
 
         rwLock.readLock();
 
-        checkState(false);
+        if (state == GridKernalState.DISCONNECTED)
+            throw new IgniteClientDisconnectedException(reconnectFut, "Client node disconnected.", null);
     }
 
     /** {@inheritDoc} */
@@ -126,12 +141,21 @@ public class GridKernalGatewayImpl implements GridKernalGateway, Serializable {
     }
 
     /** {@inheritDoc} */
-    @Override public void onDisconnected() {
+    @Override public GridFutureAdapter<?> onDisconnected() {
         rwLock.readLock();
 
         try {
-            if (state == GridKernalState.STARTED)
+            if (state == GridKernalState.STARTED) {
+                GridFutureAdapter<?> fut = new GridFutureAdapter<>();
+
+                reconnectFut = new IgniteFutureImpl<>(fut);
+
                 state = GridKernalState.DISCONNECTED;
+
+                return fut;
+            }
+            else
+                return null;
         }
         finally {
             rwLock.readUnlock();
@@ -143,16 +167,15 @@ public class GridKernalGatewayImpl implements GridKernalGateway, Serializable {
         rwLock.writeLock();
 
         try {
-            if (state == GridKernalState.DISCONNECTED)
+            if (state == GridKernalState.DISCONNECTED) {
                 state = GridKernalState.STARTED;
+
+                ((GridFutureAdapter<?>)reconnectFut.internalFuture()).onDone();
+            }
         }
         finally {
             rwLock.writeUnlock();
         }
-
-        synchronized (this) {
-            notifyAll();
-        }
     }
 
     /**
@@ -188,12 +211,13 @@ public class GridKernalGatewayImpl implements GridKernalGateway, Serializable {
     @Override public void setState(GridKernalState state) {
         assert state != null;
 
+        GridKernalState state0 = this.state;
+
         // NOTE: this method should always be called within write lock.
         this.state = state;
 
-        synchronized (this) {
-            notifyAll();
-        }
+        if (state0 == GridKernalState.DISCONNECTED)
+            ((GridFutureAdapter<?>)reconnectFut.internalFuture()).onDone(new IgniteCheckedException("Node stopped."));
     }
 
     /** {@inheritDoc} */
@@ -206,37 +230,6 @@ public class GridKernalGatewayImpl implements GridKernalGateway, Serializable {
         return stackTrace;
     }
 
-    /**
-     * @param err If {@code true} throws {@link IllegalStateException} if not started.
-     */
-    private void checkState(boolean err) {
-        if (state != GridKernalState.STARTED) {
-            do {
-                if (state == GridKernalState.DISCONNECTED) {
-                    rwLock.readUnlock();
-
-                    try {
-                        synchronized (this) {
-                            while (state == GridKernalState.DISCONNECTED)
-                                this.wait();
-                        }
-                    }
-                    catch (InterruptedException e) {
-                        throw new IgniteException(e);
-                    }
-
-                    rwLock.readLock();
-                }
-                else if (err) {
-                    rwLock.readUnlock();
-
-                    throw illegalState();
-                }
-            }
-            while (state != GridKernalState.STARTED);
-        }
-    }
-
     /** {@inheritDoc} */
     @Override public String toString() {
         return S.toString(GridKernalGatewayImpl.class, this);

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/main/java/org/apache/ignite/internal/GridPluginComponent.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridPluginComponent.java b/modules/core/src/main/java/org/apache/ignite/internal/GridPluginComponent.java
index 709ce3d..9639df0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/GridPluginComponent.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/GridPluginComponent.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal;
 
 import org.apache.ignite.*;
 import org.apache.ignite.cluster.*;
+import org.apache.ignite.lang.*;
 import org.apache.ignite.plugin.*;
 import org.apache.ignite.spi.*;
 import org.jetbrains.annotations.*;
@@ -64,7 +65,7 @@ public class GridPluginComponent implements GridComponent {
     }
 
     /** {@inheritDoc} */
-    @Override public void onDisconnected() {
+    @Override public void onDisconnected(IgniteFuture<?> reconnectFut) {
         // No-op.
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/main/java/org/apache/ignite/internal/IgniteClientDisconnectedCheckedException.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteClientDisconnectedCheckedException.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteClientDisconnectedCheckedException.java
index 2e999f4..bfa665d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteClientDisconnectedCheckedException.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteClientDisconnectedCheckedException.java
@@ -18,15 +18,29 @@
 package org.apache.ignite.internal;
 
 import org.apache.ignite.*;
+import org.apache.ignite.lang.*;
 
 /**
  *
  */
 public class IgniteClientDisconnectedCheckedException extends IgniteCheckedException {
+    /** */
+    private IgniteFuture<?> reconnectFut;
+
     /**
+     * @param reconnectFut Reconnect future.
      * @param msg Message.
      */
-    public IgniteClientDisconnectedCheckedException(String msg) {
+    public IgniteClientDisconnectedCheckedException(IgniteFuture<?> reconnectFut, String msg) {
         super(msg);
+
+        this.reconnectFut = reconnectFut;
+    }
+
+    /**
+     * @return Reconnect future.
+     */
+    public IgniteFuture<?> reconnectFuture() {
+        return reconnectFut;
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
index 02f4c14..f97a1c4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
@@ -1676,7 +1676,7 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
 
             GridKernalState state = gw.getState();
 
-            if (state == STARTED)
+            if (state == STARTED || state == DISCONNECTED)
                 firstStop = true;
             else if (state == STARTING)
                 U.warn(log, "Attempt to stop starting grid. This operation " +
@@ -1753,7 +1753,7 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
                 if (cache != null)
                     cache.blockGateways();
 
-                assert gw.getState() == STARTED || gw.getState() == STARTING;
+                assert gw.getState() == STARTED || gw.getState() == STARTING || gw.getState() == DISCONNECTED;
 
                 // No more kernal calls from this point on.
                 gw.setState(STOPPING);
@@ -2804,14 +2804,46 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
      *
      */
     public void disconnected() {
-        ctx.gateway().onDisconnected();
+        Throwable err = null;
 
-        try {
-            for (GridComponent comp : ctx.components())
-                comp.onDisconnected();
+        GridFutureAdapter<?> reconnectFut = ctx.gateway().onDisconnected();
+
+        if (reconnectFut == null) {
+            assert ctx.gateway().getState() != STARTED : ctx.gateway().getState();
+
+            return;
         }
-        catch (IgniteCheckedException e) {
-            e.printStackTrace();
+
+        IgniteFuture<?> userFut = new IgniteFutureImpl<>(reconnectFut);
+
+        ctx.cluster().get().clientReconnectFuture(userFut);
+
+        List<GridComponent> comps = ctx.components();
+
+        for (ListIterator<GridComponent> it = comps.listIterator(comps.size()); it.hasPrevious();) {
+            GridComponent comp = it.previous();
+
+            try {
+                if (!skipDaemon(comp))
+                    comp.onDisconnected(userFut);
+            }
+            catch (IgniteCheckedException e) {
+                err = e;
+            }
+            catch (Throwable e) {
+                err = e;
+
+                if (e instanceof Error)
+                    throw e;
+            }
+        }
+
+        if (err != null) {
+            reconnectFut.onDone(err);
+
+            U.error(log, "Failed to reconnect, will stop node", err);
+
+            close();
         }
     }
 
@@ -2819,19 +2851,29 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
      *
      */
     public void reconnected() {
-        new Thread() {
-            public void run() {
-                try {
-                    ctx.gateway().onReconnected();
+        Throwable err = null;
 
-                    for (GridComponent comp : ctx.components())
-                        comp.onReconnected();
-                }
-                catch (IgniteCheckedException e) {
-                    e.printStackTrace();
-                }
-            }
-        }.start();
+        try {
+            for (GridComponent comp : ctx.components())
+                comp.onReconnected();
+
+            ctx.gateway().onReconnected();
+        }
+        catch (IgniteCheckedException e) {
+            err = e;
+        }
+        catch (Throwable e) {
+            err = e;
+
+            if (e instanceof Error)
+                throw e;
+        }
+
+        if (err != null) {
+            U.error(log, "Failed to reconnect, will stop node", err);
+
+            close();
+        }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/main/java/org/apache/ignite/internal/cluster/IgniteClusterAsyncImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/cluster/IgniteClusterAsyncImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/cluster/IgniteClusterAsyncImpl.java
index 26c704c..51cf523 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/cluster/IgniteClusterAsyncImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/cluster/IgniteClusterAsyncImpl.java
@@ -287,6 +287,11 @@ public class IgniteClusterAsyncImpl extends AsyncSupportAdapter<IgniteCluster>
     }
 
     /** {@inheritDoc} */
+    @Nullable @Override public IgniteFuture<?> clientReconnectFuture() {
+        return cluster.clientReconnectFuture();
+    }
+
+    /** {@inheritDoc} */
     @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
         cluster = (IgniteClusterImpl)in.readObject();
     }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/main/java/org/apache/ignite/internal/cluster/IgniteClusterImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/cluster/IgniteClusterImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/cluster/IgniteClusterImpl.java
index 3c937b0..c4de2da 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/cluster/IgniteClusterImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/cluster/IgniteClusterImpl.java
@@ -52,6 +52,9 @@ public class IgniteClusterImpl extends ClusterGroupAdapter implements IgniteClus
     @GridToStringExclude
     private ConcurrentMap nodeLoc;
 
+    /** */
+    private IgniteFuture<?> reconnecFut;
+
     /**
      * Required by {@link Externalizable}.
      */
@@ -501,6 +504,18 @@ public class IgniteClusterImpl extends ClusterGroupAdapter implements IgniteClus
         nodeLoc.clear();
     }
 
+    /**
+     * @param reconnecFut Reconnect future.
+     */
+    public void clientReconnectFuture(IgniteFuture<?> reconnecFut) {
+        this.reconnecFut = reconnecFut;
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public IgniteFuture<?> clientReconnectFuture() {
+        return reconnecFut;
+    }
+
     /** {@inheritDoc} */
     @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
         ctx = (GridKernalContext)in.readObject();

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/main/java/org/apache/ignite/internal/managers/GridManagerAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/GridManagerAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/GridManagerAdapter.java
index d886f4c..b0a46eb 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/GridManagerAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/GridManagerAdapter.java
@@ -167,7 +167,7 @@ public abstract class GridManagerAdapter<T extends IgniteSpi> implements GridMan
     }
 
     /** {@inheritDoc} */
-    @Override public void onDisconnected() throws IgniteCheckedException {
+    @Override public void onDisconnected(IgniteFuture<?> reconnectFut) throws IgniteCheckedException {
         // No-op.
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentManager.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentManager.java
index b82090f..9eda2eb 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentManager.java
@@ -110,7 +110,7 @@ public class GridDeploymentManager extends GridManagerAdapter<DeploymentSpi> {
     }
 
     /** {@inheritDoc} */
-    @Override public void onDisconnected() throws IgniteCheckedException {
+    @Override public void onDisconnected(IgniteFuture<?> reconnectFut) throws IgniteCheckedException {
         storesOnKernalStop();
 
         storesStop();

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
index 894e025..a8af43b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
@@ -294,7 +294,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
     }
 
     /** {@inheritDoc} */
-    @Override public void onDisconnected() throws IgniteCheckedException {
+    @Override public void onDisconnected(IgniteFuture<?> reconnectFut) throws IgniteCheckedException {
         locJoinEvt = new GridFutureAdapter<>();
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/main/java/org/apache/ignite/internal/processors/GridProcessorAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/GridProcessorAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/GridProcessorAdapter.java
index 04a39d1..1a6791b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/GridProcessorAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/GridProcessorAdapter.java
@@ -22,6 +22,7 @@ import org.apache.ignite.cluster.*;
 import org.apache.ignite.internal.*;
 import org.apache.ignite.internal.util.tostring.*;
 import org.apache.ignite.internal.util.typedef.internal.*;
+import org.apache.ignite.lang.*;
 import org.apache.ignite.spi.*;
 import org.jetbrains.annotations.*;
 
@@ -62,7 +63,7 @@ public abstract class GridProcessorAdapter implements GridProcessor {
     }
 
     /** {@inheritDoc} */
-    @Override public void onDisconnected() throws IgniteCheckedException {
+    @Override public void onDisconnected(IgniteFuture<?> reconnectFut) throws IgniteCheckedException {
         // No-op.
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheGateway.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheGateway.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheGateway.java
index d63e818..46674bc 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheGateway.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheGateway.java
@@ -22,6 +22,7 @@ import org.apache.ignite.internal.*;
 import org.apache.ignite.internal.util.*;
 import org.apache.ignite.internal.util.tostring.*;
 import org.apache.ignite.internal.util.typedef.internal.*;
+import org.apache.ignite.lang.*;
 import org.jetbrains.annotations.*;
 
 /**
@@ -36,6 +37,9 @@ public class GridCacheGateway<K, V> {
     private volatile State state = State.STARTED;
 
     /** */
+    private IgniteFuture<?> reconnectFut;
+
+    /** */
     private GridSpinReadWriteLock rwLock = new GridSpinReadWriteLock();
 
     /**
@@ -60,39 +64,27 @@ public class GridCacheGateway<K, V> {
     }
 
     /**
-     *
+     * @param lock {@code True} if lock is held.
+     * @param stopErr {@code True} if throw exception if stopped.
      */
-    private boolean checkState(boolean lock, boolean err) {
+    private boolean checkState(boolean lock, boolean stopErr) {
+        State state = this.state;
+
         if (state != State.STARTED) {
-            do {
-                if (state == State.STOPPED) {
-                    if (lock)
-                        rwLock.readUnlock();
-
-                    if (err)
-                        throw new IllegalStateException("Cache has been stopped: " + ctx.name());
-                    else
-                        return false;
-                }
-                else {
-                    if (lock)
-                        rwLock.readUnlock();
-
-                    try {
-                        synchronized (this) {
-                            while (state == State.DISCONNECTED)
-                                wait();
-                        }
-                    }
-                    catch (InterruptedException e) {
-                        throw new IgniteException(e);
-                    }
-
-                    if (lock)
-                        rwLock.readLock();
-                }
+            if (lock)
+                rwLock.readUnlock();
+
+            if (state == State.STOPPED) {
+                if (stopErr)
+                    throw new IllegalStateException("Cache has been stopped: " + ctx.name());
+                else
+                    return false;
+            }
+            else {
+                assert reconnectFut != null;
+
+                throw new IgniteClientDisconnectedException(reconnectFut, "Client disconnected,", null);
             }
-            while (state != State.STARTED);
         }
 
         return true;
@@ -255,27 +247,19 @@ public class GridCacheGateway<K, V> {
      */
     public void stopped() {
         state = State.STOPPED;
-
-        synchronized (this) {
-            notifyAll();
-        }
     }
 
     /**
-     *
+     * @param reconnectFut Reconnect future.
      */
-    public void onDisconnected() {
-        if (state == State.STARTED)
-            state = State.DISCONNECTED;
-    }
+    public void onDisconnected(IgniteFuture<?> reconnectFut) {
+        assert reconnectFut != null;
 
-    /**
-     *
-     */
-    public void waitOperations() {
-        rwLock.writeLock();
+        if (state == State.STARTED) {
+            this.reconnectFut = reconnectFut;
 
-        rwLock.writeUnlock();
+            state = State.DISCONNECTED;
+        }
     }
 
     /**
@@ -291,10 +275,6 @@ public class GridCacheGateway<K, V> {
         finally {
             rwLock.writeUnlock();
         }
-
-        synchronized (this) {
-            notifyAll();
-        }
     }
 
     /**
@@ -326,10 +306,6 @@ public class GridCacheGateway<K, V> {
         finally {
             rwLock.writeUnlock();
         }
-
-        synchronized (this) {
-            notifyAll();
-        }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java
index f9e9264..3bd40a2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java
@@ -294,12 +294,13 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter {
     /**
      * Cancels all client futures.
      *
-     * @param stop If {@code true} node is stopping, otherwise disconnected.
+     * @param reconnectFut Reconnect future is node disconnected, otherwise {@code null}.
      */
-    public void cancelClientFutures(boolean stop) {
-        IgniteCheckedException e = stop ?
+    public void cancelClientFutures(@Nullable IgniteFuture<?> reconnectFut) {
+        IgniteCheckedException e = reconnectFut == null ?
             new IgniteCheckedException("Operation has been cancelled (node is stopping).") :
-            new IgniteClientDisconnectedCheckedException("Operation has been cancelled (node disconnected).");
+            new IgniteClientDisconnectedCheckedException(reconnectFut,
+                "Operation has been cancelled (client node disconnected).");
 
         for (Collection<GridCacheFuture<?>> futures : futs.values()) {
             for (GridCacheFuture<?> future : futures)

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
index 3f06e8e..e883b9c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
@@ -274,52 +274,54 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
         // Allow discovery events to get processed.
         locExchFut.onDone();
 
-        if (log.isDebugEnabled())
-            log.debug("Beginning to wait on local exchange future: " + fut);
+        if (cctx.kernalContext().gateway().getState() == GridKernalState.STARTED) {
+            if (log.isDebugEnabled())
+                log.debug("Beginning to wait on local exchange future: " + fut);
 
-        try {
-            boolean first = true;
+            try {
+                boolean first = true;
 
-            while (true) {
-                try {
-                    fut.get(cctx.preloadExchangeTimeout());
+                while (true) {
+                    try {
+                        fut.get(cctx.preloadExchangeTimeout());
 
-                    break;
-                }
-                catch (IgniteClientDisconnectedCheckedException e) {
-                    log.info("Disconnected while waiting for initial partition map exchange: " + e);
+                        break;
+                    }
+                    catch (IgniteClientDisconnectedCheckedException e) {
+                        log.info("Disconnected while waiting for initial partition map exchange: " + e);
 
-                    break;
-                }
-                catch (IgniteFutureTimeoutCheckedException ignored) {
-                    if (first) {
-                        U.warn(log, "Failed to wait for initial partition map exchange. " +
-                            "Possible reasons are: " + U.nl() +
-                            "  ^-- Transactions in deadlock." + U.nl() +
-                            "  ^-- Long running transactions (ignore if this is the case)." + U.nl() +
-                            "  ^-- Unreleased explicit locks.");
-
-                        first = false;
+                        break;
+                    }
+                    catch (IgniteFutureTimeoutCheckedException ignored) {
+                        if (first) {
+                            U.warn(log, "Failed to wait for initial partition map exchange. " +
+                                "Possible reasons are: " + U.nl() +
+                                "  ^-- Transactions in deadlock." + U.nl() +
+                                "  ^-- Long running transactions (ignore if this is the case)." + U.nl() +
+                                "  ^-- Unreleased explicit locks.");
+
+                            first = false;
+                        }
+                        else
+                            U.warn(log, "Still waiting for initial partition map exchange [fut=" + fut + ']');
                     }
-                    else
-                        U.warn(log, "Still waiting for initial partition map exchange [fut=" + fut + ']');
                 }
+
+                for (GridCacheContext cacheCtx : cctx.cacheContexts())
+                    cacheCtx.preloader().onInitialExchangeComplete(null);
             }
+            catch (IgniteFutureTimeoutCheckedException e) {
+                IgniteCheckedException err = new IgniteCheckedException("Timed out waiting for exchange future: " + fut, e);
 
-            for (GridCacheContext cacheCtx : cctx.cacheContexts())
-                cacheCtx.preloader().onInitialExchangeComplete(null);
-        }
-        catch (IgniteFutureTimeoutCheckedException e) {
-            IgniteCheckedException err = new IgniteCheckedException("Timed out waiting for exchange future: " + fut, e);
+                for (GridCacheContext cacheCtx : cctx.cacheContexts())
+                    cacheCtx.preloader().onInitialExchangeComplete(err);
 
-            for (GridCacheContext cacheCtx : cctx.cacheContexts())
-                cacheCtx.preloader().onInitialExchangeComplete(err);
+                throw err;
+            }
 
-            throw err;
+            if (log.isDebugEnabled())
+                log.debug("Finished waiting on local exchange: " + fut.exchangeId());
         }
-
-        if (log.isDebugEnabled())
-            log.debug("Finished waiting on local exchange: " + fut.exchangeId());
     }
 
     /** {@inheritDoc} */
@@ -331,7 +333,7 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
         cctx.io().removeHandler(0, GridDhtPartitionsSingleRequest.class);
 
         IgniteCheckedException err = disconnected ?
-            new IgniteClientDisconnectedCheckedException("Node disconnected: " + cctx.gridName()) :
+            new IgniteClientDisconnectedCheckedException(null, "Node disconnected: " + cctx.gridName()) :
             new IgniteInterruptedCheckedException("Node is stopping: " + cctx.gridName());
 
         // Finish all exchange futures.

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
index 791661d..8d3f8da 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
@@ -913,11 +913,11 @@ public class GridCacheProcessor extends GridProcessorAdapter {
     }
 
     /** {@inheritDoc} */
-    @Override public void onDisconnected() throws IgniteCheckedException {
+    @Override public void onDisconnected(IgniteFuture<?> reconnectFut) throws IgniteCheckedException {
         for (GridCacheAdapter cache : caches.values())
-            cache.context().gate().onDisconnected();
+            cache.context().gate().onDisconnected(reconnectFut);
 
-        sharedCtx.mvcc().cancelClientFutures(false);
+        sharedCtx.mvcc().cancelClientFutures(reconnectFut);
 
         for (GridCacheAdapter cache : caches.values())
             cache.disconnected();
@@ -932,8 +932,6 @@ public class GridCacheProcessor extends GridProcessorAdapter {
         for (GridCacheAdapter cache : caches.values())
             cache.context().gate().reconnected(false);
 
-        ctx.marshallerContext().onMarshallerCacheStarted(ctx);
-
         marshallerCache().context().preloader().syncFuture().listen(new CIX1<IgniteInternalFuture<?>>() {
             @Override public void applyx(IgniteInternalFuture<?> f) throws IgniteCheckedException {
                 ctx.marshallerContext().onMarshallerCachePreloaded(ctx);
@@ -2869,7 +2867,7 @@ public class GridCacheProcessor extends GridProcessorAdapter {
      * Cancel all user operations.
      */
     public void cancelUserOperations() {
-        sharedCtx.mvcc().cancelClientFutures(true);
+        sharedCtx.mvcc().cancelClientFutures(null);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
index f88e288..6faf6e4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
@@ -1560,6 +1560,14 @@ public class GridCacheUtils {
      * @return CacheException runtime exception, never null.
      */
     @NotNull public static RuntimeException convertToCacheException(IgniteCheckedException e) {
+        IgniteClientDisconnectedCheckedException disconnectedErr =
+            e instanceof IgniteClientDisconnectedCheckedException ?
+            (IgniteClientDisconnectedCheckedException)e
+            : e.getCause(IgniteClientDisconnectedCheckedException.class);
+
+        if (disconnectedErr != null)
+            e = disconnectedErr;
+
         if (e.hasCause(CacheWriterException.class))
             return new CacheWriterException(U.convertExceptionNoWrap(e));
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java
index 7508acd..3c414e4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java
@@ -631,7 +631,7 @@ public class GridContinuousProcessor extends GridProcessorAdapter {
     }
 
     /** {@inheritDoc} */
-    @Override public void onDisconnected() throws IgniteCheckedException {
+    @Override public void onDisconnected(IgniteFuture<?> reconnectFut) throws IgniteCheckedException {
         for (UUID rmtId : rmtInfos.keySet())
             unregisterRemote(rmtId);
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/main/java/org/apache/ignite/internal/processors/service/GridServiceProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/service/GridServiceProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/service/GridServiceProcessor.java
index 89b2a31..76ea73b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/service/GridServiceProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/service/GridServiceProcessor.java
@@ -648,10 +648,9 @@ public class GridServiceProcessor extends GridProcessorAdapter {
                     }
                 }
                 else {
-                    Collection<ClusterNode> nodes =
-                        assigns.nodeFilter() == null ?
-                            ctx.discovery().nodes(topVer) :
-                            F.view(ctx.discovery().nodes(topVer), assigns.nodeFilter());
+                    Collection<ClusterNode> nodes = assigns.nodeFilter() == null ?
+                        ctx.discovery().nodes(topVer) :
+                        F.view(ctx.discovery().nodes(topVer), assigns.nodeFilter());
 
                     if (!nodes.isEmpty()) {
                         int size = nodes.size();
@@ -1021,7 +1020,7 @@ public class GridServiceProcessor extends GridProcessorAdapter {
                                     cache.getAndRemove(key);
                                 }
                                 catch (IgniteCheckedException ex) {
-                                    log.error("Failed to remove assignments for undeployed service: " + name, ex);
+                                    U.error(log, "Failed to remove assignments for undeployed service: " + name, ex);
                                 }
                             }
                         }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/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 7516f79..71dbc94 100644
--- 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
@@ -628,7 +628,10 @@ public abstract class IgniteUtils {
 
         m.put(IgniteClientDisconnectedCheckedException.class, new C1<IgniteCheckedException, IgniteException>() {
             @Override public IgniteException apply(IgniteCheckedException e) {
-                return new IgniteClientDisconnectedException(e.getMessage(), e);
+                return new IgniteClientDisconnectedException(
+                    ((IgniteClientDisconnectedCheckedException)e).reconnectFuture(),
+                    e.getMessage(),
+                    e);
             }
         });
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/test/java/org/apache/ignite/internal/GridUpdateNotifierSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/GridUpdateNotifierSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/GridUpdateNotifierSelfTest.java
index 5f2d2b4..bf499c3 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/GridUpdateNotifierSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/GridUpdateNotifierSelfTest.java
@@ -18,6 +18,7 @@
 package org.apache.ignite.internal;
 
 import org.apache.ignite.*;
+import org.apache.ignite.internal.util.future.*;
 import org.apache.ignite.internal.util.typedef.internal.*;
 import org.apache.ignite.lang.*;
 import org.apache.ignite.plugin.*;
@@ -128,8 +129,8 @@ public class GridUpdateNotifierSelfTest extends GridCommonAbstractTest {
             return false;
         }
 
-        @Override public void onDisconnected() {
-            // No-op.
+        @Override public GridFutureAdapter<?> onDisconnected() {
+            return null;
         }
 
         @Override public void onReconnected() {

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java b/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java
index 452f808..d5f2f5a 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectCacheTest.java
@@ -35,6 +35,7 @@ import org.apache.ignite.spi.*;
 import org.apache.ignite.spi.communication.tcp.*;
 import org.apache.ignite.testframework.*;
 
+import javax.cache.*;
 import java.util.*;
 import java.util.concurrent.*;
 import java.util.concurrent.atomic.*;
@@ -259,7 +260,7 @@ public class IgniteClientReconnectCacheTest extends IgniteClientReconnectAbstrac
     /**
      * @throws Exception If failed.
      */
-    public void testReconnectInitialExchangeInProgress() throws Exception {
+    public void _testReconnectInitialExchangeInProgress() throws Exception {
         final UUID clientId = UUID.randomUUID();
 
         Ignite srv = grid(0);
@@ -306,7 +307,8 @@ public class IgniteClientReconnectCacheTest extends IgniteClientReconnectAbstrac
             @Override public Ignite call() throws Exception {
                 try {
                     return startGrid(SRV_CNT);
-                } catch (Throwable e) {
+                }
+                catch (Throwable e) {
                     log.error("Unexpected error: " + e, e);
 
                     throw e;
@@ -448,7 +450,19 @@ public class IgniteClientReconnectCacheTest extends IgniteClientReconnectAbstrac
 
         IgniteInternalFuture<?> fut = GridTestUtils.runAsync(new Callable<Object>() {
             @Override public Object call() throws Exception {
-                c.apply(cache);
+                try {
+                    c.apply(cache);
+                }
+                catch (CacheException e) {
+                    log.info("Expected exception: " + e);
+
+                    assertTrue("Unexpected cause: " + e.getCause(),
+                        e.getCause() instanceof IgniteClientDisconnectedException);
+
+                    IgniteClientDisconnectedException e0 = (IgniteClientDisconnectedException)e.getCause();
+
+                    e0.reconnectFuture().get();
+                }
 
                 return null;
             }
@@ -462,14 +476,7 @@ public class IgniteClientReconnectCacheTest extends IgniteClientReconnectAbstrac
 
         srvSpi.failNode(client.localNode().id(), null);
 
-        try {
-            fut.get();
-
-            fail();
-        }
-        catch (IgniteCheckedException e) {
-            log.info("Expected error: " + e);
-        }
+        fut.get();
 
         srvCommSpi.stopBlock(false);
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectStopTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectStopTest.java b/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectStopTest.java
new file mode 100644
index 0000000..49bdae2
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/IgniteClientReconnectStopTest.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal;
+
+import org.apache.ignite.*;
+import org.apache.ignite.configuration.*;
+import org.apache.ignite.events.*;
+import org.apache.ignite.lang.*;
+
+import java.util.concurrent.*;
+
+import static java.util.concurrent.TimeUnit.*;
+import static org.apache.ignite.events.EventType.*;
+
+/**
+ *
+ */
+public class IgniteClientReconnectStopTest extends IgniteClientReconnectAbstractTest {
+    /** {@inheritDoc} */
+    @Override protected int serverCount() {
+        return 1;
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testStopWhenDisconnected() throws Exception {
+        clientMode = true;
+
+        Ignite client = startGrid(serverCount());
+
+        assertTrue(client.cluster().localNode().isClient());
+
+        Ignite srv = clientRouter(client);
+
+        TestTcpDiscoverySpi srvSpi = spi(srv);
+        final CountDownLatch disconnectLatch = new CountDownLatch(1);
+        final CountDownLatch reconnectLatch = new CountDownLatch(1);
+
+        final TestTcpDiscoverySpi clientSpi = spi(client);
+
+        log.info("Block reconnect.");
+
+        clientSpi.writeLatch = new CountDownLatch(1);
+
+        client.events().localListen(new IgnitePredicate<Event>() {
+            @Override public boolean apply(Event evt) {
+                if (evt.type() == EVT_CLIENT_NODE_DISCONNECTED) {
+                    info("Disconnected: " + evt);
+
+                    disconnectLatch.countDown();
+                } else if (evt.type() == EVT_CLIENT_NODE_RECONNECTED) {
+                    info("Reconnected: " + evt);
+
+                    reconnectLatch.countDown();
+                }
+
+                return true;
+            }
+        }, EVT_CLIENT_NODE_DISCONNECTED, EVT_CLIENT_NODE_RECONNECTED);
+
+        srvSpi.failNode(client.cluster().localNode().id(), null);
+
+        assertTrue(disconnectLatch.await(5000, MILLISECONDS));
+
+        IgniteFuture<?> reconnectFut = null;
+
+        try {
+            client.getOrCreateCache(new CacheConfiguration<>());
+
+            fail();
+        }
+        catch (IgniteClientDisconnectedException e) {
+            log.info("Expected operation exception: " + e);
+
+            reconnectFut = e.reconnectFuture();
+        }
+
+        assertNotNull(reconnectFut);
+
+        client.close();
+
+        try {
+            reconnectFut.get();
+
+            fail();
+        }
+        catch (IgniteException e) {
+            log.info("Expected reconnect exception: " + e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/807ceb38/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteClientReconnectTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteClientReconnectTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteClientReconnectTestSuite.java
index 0f5b3ee..88f0c5f 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteClientReconnectTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteClientReconnectTestSuite.java
@@ -31,6 +31,7 @@ public class IgniteClientReconnectTestSuite extends TestSuite {
     public static TestSuite suite() throws Exception {
         TestSuite suite = new TestSuite("Ignite Client Reconnect Test Suite");
 
+        suite.addTestSuite(IgniteClientReconnectStopTest.class);
         suite.addTestSuite(IgniteClientReconnectApiBlockTest.class);
         suite.addTestSuite(IgniteClientReconnectDiscoveryStateTest.class);
         suite.addTestSuite(IgniteClientReconnectCacheTest.class);