ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From agoncha...@apache.org
Subject [2/4] incubator-ignite git commit: # IGNITE-45 - Fixing examples.
Date Fri, 13 Mar 2015 05:31:34 GMT
# IGNITE-45 - Fixing examples.


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

Branch: refs/heads/ignite-459
Commit: aa98990921e4d9b044b74ef3403be6d3126f8294
Parents: a892c75
Author: Alexey Goncharuk <agoncharuk@gridgain.com>
Authored: Thu Mar 12 17:59:48 2015 -0700
Committer: Alexey Goncharuk <agoncharuk@gridgain.com>
Committed: Thu Mar 12 17:59:48 2015 -0700

----------------------------------------------------------------------
 .../starschema/CacheStarSchemaExample.java      |  35 +++--
 .../internal/events/DiscoveryCustomEvent.java   |  18 +++
 .../discovery/GridDiscoveryManager.java         | 150 ++++++++++++-------
 .../affinity/GridAffinityAssignmentCache.java   |   3 +-
 .../cache/DynamicCacheChangeBatch.java          |   9 ++
 .../processors/cache/GridCacheContext.java      |  13 +-
 .../processors/cache/GridCacheGateway.java      |   3 +-
 .../GridCachePartitionExchangeManager.java      |  26 ++--
 .../processors/cache/GridCacheProcessor.java    |  21 ++-
 .../cache/GridCacheSharedContext.java           |  10 ++
 .../processors/cache/GridCacheUtils.java        |  67 +++++----
 .../processors/cache/IgniteCacheProxy.java      |  15 +-
 .../cache/affinity/GridCacheAffinityImpl.java   |   2 +-
 .../dht/GridClientPartitionTopology.java        |  29 +++-
 .../dht/GridDhtPartitionTopology.java           |   2 +-
 .../dht/GridDhtPartitionTopologyImpl.java       |  43 ++++--
 .../dht/atomic/GridDhtAtomicCache.java          |  16 +-
 .../dht/colocated/GridDhtColocatedCache.java    |   4 +-
 .../preloader/GridDhtPartitionExchangeId.java   |   3 +-
 .../GridDhtPartitionsExchangeFuture.java        |  38 +++--
 .../near/GridNearTransactionalCache.java        |   4 +-
 .../processors/igfs/IgfsMetaManager.java        |   3 +-
 .../processors/query/GridQueryIndexing.java     |  12 ++
 .../processors/query/GridQueryProcessor.java    |  40 +++++
 .../resource/GridResourceProcessor.java         |   2 +
 .../ignite/internal/GridDiscoverySelfTest.java  |   3 +-
 .../GridDiscoveryManagerAliveCacheSelfTest.java |   7 +-
 .../discovery/GridDiscoveryManagerSelfTest.java |  98 ++++++------
 .../processors/hadoop/HadoopContext.java        |   4 +-
 .../processors/query/h2/IgniteH2Indexing.java   |  41 ++++-
 30 files changed, 498 insertions(+), 223 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/examples/src/main/java/org/apache/ignite/examples/datagrid/starschema/CacheStarSchemaExample.java
----------------------------------------------------------------------
diff --git a/examples/src/main/java/org/apache/ignite/examples/datagrid/starschema/CacheStarSchemaExample.java b/examples/src/main/java/org/apache/ignite/examples/datagrid/starschema/CacheStarSchemaExample.java
index 04aab84..f75052d 100644
--- a/examples/src/main/java/org/apache/ignite/examples/datagrid/starschema/CacheStarSchemaExample.java
+++ b/examples/src/main/java/org/apache/ignite/examples/datagrid/starschema/CacheStarSchemaExample.java
@@ -72,34 +72,32 @@ public class CacheStarSchemaExample {
      *
      * @param args Command line arguments, none required.
      */
-    public static void main(String[] args) {
-        Ignite ignite = Ignition.start("examples/config/example-compute.xml");
+    public static void main(String[] args) throws Exception {
+        try (Ignite ignite = Ignition.start("examples/config/example-compute.xml")) {
 
-        System.out.println();
-        System.out.println(">>> Cache star schema example started.");
+            System.out.println();
+            System.out.println(">>> Cache star schema example started.");
 
-        CacheConfiguration<Integer, FactPurchase> factCacheCfg = new CacheConfiguration<>();
+            CacheConfiguration<Integer, FactPurchase> factCacheCfg = new CacheConfiguration<>();
 
-        factCacheCfg.setCacheMode(CacheMode.PARTITIONED);
-        factCacheCfg.setName(PARTITIONED_CACHE_NAME);
+            factCacheCfg.setCacheMode(CacheMode.PARTITIONED);
+            factCacheCfg.setName(PARTITIONED_CACHE_NAME);
+            factCacheCfg.setQueryIndexEnabled(true);
 
-        CacheConfiguration<Integer, Object> dimCacheCfg = new CacheConfiguration<>();
+            CacheConfiguration<Integer, Object> dimCacheCfg = new CacheConfiguration<>();
 
-        dimCacheCfg.setCacheMode(CacheMode.REPLICATED);
-        dimCacheCfg.setName(REPLICATED_CACHE_NAME);
+            dimCacheCfg.setCacheMode(CacheMode.REPLICATED);
+            dimCacheCfg.setName(REPLICATED_CACHE_NAME);
+            dimCacheCfg.setQueryIndexEnabled(true);
 
-        try (IgniteCache<Integer, FactPurchase> factCache = ignite.createCache(factCacheCfg);
-            IgniteCache<Integer, Object> dimCache = ignite.createCache(dimCacheCfg)) {
-            try {
+            try (IgniteCache<Integer, FactPurchase> factCache = ignite.createCache(factCacheCfg);
+                 IgniteCache<Integer, Object> dimCache = ignite.createCache(dimCacheCfg)) {
                 populateDimensions(dimCache);
                 populateFacts(factCache);
 
                 queryStorePurchases(factCache);
                 queryProductPurchases(factCache);
             }
-            finally {
-                Ignition.stop(false);
-            }
         }
     }
 
@@ -162,7 +160,7 @@ public class CacheStarSchemaExample {
         // Create cross cache query to get all purchases made at store1.
         QueryCursor<Cache.Entry<Integer, FactPurchase>> storePurchases = factCache.query(sql(
             FactPurchase.class,
-            "from \"replicated\".DimStore, \"partitioned\".FactPurchase "
+            "from \"" + REPLICATED_CACHE_NAME + "\".DimStore, \"" + PARTITIONED_CACHE_NAME + "\".FactPurchase "
                 + "where DimStore.id=FactPurchase.storeId and DimStore.name=?").setArgs("Store1"));
 
         printQueryResults("All purchases made at store1:", storePurchases.getAll());
@@ -190,7 +188,8 @@ public class CacheStarSchemaExample {
         // for specified products.
         QueryCursor<Cache.Entry<Integer, FactPurchase>> prodPurchases = factCache.query(sql(
             FactPurchase.class,
-            "from \"replicated\".DimStore, \"replicated\".DimProduct, \"partitioned\".FactPurchase "
+            "from \"" + REPLICATED_CACHE_NAME + "\".DimStore, \"" + REPLICATED_CACHE_NAME + "\".DimProduct, " +
+                "\"" + PARTITIONED_CACHE_NAME + "\".FactPurchase "
                 + "where DimStore.id=FactPurchase.storeId and DimProduct.id=FactPurchase.productId "
                 + "and DimStore.name=? and DimProduct.id in(?, ?, ?)")
             .setArgs("Store2", p1.getId(), p2.getId(), p3.getId()));

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/modules/core/src/main/java/org/apache/ignite/internal/events/DiscoveryCustomEvent.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/events/DiscoveryCustomEvent.java b/modules/core/src/main/java/org/apache/ignite/internal/events/DiscoveryCustomEvent.java
index 0f3e83b..ee32692 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/events/DiscoveryCustomEvent.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/events/DiscoveryCustomEvent.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.events;
 
 import org.apache.ignite.events.*;
 import org.apache.ignite.internal.managers.discovery.*;
+import org.apache.ignite.internal.processors.affinity.*;
 import org.apache.ignite.internal.util.typedef.internal.*;
 
 import java.io.*;
@@ -43,6 +44,9 @@ public class DiscoveryCustomEvent extends DiscoveryEvent {
     /** */
     private Serializable data;
 
+    /** Affinity topology version. */
+    private AffinityTopologyVersion affTopVer;
+
     /**
      * Default constructor.
      */
@@ -64,6 +68,20 @@ public class DiscoveryCustomEvent extends DiscoveryEvent {
         this.data = data;
     }
 
+    /**
+     * @return Affinity topology version.
+     */
+    public AffinityTopologyVersion affinityTopologyVersion() {
+        return affTopVer;
+    }
+
+    /**
+     * @param affTopVer Affinity topology version.
+     */
+    public void affinityTopologyVersion(AffinityTopologyVersion affTopVer) {
+        this.affTopVer = affTopVer;
+    }
+
     /** {@inheritDoc} */
     @Override public String toString() {
         return S.toString(DiscoveryCustomEvent.class, this, super.toString());

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/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 07058c4..1543df2 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
@@ -21,11 +21,11 @@ import org.apache.ignite.*;
 import org.apache.ignite.cluster.*;
 import org.apache.ignite.events.*;
 import org.apache.ignite.internal.*;
-import org.apache.ignite.internal.client.util.GridConcurrentHashSet;
 import org.apache.ignite.internal.events.*;
 import org.apache.ignite.internal.managers.*;
 import org.apache.ignite.internal.managers.communication.*;
 import org.apache.ignite.internal.managers.eventstorage.*;
+import org.apache.ignite.internal.processors.affinity.*;
 import org.apache.ignite.internal.processors.jobmetrics.*;
 import org.apache.ignite.internal.processors.security.*;
 import org.apache.ignite.internal.util.*;
@@ -95,9 +95,9 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
     };
 
     /** Disco history entries comparator. */
-    private static final Comparator<Map.Entry<Long, DiscoCache>> histCmp =
-        new Comparator<Map.Entry<Long, DiscoCache>>() {
-            @Override public int compare(Map.Entry<Long, DiscoCache> o1, Map.Entry<Long, DiscoCache> o2) {
+    private static final Comparator<Map.Entry<AffinityTopologyVersion, DiscoCache>> histCmp =
+        new Comparator<Map.Entry<AffinityTopologyVersion, DiscoCache>>() {
+            @Override public int compare(Map.Entry<AffinityTopologyVersion, DiscoCache> o1, Map.Entry<AffinityTopologyVersion, DiscoCache> o2) {
                 return o1.getKey().compareTo(o2.getKey());
             }
         };
@@ -130,15 +130,17 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
     private final AtomicReference<DiscoCache> discoCache = new AtomicReference<>();
 
     /** Topology cache history. */
-    private final GridBoundedConcurrentLinkedHashMap<Long, DiscoCache> discoCacheHist =
-        new GridBoundedConcurrentLinkedHashMap<>(DISCOVERY_HISTORY_SIZE,
-            DISCOVERY_HISTORY_SIZE, 0.7f, 1);
+    private final Map<AffinityTopologyVersion, DiscoCache> discoCacheHist =
+        new GridBoundedConcurrentLinkedHashMap<>(DISCOVERY_HISTORY_SIZE, DISCOVERY_HISTORY_SIZE, 0.7f, 1);
 
     /** Topology snapshots history. */
     private volatile Map<Long, Collection<ClusterNode>> topHist = new HashMap<>();
 
     /** Topology version. */
-    private final GridAtomicLong topVer = new GridAtomicLong();
+    private final AtomicReference<AffinityTopologyVersion> topVer = new AtomicReference<>(AffinityTopologyVersion.ZERO);
+
+    /** Minor topology version. */
+    private int minorTopVer;
 
     /** Order supported flag. */
     private boolean discoOrdered;
@@ -241,6 +243,19 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
             predicate.addNearNode(nearNodeId);
     }
 
+    /**
+     * @param evtType Event type.
+     * @return Next affinity topology version.
+     */
+    private AffinityTopologyVersion nextTopologyVersion(int evtType, long topVer) {
+        if (evtType == DiscoveryCustomEvent.EVT_DISCOVERY_CUSTOM_EVT)
+            minorTopVer++;
+        else if (evtType != EVT_NODE_METRICS_UPDATED)
+            minorTopVer = 0;
+
+        return new AffinityTopologyVersion(topVer, minorTopVer);
+    }
+
     /** {@inheritDoc} */
     @Override public void start() throws IgniteCheckedException {
         long totSysMemory = -1;
@@ -312,6 +327,8 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
                 if (snapshots != null)
                     topHist = snapshots;
 
+                AffinityTopologyVersion nextTopVer = nextTopologyVersion(type, topVer);
+
                 if (type == EVT_NODE_FAILED || type == EVT_NODE_LEFT) {
                     for (DiscoCache c : discoCacheHist.values())
                         c.updateAlives(node);
@@ -332,7 +349,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
                 if (type != EVT_NODE_METRICS_UPDATED) {
                     DiscoCache cache = new DiscoCache(locNode, F.view(topSnapshot, F.remoteNodes(locNode.id())));
 
-                    discoCacheHist.put(topVer, cache);
+                    discoCacheHist.put(nextTopVer, cache);
                     discoCache.set(cache);
                 }
 
@@ -357,14 +374,14 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
                 }
 
                 if (topVer > 0 && (type == EVT_NODE_JOINED || type == EVT_NODE_FAILED || type == EVT_NODE_LEFT)) {
-                    boolean set = GridDiscoveryManager.this.topVer.setIfGreater(topVer);
+                    boolean set = updateTopologyVersionIfGreater(nextTopVer);
 
                     assert set : "Topology version has not been updated [this.topVer=" +
                         GridDiscoveryManager.this.topVer + ", topVer=" + topVer + ", node=" + node +
                         ", evt=" + U.gridEventName(type) + ']';
                 }
 
-                discoWrk.addEvent(type, topVer, node, topSnapshot, data);
+                discoWrk.addEvent(type, nextTopVer, node, topSnapshot, data);
             }
         });
 
@@ -422,7 +439,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
 
         locNode = spi.getLocalNode();
 
-        topVer.setIfGreater(locNode.order());
+        updateTopologyVersionIfGreater(new AffinityTopologyVersion(locNode.order()));
 
         // Start discovery worker.
         new IgniteThread(discoWrk).start();
@@ -733,7 +750,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
      * Prints the latest topology info into log taking into account logging/verbosity settings.
      */
     public void ackTopology() {
-        ackTopology(topVer.get(), false);
+        ackTopology(topVer.get().topologyVersion(), false);
     }
 
     /**
@@ -1038,7 +1055,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
      * @return Collection of cache nodes.
      */
     public Collection<ClusterNode> nodes(long topVer) {
-        return resolveDiscoCache(null, topVer).allNodes();
+        return resolveDiscoCache(null, new AffinityTopologyVersion(topVer)).allNodes();
     }
 
     /**
@@ -1048,8 +1065,8 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
      * @param topVer Topology version.
      * @return Collection of cache nodes.
      */
-    public Collection<ClusterNode> cacheNodes(@Nullable String cacheName, long topVer) {
-        return resolveDiscoCache(cacheName, topVer).cacheNodes(cacheName, topVer);
+    public Collection<ClusterNode> cacheNodes(@Nullable String cacheName, AffinityTopologyVersion topVer) {
+        return resolveDiscoCache(cacheName, topVer).cacheNodes(cacheName, topVer.topologyVersion());
     }
 
     /**
@@ -1058,8 +1075,8 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
      * @param topVer Topology version.
      * @return Collection of cache nodes.
      */
-    public Collection<ClusterNode> cacheNodes(long topVer) {
-        return resolveDiscoCache(null, topVer).allNodesWithCaches(topVer);
+    public Collection<ClusterNode> cacheNodes(AffinityTopologyVersion topVer) {
+        return resolveDiscoCache(null, topVer).allNodesWithCaches(topVer.topologyVersion());
     }
 
     /**
@@ -1069,8 +1086,8 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
      * @param topVer Topology version.
      * @return Collection of cache nodes.
      */
-    public Collection<ClusterNode> remoteCacheNodes(@Nullable String cacheName, long topVer) {
-        return resolveDiscoCache(cacheName, topVer).remoteCacheNodes(cacheName, topVer);
+    public Collection<ClusterNode> remoteCacheNodes(@Nullable String cacheName, AffinityTopologyVersion topVer) {
+        return resolveDiscoCache(cacheName, topVer).remoteCacheNodes(cacheName, topVer.topologyVersion());
     }
 
     /**
@@ -1079,8 +1096,8 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
      * @param topVer Topology version.
      * @return Collection of cache nodes.
      */
-    public Collection<ClusterNode> remoteCacheNodes(long topVer) {
-        return resolveDiscoCache(null, topVer).remoteCacheNodes(topVer);
+    public Collection<ClusterNode> remoteCacheNodes(AffinityTopologyVersion topVer) {
+        return resolveDiscoCache(null, topVer).remoteCacheNodes(topVer.topologyVersion());
     }
 
     /**
@@ -1090,8 +1107,8 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
      * @param topVer Topology version.
      * @return Collection of cache nodes.
      */
-    public Collection<ClusterNode> aliveCacheNodes(@Nullable String cacheName, long topVer) {
-        return resolveDiscoCache(cacheName, topVer).aliveCacheNodes(cacheName, topVer);
+    public Collection<ClusterNode> aliveCacheNodes(@Nullable String cacheName, AffinityTopologyVersion topVer) {
+        return resolveDiscoCache(cacheName, topVer).aliveCacheNodes(cacheName, topVer.topologyVersion());
     }
 
     /**
@@ -1101,8 +1118,8 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
      * @param topVer Topology version.
      * @return Collection of cache nodes.
      */
-    public Collection<ClusterNode> aliveRemoteCacheNodes(@Nullable String cacheName, long topVer) {
-        return resolveDiscoCache(cacheName, topVer).aliveRemoteCacheNodes(cacheName, topVer);
+    public Collection<ClusterNode> aliveRemoteCacheNodes(@Nullable String cacheName, AffinityTopologyVersion topVer) {
+        return resolveDiscoCache(cacheName, topVer).aliveRemoteCacheNodes(cacheName, topVer.topologyVersion());
     }
 
     /**
@@ -1111,8 +1128,8 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
      * @param topVer Topology version (maximum allowed node order).
      * @return Collection of alive cache nodes.
      */
-    public Collection<ClusterNode> aliveRemoteNodesWithCaches(long topVer) {
-        return resolveDiscoCache(null, topVer).aliveRemoteNodesWithCaches(topVer);
+    public Collection<ClusterNode> aliveRemoteNodesWithCaches(AffinityTopologyVersion topVer) {
+        return resolveDiscoCache(null, topVer).aliveRemoteNodesWithCaches(topVer.topologyVersion());
     }
 
     /**
@@ -1121,8 +1138,8 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
      * @param topVer Topology version (maximum allowed node order).
      * @return Collection of alive cache nodes.
      */
-    public Collection<ClusterNode> aliveNodesWithCaches(long topVer) {
-        return resolveDiscoCache(null, topVer).aliveNodesWithCaches(topVer);
+    public Collection<ClusterNode> aliveNodesWithCaches(AffinityTopologyVersion topVer) {
+        return resolveDiscoCache(null, topVer).aliveNodesWithCaches(topVer.topologyVersion());
     }
 
     /**
@@ -1132,8 +1149,8 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
      * @param topVer Topology version.
      * @return Collection of cache affinity nodes.
      */
-    public Collection<ClusterNode> cacheAffinityNodes(@Nullable String cacheName, long topVer) {
-        return resolveDiscoCache(cacheName, topVer).cacheAffinityNodes(cacheName, topVer);
+    public Collection<ClusterNode> cacheAffinityNodes(@Nullable String cacheName, AffinityTopologyVersion topVer) {
+        return resolveDiscoCache(cacheName, topVer).cacheAffinityNodes(cacheName, topVer.topologyVersion());
     }
 
     /**
@@ -1184,7 +1201,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
      * @param topVer Topology version.
      * @return {@code True} if cache with given name has at least one node with near cache enabled.
      */
-    public boolean hasNearCache(@Nullable String cacheName, long topVer) {
+    public boolean hasNearCache(@Nullable String cacheName, AffinityTopologyVersion topVer) {
         return resolveDiscoCache(cacheName, topVer).hasNearCache(cacheName);
     }
 
@@ -1195,14 +1212,15 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
      * @param topVer Topology version.
      * @return Discovery cache.
      */
-    private DiscoCache resolveDiscoCache(@Nullable String cacheName, long topVer) {
-        DiscoCache cache = topVer == -1 || topVer == topologyVersion() ? discoCache() : discoCacheHist.get(topVer);
+    private DiscoCache resolveDiscoCache(@Nullable String cacheName, AffinityTopologyVersion topVer) {
+        DiscoCache cache = AffinityTopologyVersion.NONE.equals(topVer) || topVer.equals(this.topVer.get()) ?
+            discoCache() : discoCacheHist.get(topVer);
 
         if (cache == null) {
             // Find the eldest acceptable discovery cache.
-            Map.Entry<Long, DiscoCache> eldest = Collections.min(discoCacheHist.entrySet(), histCmp);
+            Map.Entry<AffinityTopologyVersion, DiscoCache> eldest = Collections.min(discoCacheHist.entrySet(), histCmp);
 
-            if (topVer < eldest.getKey())
+            if (topVer.compareTo(eldest.getKey()) < 0)
                 cache = eldest.getValue();
         }
 
@@ -1243,7 +1261,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
 
     /** @return Topology version. */
     public long topologyVersion() {
-        return topVer.get();
+        return topVer.get().topologyVersion();
     }
 
     /** @return Event that represents a local node joined to topology. */
@@ -1257,6 +1275,13 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
     }
 
     /**
+     * @param evt Event.
+     */
+    public void sendCustomEvent(Serializable evt) {
+        getSpi().sendCustomEvent(evt);
+    }
+
+    /**
      * Gets first grid node start time, see {@link DiscoverySpi#getGridStartTime()}.
      *
      * @return Start time of the first grid node.
@@ -1265,6 +1290,25 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
         return getSpi().getGridStartTime();
     }
 
+    /**
+     * Updates topology version if current version is smaller than updated.
+     *
+     * @param updated Updated topology version.
+     * @return {@code True} if topology was updated.
+     */
+    private boolean updateTopologyVersionIfGreater(AffinityTopologyVersion updated) {
+        while (true) {
+            AffinityTopologyVersion cur = topVer.get();
+
+            if (updated.compareTo(cur) > 0) {
+                if (topVer.compareAndSet(cur, updated))
+                    return true;
+            }
+            else
+                return false;
+        }
+    }
+
     /** Stops local node. */
     private void stopNode() {
         new Thread(
@@ -1291,13 +1335,6 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
         ).start();
     }
 
-    /**
-     * @param evt Event.
-     */
-    public void sendCustomEvent(Serializable evt) {
-        getSpi().sendCustomEvent(evt);
-    }
-
     /** Worker for network segment checks. */
     private class SegmentCheckWorker extends GridWorker {
         /** */
@@ -1353,7 +1390,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
                     lastChk = now;
 
                     if (!segValid) {
-                        discoWrk.addEvent(EVT_NODE_SEGMENTED, 0, getSpi().getLocalNode(),
+                        discoWrk.addEvent(EVT_NODE_SEGMENTED, AffinityTopologyVersion.NONE, getSpi().getLocalNode(),
                             Collections.<ClusterNode>emptyList(), null);
 
                         lastSegChkRes.set(false);
@@ -1374,7 +1411,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
     /** Worker for discovery events. */
     private class DiscoveryWorker extends GridWorker {
         /** Event queue. */
-        private final BlockingQueue<GridTuple5<Integer, Long, ClusterNode, Collection<ClusterNode>, Serializable>> evts =
+        private final BlockingQueue<GridTuple5<Integer, AffinityTopologyVersion, ClusterNode, Collection<ClusterNode>, Serializable>> evts =
             new LinkedBlockingQueue<>();
 
         /** Node segmented event fired flag. */
@@ -1437,7 +1474,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
          */
         void addEvent(
             int type,
-            long topVer,
+            AffinityTopologyVersion topVer,
             ClusterNode node,
             Collection<ClusterNode> topSnapshot,
             @Nullable Serializable data
@@ -1478,11 +1515,11 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
         /** @throws InterruptedException If interrupted. */
         @SuppressWarnings("DuplicateCondition")
         private void body0() throws InterruptedException {
-            GridTuple5<Integer, Long, ClusterNode, Collection<ClusterNode>, Serializable> evt = evts.take();
+            GridTuple5<Integer, AffinityTopologyVersion, ClusterNode, Collection<ClusterNode>, Serializable> evt = evts.take();
 
             int type = evt.get1();
 
-            long topVer = evt.get2();
+            AffinityTopologyVersion topVer = evt.get2();
 
             ClusterNode node = evt.get3();
 
@@ -1492,7 +1529,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
 
             switch (type) {
                 case EVT_NODE_JOINED: {
-                    assert !discoOrdered || topVer == node.order() : "Invalid topology version [topVer=" + topVer +
+                    assert !discoOrdered || topVer.topologyVersion() == node.order() : "Invalid topology version [topVer=" + topVer +
                         ", node=" + node + ']';
 
                     try {
@@ -1507,7 +1544,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
                             if (log.isInfoEnabled())
                                 log.info("Added new node to topology: " + node);
 
-                            ackTopology(topVer, true);
+                            ackTopology(topVer.topologyVersion(), true);
                         }
                         else if (log.isDebugEnabled())
                             log.debug("Added new node to topology: " + node);
@@ -1528,7 +1565,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
                             if (log.isInfoEnabled())
                                 log.info("Node left topology: " + node);
 
-                            ackTopology(topVer, true);
+                            ackTopology(topVer.topologyVersion(), true);
                         }
                         else if (log.isDebugEnabled())
                             log.debug("Node left topology: " + node);
@@ -1548,7 +1585,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
                         if (!isLocDaemon) {
                             U.warn(log, "Node FAILED: " + node);
 
-                            ackTopology(topVer, true);
+                            ackTopology(topVer.topologyVersion(), true);
                         }
                         else if (log.isDebugEnabled())
                             log.debug("Node FAILED: " + node);
@@ -1594,7 +1631,8 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
                         customEvt.node(ctx.discovery().localNode());
                         customEvt.eventNode(node);
                         customEvt.type(type);
-                        customEvt.topologySnapshot(topVer, null);
+                        customEvt.topologySnapshot(topVer.topologyVersion(), null);
+                        customEvt.affinityTopologyVersion(topVer);
                         customEvt.data(evt.get5());
 
                         ctx.event().record(customEvt);
@@ -1611,7 +1649,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
                     assert false : "Invalid discovery event: " + type;
             }
 
-            recordEvent(type, topVer, node, evt.get4());
+            recordEvent(type, topVer.topologyVersion(), node, evt.get4());
 
             if (segmented)
                 onSegmentation();

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentCache.java
index 9065ec5..dc103ac 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentCache.java
@@ -25,7 +25,6 @@ import org.apache.ignite.internal.*;
 import org.apache.ignite.internal.processors.cache.*;
 import org.apache.ignite.internal.util.future.*;
 import org.apache.ignite.internal.util.typedef.*;
-import org.apache.ignite.internal.util.typedef.internal.*;
 import org.jdk8.backport.*;
 import org.jetbrains.annotations.*;
 
@@ -160,7 +159,7 @@ public class GridAffinityAssignmentCache {
             sorted = Collections.singletonList(ctx.localNode());
         else {
             // Resolve nodes snapshot for specified topology version.
-            Collection<ClusterNode> nodes = ctx.discovery().cacheAffinityNodes(cacheName, topVer.topologyVersion());
+            Collection<ClusterNode> nodes = ctx.discovery().cacheAffinityNodes(cacheName, topVer);
 
             sorted = sort(nodes);
         }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheChangeBatch.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheChangeBatch.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheChangeBatch.java
index aab7fcc..3de9a99 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheChangeBatch.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheChangeBatch.java
@@ -17,6 +17,9 @@
 
 package org.apache.ignite.internal.processors.cache;
 
+import org.apache.ignite.internal.util.tostring.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
+
 import java.io.*;
 import java.util.*;
 
@@ -28,6 +31,7 @@ public class DynamicCacheChangeBatch implements Serializable {
     private static final long serialVersionUID = 0L;
 
     /** Change requests. */
+    @GridToStringInclude
     private Collection<DynamicCacheChangeRequest> reqs;
 
     /**
@@ -45,4 +49,9 @@ public class DynamicCacheChangeBatch implements Serializable {
     public Collection<DynamicCacheChangeRequest> requests() {
         return reqs;
     }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(DynamicCacheChangeBatch.class, this);
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
index 2819b96..920f932 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
@@ -292,16 +292,7 @@ public class GridCacheContext<K, V> implements Externalizable {
 
         cacheName = cacheCfg.getName();
 
-        if (cacheName != null) {
-            int hash = cacheName.hashCode();
-
-            if (hash == 0)
-                hash = 1;
-
-            cacheId = hash;
-        }
-        else
-            cacheId = 1;
+        cacheId = CU.cacheId(cacheName);
 
         sys = ctx.cache().systemCache(cacheName);
 
@@ -1939,7 +1930,7 @@ public class GridCacheContext<K, V> implements Externalizable {
                 return toCacheKeyObject(key);
             }
         });
-    };
+    }
 
     /** {@inheritDoc} */
     @Override public void writeExternal(ObjectOutput out) throws IOException {

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/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 380ddac..2358480 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
@@ -83,7 +83,8 @@ public class GridCacheGateway<K, V> {
             ctx.mvcc().contextReset();
 
             // Unwind eviction notifications.
-            CU.unwindEvicts(ctx);
+            if (!ctx.shared().closed(ctx))
+                CU.unwindEvicts(ctx);
         }
         finally {
             ctx.kernalContext().gateway().readUnlock();

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/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 1d9e97c..421d4c6 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
@@ -84,9 +84,6 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
     @GridToStringExclude
     private final ConcurrentMap<Integer, GridClientPartitionTopology> clientTops = new ConcurrentHashMap8<>();
 
-    /** Minor topology version incremented each time a new dynamic cache is started. */
-    private volatile int minorTopVer;
-
     /** */
     private volatile GridDhtPartitionsExchangeFuture lastInitializedFuture;
 
@@ -134,7 +131,7 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
                             "order [newOrder=" + n.order() + ", locOrder=" + loc.order() + ']';
 
                     exchId = exchangeId(n.id(),
-                        new AffinityTopologyVersion(e.topologyVersion(), minorTopVer = 0),
+                        affinityTopologyVersion(e),
                         e.type());
 
                     exchFut = exchangeFuture(exchId, e, null);
@@ -155,7 +152,7 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
 
                         if (!F.isEmpty(valid)) {
                             exchId = exchangeId(n.id(),
-                                new AffinityTopologyVersion(e.topologyVersion(), ++minorTopVer),
+                                affinityTopologyVersion(e),
                                 e.type());
 
                             exchFut = exchangeFuture(exchId, e, valid);
@@ -240,13 +237,13 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
 
         assert startTime > 0;
 
-        final AffinityTopologyVersion startTopVer = new AffinityTopologyVersion(loc.order(), minorTopVer);
-
-        GridDhtPartitionExchangeId exchId = exchangeId(loc.id(), startTopVer, EVT_NODE_JOINED);
-
         // Generate dummy discovery event for local node joining.
         DiscoveryEvent discoEvt = cctx.discovery().localJoinEvent();
 
+        final AffinityTopologyVersion startTopVer = affinityTopologyVersion(discoEvt);
+
+        GridDhtPartitionExchangeId exchId = exchangeId(loc.id(), startTopVer, EVT_NODE_JOINED);
+
         assert discoEvt != null;
 
         assert discoEvt.topologyVersion() == startTopVer.topologyVersion();
@@ -425,6 +422,17 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
     }
 
     /**
+     * @param evt Discovery event.
+     * @return Affinity topology version.
+     */
+    private AffinityTopologyVersion affinityTopologyVersion(DiscoveryEvent evt) {
+        if (evt.type() == DiscoveryCustomEvent.EVT_DISCOVERY_CUSTOM_EVT)
+            return ((DiscoveryCustomEvent)evt).affinityTopologyVersion();
+
+        return new AffinityTopologyVersion(evt.topologyVersion());
+    }
+
+    /**
      * @return {@code True} if topology has changed.
      */
     public boolean topologyChanged() {

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/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 0dd69cc..9d613a5 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
@@ -869,6 +869,14 @@ public class GridCacheProcessor extends GridProcessorAdapter {
                 mgr.stop(cancel);
         }
 
+        try {
+            ctx.kernalContext().query().onCacheStopped(cache.context());
+        }
+        catch (IgniteCheckedException e) {
+            // TODO implement.
+            e.printStackTrace();
+        }
+
         U.stopLifecycleAware(log, lifecycleAwares(cache.configuration(), ctx.jta().tmLookup(),
             ctx.store().configuredStore()));
 
@@ -1186,6 +1194,8 @@ public class GridCacheProcessor extends GridProcessorAdapter {
             cacheCtx.cache(dht);
         }
 
+        ctx.query().onCacheStarted(ret);
+
         return ret;
     }
 
@@ -1288,7 +1298,7 @@ public class GridCacheProcessor extends GridProcessorAdapter {
     /**
      * @param req Stop request.
      */
-    public void prepareCacheStop(DynamicCacheChangeRequest req) {
+    public void blockGateway(DynamicCacheChangeRequest req) {
         assert req.isStop();
 
         // Break the proxy before exchange future is done.
@@ -1296,6 +1306,13 @@ public class GridCacheProcessor extends GridProcessorAdapter {
 
         if (proxy != null)
             proxy.gate().onStopped();
+    }
+
+    /**
+     * @param req Stop request.
+     */
+    public void prepareCacheStop(DynamicCacheChangeRequest req) {
+        assert req.isStop();
 
         GridCacheAdapter<?, ?> cache = caches.remove(req.cacheName());
 
@@ -1326,6 +1343,8 @@ public class GridCacheProcessor extends GridProcessorAdapter {
                 jCacheProxies.put(cache.name(), new IgniteCacheProxy(cache.context(), cache, null, false));
         }
         else {
+            prepareCacheStop(req);
+
             String masked = maskNull(req.cacheName());
 
             DynamicCacheDescriptor desc = registeredCaches.get(masked);

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java
index 4be4ce7..382c6be 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java
@@ -152,6 +152,16 @@ public class GridCacheSharedContext<K, V> {
     }
 
     /**
+     * Checks if cache context is closed.
+     *
+     * @param ctx Cache context to check.
+     * @return {@code True} if cache context is closed.
+     */
+    public boolean closed(GridCacheContext ctx) {
+        return !ctxMap.containsKey(ctx.cacheId());
+    }
+
+    /**
      * @return List of shared context managers in starting order.
      */
     public List<GridCacheSharedManager<K, V>> managers() {

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/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 2617071..52789c2 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
@@ -447,7 +447,7 @@ public class GridCacheUtils {
      *      that may have already left).
      */
     public static Collection<ClusterNode> allNodes(GridCacheContext ctx) {
-        return allNodes(ctx, -1);
+        return allNodes(ctx, AffinityTopologyVersion.NONE);
     }
 
     /**
@@ -458,7 +458,7 @@ public class GridCacheUtils {
      * @return All nodes on which cache with the same name is started (including nodes
      *      that may have already left).
      */
-    public static Collection<ClusterNode> allNodes(GridCacheContext ctx, long topOrder) {
+    public static Collection<ClusterNode> allNodes(GridCacheContext ctx, AffinityTopologyVersion topOrder) {
         return ctx.discovery().cacheNodes(ctx.namex(), topOrder);
     }
 
@@ -470,7 +470,7 @@ public class GridCacheUtils {
      * @return All nodes on which cache with the same name is started (including nodes
      *      that may have already left).
      */
-    public static Collection<ClusterNode> allNodes(GridCacheSharedContext ctx, long topOrder) {
+    public static Collection<ClusterNode> allNodes(GridCacheSharedContext ctx, AffinityTopologyVersion topOrder) {
         return ctx.discovery().cacheNodes(topOrder);
     }
 
@@ -481,7 +481,7 @@ public class GridCacheUtils {
      * @param topOrder Maximum allowed node order.
      * @return Affinity nodes.
      */
-    public static Collection<ClusterNode> aliveNodes(final GridCacheContext ctx, long topOrder) {
+    public static Collection<ClusterNode> aliveNodes(final GridCacheContext ctx, AffinityTopologyVersion topOrder) {
         return ctx.discovery().aliveCacheNodes(ctx.namex(), topOrder);
     }
 
@@ -492,7 +492,7 @@ public class GridCacheUtils {
      * @return Remote nodes on which cache with the same name is started.
      */
     public static Collection<ClusterNode> remoteNodes(final GridCacheContext ctx) {
-        return remoteNodes(ctx, -1);
+        return remoteNodes(ctx, AffinityTopologyVersion.NONE);
     }
 
     /**
@@ -502,7 +502,7 @@ public class GridCacheUtils {
      * @return Collection of nodes with at least one cache configured.
      */
     public static Collection<ClusterNode> remoteNodes(GridCacheSharedContext ctx) {
-        return remoteNodes(ctx, -1);
+        return remoteNodes(ctx, AffinityTopologyVersion.NONE);
     }
 
     /**
@@ -512,7 +512,7 @@ public class GridCacheUtils {
      * @param topOrder Maximum allowed node order.
      * @return Remote nodes on which cache with the same name is started.
      */
-    public static Collection<ClusterNode> remoteNodes(final GridCacheContext ctx, long topOrder) {
+    public static Collection<ClusterNode> remoteNodes(final GridCacheContext ctx, AffinityTopologyVersion topOrder) {
         return ctx.discovery().remoteCacheNodes(ctx.namex(), topOrder);
     }
 
@@ -523,7 +523,7 @@ public class GridCacheUtils {
      * @param topOrder Maximum allowed node order.
      * @return Affinity nodes.
      */
-    public static Collection<ClusterNode> aliveRemoteNodes(final GridCacheContext ctx, long topOrder) {
+    public static Collection<ClusterNode> aliveRemoteNodes(final GridCacheContext ctx, AffinityTopologyVersion topOrder) {
         return ctx.discovery().aliveRemoteCacheNodes(ctx.namex(), topOrder);
     }
 
@@ -534,7 +534,7 @@ public class GridCacheUtils {
      * @param topVer Topology version.
      * @return Collection of remote nodes with at least one cache configured.
      */
-    public static Collection<ClusterNode> remoteNodes(final GridCacheSharedContext ctx, long topVer) {
+    public static Collection<ClusterNode> remoteNodes(final GridCacheSharedContext ctx, AffinityTopologyVersion topVer) {
         return ctx.discovery().remoteCacheNodes(topVer);
     }
 
@@ -545,7 +545,7 @@ public class GridCacheUtils {
      * @param topOrder Maximum allowed node order.
      * @return Affinity nodes.
      */
-    public static Collection<ClusterNode> aliveCacheNodes(final GridCacheSharedContext ctx, long topOrder) {
+    public static Collection<ClusterNode> aliveCacheNodes(final GridCacheSharedContext ctx, AffinityTopologyVersion topOrder) {
         return ctx.discovery().aliveNodesWithCaches(topOrder);
     }
 
@@ -556,7 +556,7 @@ public class GridCacheUtils {
      * @param topOrder Maximum allowed node order.
      * @return Affinity nodes.
      */
-    public static Collection<ClusterNode> aliveRemoteCacheNodes(final GridCacheSharedContext ctx, long topOrder) {
+    public static Collection<ClusterNode> aliveRemoteCacheNodes(final GridCacheSharedContext ctx, AffinityTopologyVersion topOrder) {
         return ctx.discovery().aliveRemoteNodesWithCaches(topOrder);
     }
 
@@ -567,18 +567,7 @@ public class GridCacheUtils {
      * @return All nodes on which cache with the same name is started.
      */
     public static Collection<ClusterNode> affinityNodes(final GridCacheContext ctx) {
-        return ctx.discovery().cacheAffinityNodes(ctx.namex(), -1);
-    }
-
-    /**
-     * Gets DHT affinity nodes.
-     *
-     * @param ctx Cache context.
-     * @param topOrder Maximum allowed node order.
-     * @return Affinity nodes.
-     */
-    public static Collection<ClusterNode> affinityNodes(GridCacheContext ctx, long topOrder) {
-        return ctx.discovery().cacheAffinityNodes(ctx.namex(), topOrder);
+        return ctx.discovery().cacheAffinityNodes(ctx.namex(), AffinityTopologyVersion.NONE);
     }
 
     /**
@@ -589,7 +578,7 @@ public class GridCacheUtils {
      * @return Affinity nodes.
      */
     public static Collection<ClusterNode> affinityNodes(GridCacheContext ctx, AffinityTopologyVersion topOrder) {
-        return affinityNodes(ctx, topOrder.topologyVersion());
+        return ctx.discovery().cacheAffinityNodes(ctx.namex(), topOrder);
     }
 
     /**
@@ -650,7 +639,7 @@ public class GridCacheUtils {
      * @return Oldest node for the current topology version.
      */
     public static ClusterNode oldest(GridCacheContext cctx) {
-        return oldest(cctx, -1);
+        return oldest(cctx, AffinityTopologyVersion.NONE);
     }
 
     /**
@@ -660,7 +649,7 @@ public class GridCacheUtils {
      * @return Oldest node.
      */
     public static ClusterNode oldest(GridCacheSharedContext ctx) {
-        return oldest(ctx, -1);
+        return oldest(ctx, AffinityTopologyVersion.NONE);
     }
 
     /**
@@ -670,15 +659,15 @@ public class GridCacheUtils {
      * @param topOrder Maximum allowed node order.
      * @return Oldest node for the given topology version.
      */
-    public static ClusterNode oldest(GridCacheContext cctx, long topOrder) {
+    public static ClusterNode oldest(GridCacheContext cctx, AffinityTopologyVersion topOrder) {
         ClusterNode oldest = null;
 
         for (ClusterNode n : aliveNodes(cctx, topOrder))
             if (oldest == null || n.order() < oldest.order())
                 oldest = n;
 
-        assert oldest != null : "Failed to find oldest node for cache context: " + cctx.name();
-        assert oldest.order() <= topOrder || topOrder < 0;
+        assert oldest != null : "Failed to find oldest node for cache context [name=" + cctx.name() + ", topOrder=" + topOrder + ']';
+        assert oldest.order() <= topOrder.topologyVersion() || AffinityTopologyVersion.NONE.equals(topOrder);
 
         return oldest;
     }
@@ -690,7 +679,7 @@ public class GridCacheUtils {
      * @param topOrder Maximum allowed node order.
      * @return Oldest node for the given topology version.
      */
-    public static ClusterNode oldest(GridCacheSharedContext cctx, long topOrder) {
+    public static ClusterNode oldest(GridCacheSharedContext cctx, AffinityTopologyVersion topOrder) {
         ClusterNode oldest = null;
 
         for (ClusterNode n : aliveCacheNodes(cctx, topOrder)) {
@@ -699,7 +688,7 @@ public class GridCacheUtils {
         }
 
         assert oldest != null : "Failed to find oldest node with caches: " + topOrder;
-        assert oldest.order() <= topOrder || topOrder < 0;
+        assert oldest.order() <= topOrder.topologyVersion() || AffinityTopologyVersion.NONE.equals(topOrder);
 
         return oldest;
     }
@@ -1541,9 +1530,21 @@ public class GridCacheUtils {
      * @return Cache ID for utility cache.
      */
     public static int utilityCacheId() {
-        int hc = UTILITY_CACHE_NAME.hashCode();
+        return cacheId(UTILITY_CACHE_NAME);
+    }
 
-        return hc == 0 ? 1 : hc;
+    /** {@inheritDoc} */
+    public static int cacheId(String cacheName) {
+        if (cacheName != null) {
+            int hash = cacheName.hashCode();
+
+            if (hash == 0)
+                hash = 1;
+
+            return hash;
+        }
+        else
+            return 1;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java
index 17af9e5..93fca43 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java
@@ -1243,18 +1243,29 @@ public class IgniteCacheProxy<K, V> extends AsyncSupportAdapter<IgniteCache<K, V
 
     /** {@inheritDoc} */
     @Override public void close() {
+        gate.enter();
+
         try {
             ctx.kernalContext().cache().dynamicStopCache(ctx.name()).get();
         }
         catch (IgniteCheckedException e) {
             throw new CacheException(e);
         }
+        finally {
+            gate.leave();
+        }
     }
 
     /** {@inheritDoc} */
     @Override public boolean isClosed() {
-        // TODO IGNITE-45 (Support start/close/destroy cache correctly)
-        return getCacheManager() == null;
+        gate.enter();
+
+        try {
+            return ctx.kernalContext().cache().context().closed(ctx);
+        }
+        finally {
+            gate.leave();
+        }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/affinity/GridCacheAffinityImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/affinity/GridCacheAffinityImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/affinity/GridCacheAffinityImpl.java
index 2de9f2f..f79193c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/affinity/GridCacheAffinityImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/affinity/GridCacheAffinityImpl.java
@@ -167,7 +167,7 @@ public class GridCacheAffinityImpl<K, V> implements CacheAffinity<K> {
 
         AffinityTopologyVersion topVer = topologyVersion();
 
-        int nodesCnt = cctx.discovery().cacheAffinityNodes(cctx.name(), topVer.topologyVersion()).size();
+        int nodesCnt = cctx.discovery().cacheAffinityNodes(cctx.name(), topVer).size();
 
         // Must return empty map if no alive nodes present or keys is empty.
         Map<ClusterNode, Collection<K>> res = new HashMap<>(nodesCnt, 1.0f);

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
index d72ee3d..646234c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
@@ -65,6 +65,9 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
     /** */
     private AffinityTopologyVersion topVer = AffinityTopologyVersion.NONE;
 
+    /** */
+    private boolean stopping;
+
     /** A future that will be completed when topology with version topVer will be ready to use. */
     private GridDhtTopologyFuture topReadyFut;
 
@@ -127,14 +130,19 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
     }
 
     /** {@inheritDoc} */
-    @Override public void updateTopologyVersion(GridDhtPartitionExchangeId exchId,
-        GridDhtPartitionsExchangeFuture exchFut) {
+    @Override public void updateTopologyVersion(
+        GridDhtPartitionExchangeId exchId,
+        GridDhtPartitionsExchangeFuture exchFut,
+        boolean stopping
+    ) {
         lock.writeLock().lock();
 
         try {
             assert exchId.topologyVersion().compareTo(topVer) > 0 : "Invalid topology version [topVer=" + topVer +
                 ", exchId=" + exchId + ']';
 
+            this.stopping = stopping;
+
             topVer = exchId.topologyVersion();
 
             topReadyFut = exchFut;
@@ -179,6 +187,9 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
         lock.writeLock().lock();
 
         try {
+            if (stopping)
+                return;
+
             assert topVer.equals(exchId.topologyVersion()) : "Invalid topology version [topVer=" +
                 topVer + ", exchId=" + exchId + ']';
 
@@ -186,7 +197,7 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
                 removeNode(exchId.nodeId());
 
             // In case if node joins, get topology at the time of joining node.
-            ClusterNode oldest = CU.oldest(cctx, topVer.topologyVersion());
+            ClusterNode oldest = CU.oldest(cctx, topVer);
 
             if (log.isDebugEnabled())
                 log.debug("Partition map beforeExchange [exchId=" + exchId + ", fullMap=" + fullMapString() + ']');
@@ -344,7 +355,7 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
      * @return List of nodes for the partition.
      */
     private List<ClusterNode> nodes(int p, AffinityTopologyVersion topVer, GridDhtPartitionState state, GridDhtPartitionState... states) {
-        Collection<UUID> allIds = topVer.topologyVersion() > 0 ? F.nodeIds(CU.allNodes(cctx, topVer.topologyVersion())) : null;
+        Collection<UUID> allIds = topVer.topologyVersion() > 0 ? F.nodeIds(CU.allNodes(cctx, topVer)) : null;
 
         lock.readLock().lock();
 
@@ -535,6 +546,9 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
         lock.writeLock().lock();
 
         try {
+            if (stopping)
+                return null;
+
             if (lastExchangeId != null && exchId != null && lastExchangeId.compareTo(exchId) > 0) {
                 if (log.isDebugEnabled())
                     log.debug("Stale exchange id for single partition map update (will ignore) [lastExchId=" +
@@ -624,7 +638,7 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
         assert nodeId.equals(cctx.localNodeId());
 
         // In case if node joins, get topology at the time of joining node.
-        ClusterNode oldest = CU.oldest(cctx, topVer.topologyVersion());
+        ClusterNode oldest = CU.oldest(cctx, topVer);
 
         // If this node became the oldest node.
         if (oldest.id().equals(cctx.localNodeId())) {
@@ -674,7 +688,7 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
         assert nodeId != null;
         assert lock.writeLock().isHeldByCurrentThread();
 
-        ClusterNode oldest = CU.oldest(cctx, topVer.topologyVersion());
+        ClusterNode oldest = CU.oldest(cctx, topVer);
 
         ClusterNode loc = cctx.localNode();
 
@@ -723,6 +737,9 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
         lock.writeLock().lock();
 
         try {
+            if (stopping)
+                return;
+
             assert part.state() == EVICTED;
 
             long seq = updateSeq ? this.updateSeq.incrementAndGet() : this.updateSeq.get();

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java
index 1e61223..7db15c7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java
@@ -47,7 +47,7 @@ public interface GridDhtPartitionTopology {
      * @param exchId Exchange ID.
      * @param exchFut Exchange future.
      */
-    public void updateTopologyVersion(GridDhtPartitionExchangeId exchId, GridDhtPartitionsExchangeFuture exchFut);
+    public void updateTopologyVersion(GridDhtPartitionExchangeId exchId, GridDhtPartitionsExchangeFuture exchFut, boolean stopping);
 
     /**
      * Topology version.

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
index 86cb805..e7ce96f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
@@ -68,6 +68,9 @@ class GridDhtPartitionTopologyImpl<K, V> implements GridDhtPartitionTopology {
     /** */
     private AffinityTopologyVersion topVer = AffinityTopologyVersion.NONE;
 
+    /** */
+    private boolean stopping;
+
     /** A future that will be completed when topology with version topVer will be ready to use. */
     private GridDhtTopologyFuture topReadyFut;
 
@@ -81,6 +84,8 @@ class GridDhtPartitionTopologyImpl<K, V> implements GridDhtPartitionTopology {
      * @param cctx Context.
      */
     GridDhtPartitionTopologyImpl(GridCacheContext<K, V> cctx) {
+        assert cctx != null;
+
         this.cctx = cctx;
 
         log = cctx.logger(getClass());
@@ -150,14 +155,19 @@ class GridDhtPartitionTopologyImpl<K, V> implements GridDhtPartitionTopology {
     }
 
     /** {@inheritDoc} */
-    @Override public void updateTopologyVersion(GridDhtPartitionExchangeId exchId,
-        GridDhtPartitionsExchangeFuture exchFut) {
+    @Override public void updateTopologyVersion(
+        GridDhtPartitionExchangeId exchId,
+        GridDhtPartitionsExchangeFuture exchFut,
+        boolean stopping
+    ) {
         lock.writeLock().lock();
 
         try {
             assert exchId.topologyVersion().compareTo(topVer) > 0 : "Invalid topology version [topVer=" + topVer +
                 ", exchId=" + exchId + ']';
 
+            this.stopping = stopping;
+
             topVer = exchId.topologyVersion();
 
             topReadyFut = exchFut;
@@ -207,6 +217,9 @@ class GridDhtPartitionTopologyImpl<K, V> implements GridDhtPartitionTopology {
         lock.writeLock().lock();
 
         try {
+            if (stopping)
+                return;
+
             assert topVer.equals(exchId.topologyVersion()) : "Invalid topology version [topVer=" +
                 topVer + ", exchId=" + exchId + ']';
 
@@ -214,7 +227,7 @@ class GridDhtPartitionTopologyImpl<K, V> implements GridDhtPartitionTopology {
                 removeNode(exchId.nodeId());
 
             // In case if node joins, get topology at the time of joining node.
-            ClusterNode oldest = CU.oldest(cctx, topVer.topologyVersion());
+            ClusterNode oldest = CU.oldest(cctx, topVer);
 
             if (log.isDebugEnabled())
                 log.debug("Partition map beforeExchange [exchId=" + exchId + ", fullMap=" + fullMapString() + ']');
@@ -222,7 +235,7 @@ class GridDhtPartitionTopologyImpl<K, V> implements GridDhtPartitionTopology {
             long updateSeq = this.updateSeq.incrementAndGet();
 
             // If this is the oldest node.
-            if (oldest.id().equals(loc.id()) || exchId.isCacheAdded()) {
+            if (oldest.id().equals(loc.id()) || exchId.isCacheAdded(cctx.cacheId())) {
                 if (node2part == null) {
                     node2part = new GridDhtPartitionFullMap(loc.id(), loc.order(), updateSeq);
 
@@ -249,8 +262,8 @@ class GridDhtPartitionTopologyImpl<K, V> implements GridDhtPartitionTopology {
             if (cctx.preloadEnabled()) {
                 for (int p = 0; p < num; p++) {
                     // If this is the first node in grid.
-                    if ((oldest.id().equals(loc.id()) && oldest.id().equals(exchId.nodeId())) || exchId.isCacheAdded()) {
-                        assert exchId.isJoined() || exchId.isCacheAdded();
+                    if ((oldest.id().equals(loc.id()) && oldest.id().equals(exchId.nodeId())) || exchId.isCacheAdded(cctx.cacheId())) {
+                        assert exchId.isJoined() || exchId.isCacheAdded(cctx.cacheId());
 
                         try {
                             GridDhtLocalPartition locPart = localPartition(p, topVer, true, false);
@@ -373,6 +386,9 @@ class GridDhtPartitionTopologyImpl<K, V> implements GridDhtPartitionTopology {
         lock.writeLock().lock();
 
         try {
+            if (stopping)
+                return false;
+
             assert topVer.equals(exchId.topologyVersion()) : "Invalid topology version [topVer=" +
                 topVer + ", exchId=" + exchId + ']';
 
@@ -622,7 +638,7 @@ class GridDhtPartitionTopologyImpl<K, V> implements GridDhtPartitionTopology {
      * @return List of nodes for the partition.
      */
     private List<ClusterNode> nodes(int p, AffinityTopologyVersion topVer, GridDhtPartitionState state, GridDhtPartitionState... states) {
-        Collection<UUID> allIds = topVer.topologyVersion() > 0 ? F.nodeIds(CU.allNodes(cctx, topVer.topologyVersion())) : null;
+        Collection<UUID> allIds = topVer.topologyVersion() > 0 ? F.nodeIds(CU.allNodes(cctx, topVer)) : null;
 
         lock.readLock().lock();
 
@@ -721,6 +737,9 @@ class GridDhtPartitionTopologyImpl<K, V> implements GridDhtPartitionTopology {
         lock.writeLock().lock();
 
         try {
+            if (stopping)
+                return null;
+
             if (exchId != null && lastExchangeId != null && lastExchangeId.compareTo(exchId) >= 0) {
                 if (log.isDebugEnabled())
                     log.debug("Stale exchange id for full partition map update (will ignore) [lastExchId=" +
@@ -821,6 +840,9 @@ class GridDhtPartitionTopologyImpl<K, V> implements GridDhtPartitionTopology {
         lock.writeLock().lock();
 
         try {
+            if (stopping)
+                return null;
+
             if (lastExchangeId != null && exchId != null && lastExchangeId.compareTo(exchId) > 0) {
                 if (log.isDebugEnabled())
                     log.debug("Stale exchange id for single partition map update (will ignore) [lastExchId=" +
@@ -980,7 +1002,7 @@ class GridDhtPartitionTopologyImpl<K, V> implements GridDhtPartitionTopology {
         assert nodeId.equals(cctx.nodeId());
 
         // In case if node joins, get topology at the time of joining node.
-        ClusterNode oldest = CU.oldest(cctx, topVer.topologyVersion());
+        ClusterNode oldest = CU.oldest(cctx, topVer);
 
         // If this node became the oldest node.
         if (oldest.id().equals(cctx.nodeId())) {
@@ -1030,7 +1052,7 @@ class GridDhtPartitionTopologyImpl<K, V> implements GridDhtPartitionTopology {
         assert nodeId != null;
         assert lock.writeLock().isHeldByCurrentThread();
 
-        ClusterNode oldest = CU.oldest(cctx, topVer.topologyVersion());
+        ClusterNode oldest = CU.oldest(cctx, topVer);
 
         ClusterNode loc = cctx.localNode();
 
@@ -1096,6 +1118,9 @@ class GridDhtPartitionTopologyImpl<K, V> implements GridDhtPartitionTopology {
         lock.writeLock().lock();
 
         try {
+            if (stopping)
+                return;
+
             assert part.state() == EVICTED;
 
             long seq = updateSeq ? this.updateSeq.incrementAndGet() : this.updateSeq.get();

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
index c8ff3e2..ec2621c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
@@ -229,6 +229,12 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
         });
     }
 
+    /** {@inheritDoc} */
+    @Override public void stop() {
+        for (DeferredResponseBuffer buf : pendingResponses.values())
+            buf.finish();
+    }
+
     /**
      * @param near Near cache.
      */
@@ -1638,7 +1644,7 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
 
         AffinityTopologyVersion topVer = req.topologyVersion();
 
-        boolean checkReaders = hasNear || ctx.discovery().hasNearCache(name(), topVer.topologyVersion());
+        boolean checkReaders = hasNear || ctx.discovery().hasNearCache(name(), topVer);
 
         boolean readersOnly = false;
 
@@ -1864,7 +1870,7 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
 
         AffinityTopologyVersion topVer = req.topologyVersion();
 
-        boolean checkReaders = hasNear || ctx.discovery().hasNearCache(name(), topVer.topologyVersion());
+        boolean checkReaders = hasNear || ctx.discovery().hasNearCache(name(), topVer);
 
         CacheStorePartialUpdateException storeErr = null;
 
@@ -2337,7 +2343,7 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
 
             AffinityTopologyVersion topVer = updateReq.topologyVersion();
 
-            Collection<ClusterNode> nodes = ctx.kernalContext().discovery().cacheAffinityNodes(name(), topVer.topologyVersion());
+            Collection<ClusterNode> nodes = ctx.kernalContext().discovery().cacheAffinityNodes(name(), topVer);
 
             // We are on primary node for some key.
             assert !nodes.isEmpty();
@@ -2898,13 +2904,13 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
                 respVers);
 
             try {
-                ctx.gate().enter();
+                ctx.kernalContext().gateway().readLock();
 
                 try {
                     ctx.io().send(nodeId, msg, ctx.ioPolicy());
                 }
                 finally {
-                    ctx.gate().leave();
+                    ctx.kernalContext().gateway().readUnlock();
                 }
             }
             catch (IllegalStateException ignored) {

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
index f5c502c..6fd60dd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
@@ -447,7 +447,7 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
                     assert topVer.compareTo(AffinityTopologyVersion.ZERO) > 0;
 
                     if (map == null) {
-                        Collection<ClusterNode> affNodes = CU.allNodes(ctx, topVer.topologyVersion());
+                        Collection<ClusterNode> affNodes = CU.allNodes(ctx, topVer);
 
                         keyCnt = (int)Math.ceil((double)keys.size() / affNodes.size());
 
@@ -539,7 +539,7 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
                     AffinityTopologyVersion topVer = lock.topologyVersion();
 
                     if (map == null) {
-                        Collection<ClusterNode> affNodes = CU.allNodes(ctx, topVer.topologyVersion());
+                        Collection<ClusterNode> affNodes = CU.allNodes(ctx, topVer);
 
                         keyCnt = (int)Math.ceil((double)keys.size() / affNodes.size());
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionExchangeId.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionExchangeId.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionExchangeId.java
index 0326444..96cd7cb 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionExchangeId.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionExchangeId.java
@@ -17,7 +17,6 @@
 
 package org.apache.ignite.internal.processors.cache.distributed.dht.preloader;
 
-import org.apache.ignite.internal.events.*;
 import org.apache.ignite.internal.processors.affinity.*;
 import org.apache.ignite.internal.util.tostring.*;
 import org.apache.ignite.internal.util.typedef.internal.*;
@@ -110,7 +109,7 @@ public class GridDhtPartitionExchangeId implements Message, Comparable<GridDhtPa
     /**
      * @return {@code True} if cache was added with this exchange ID.
      */
-    public boolean isCacheAdded() {
+    public boolean isCacheAdded(int cacheId) {
         // TODO IGNITE-45 add cache added flag.
         return evt == EVT_DISCOVERY_CUSTOM_EVT;
     }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
index 1933ae6..e09ad2d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
@@ -218,7 +218,7 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
         log = cctx.logger(getClass());
 
         // Grab all nodes with order of equal or less than last joined node.
-        oldestNode.set(CU.oldest(cctx, exchId.topologyVersion().topologyVersion()));
+        oldestNode.set(CU.oldest(cctx, exchId.topologyVersion()));
 
         assert oldestNode.get() != null;
 
@@ -424,12 +424,12 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
                 for (GridCacheContext cacheCtx : cctx.cacheContexts()) {
                     // Update before waiting for locks.
                     if (!cacheCtx.isLocal())
-                        cacheCtx.topology().updateTopologyVersion(exchId, this);
+                        cacheCtx.topology().updateTopologyVersion(exchId, this, stopping(cacheCtx.cacheId()));
                 }
 
                 // Grab all alive remote nodes with order of equal or less than last joined node.
                 rmtNodes = new ConcurrentLinkedQueue<>(CU.aliveRemoteCacheNodes(cctx,
-                    exchId.topologyVersion().topologyVersion()));
+                    exchId.topologyVersion()));
 
                 rmtIds = Collections.unmodifiableSet(new HashSet<>(F.nodeIds(rmtNodes)));
 
@@ -467,7 +467,7 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
                     log.debug("After waiting for partition release future: " + this);
 
                 if (!F.isEmpty(reqs))
-                    stopCaches();
+                    blockGateways();
 
                 for (GridCacheContext cacheCtx : cctx.cacheContexts()) {
                     if (cacheCtx.isLocal())
@@ -492,7 +492,7 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
                 }
 
                 for (GridClientPartitionTopology top : cctx.exchange().clientTopologies()) {
-                    top.updateTopologyVersion(exchId, this);
+                    top.updateTopologyVersion(exchId, this, stopping(top.cacheId()));
 
                     top.beforeExchange(exchId);
                 }
@@ -553,6 +553,26 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
     }
 
     /**
+     * @param cacheId Cache ID to check.
+     * @return {@code True} if cache is stopping by this exchange.
+     */
+    private boolean stopping(int cacheId) {
+        boolean stopping = false;
+
+        if (!F.isEmpty(reqs)) {
+            for (DynamicCacheChangeRequest req : reqs) {
+                if (cacheId == CU.cacheId(req.cacheName())) {
+                    stopping = req.isStop();
+
+                    break;
+                }
+            }
+        }
+
+        return stopping;
+    }
+
+    /**
      * Starts dynamic caches.
      */
     private void startCaches() throws IgniteCheckedException {
@@ -563,12 +583,12 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
     }
 
     /**
-     * Stop dynamic caches.
+     *
      */
-    private void stopCaches() {
+    private void blockGateways() {
         for (DynamicCacheChangeRequest req : reqs) {
             if (req.isStop())
-                cctx.cache().prepareCacheStop(req);
+                cctx.cache().blockGateway(req);
         }
     }
 
@@ -961,7 +981,7 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
 
                             boolean set = false;
 
-                            ClusterNode newOldest = CU.oldest(cctx, exchId.topologyVersion().topologyVersion());
+                            ClusterNode newOldest = CU.oldest(cctx, exchId.topologyVersion());
 
                             // If local node is now oldest.
                             if (newOldest.id().equals(cctx.localNodeId())) {

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
index 038ea3f..71e173b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
@@ -500,7 +500,7 @@ public class GridNearTransactionalCache<K, V> extends GridNearCacheAdapter<K, V>
                             ver = cand.version();
 
                             if (map == null) {
-                                Collection<ClusterNode> affNodes = CU.allNodes(ctx, cand.topologyVersion().topologyVersion());
+                                Collection<ClusterNode> affNodes = CU.allNodes(ctx, cand.topologyVersion());
 
                                 if (F.isEmpty(affNodes))
                                     return;
@@ -617,7 +617,7 @@ public class GridNearTransactionalCache<K, V> extends GridNearCacheAdapter<K, V>
 
                             if (cand != null) {
                                 if (map == null) {
-                                    Collection<ClusterNode> affNodes = CU.allNodes(ctx, cand.topologyVersion().topologyVersion());
+                                    Collection<ClusterNode> affNodes = CU.allNodes(ctx, cand.topologyVersion());
 
                                     if (F.isEmpty(affNodes))
                                         return;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManager.java
index 2ad10d5..53fadd9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManager.java
@@ -26,6 +26,7 @@ import org.apache.ignite.igfs.*;
 import org.apache.ignite.igfs.secondary.*;
 import org.apache.ignite.internal.*;
 import org.apache.ignite.internal.managers.eventstorage.*;
+import org.apache.ignite.internal.processors.affinity.*;
 import org.apache.ignite.internal.processors.cache.*;
 import org.apache.ignite.internal.processors.cache.transactions.*;
 import org.apache.ignite.internal.processors.task.*;
@@ -155,7 +156,7 @@ public class IgfsMetaManager extends IgfsManager {
     Collection<ClusterNode> metaCacheNodes() {
         if (busyLock.enterBusy()) {
             try {
-                return igfsCtx.kernalContext().discovery().cacheNodes(metaCache.name(), -1);
+                return igfsCtx.kernalContext().discovery().cacheNodes(metaCache.name(), AffinityTopologyVersion.NONE);
             }
             finally {
                 busyLock.leaveBusy();

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java
index 6ec2f00..2208341 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.processors.query;
 
 import org.apache.ignite.*;
 import org.apache.ignite.internal.*;
+import org.apache.ignite.internal.processors.cache.*;
 import org.apache.ignite.internal.processors.cache.query.*;
 import org.apache.ignite.internal.util.lang.*;
 import org.apache.ignite.lang.*;
@@ -46,6 +47,17 @@ public interface GridQueryIndexing {
      */
     public void stop() throws IgniteCheckedException;
 
+    /**
+     * @param ctx Cache context.
+     * @throws IgniteCheckedException If failed.
+     */
+    public void onCacheStarted(GridCacheContext ctx) throws IgniteCheckedException;
+
+    /**
+     * @param ctx Cache context.
+     * @throws IgniteCheckedException If failed.
+     */
+    public void onCacheStopped(GridCacheContext ctx) throws IgniteCheckedException;
 
     /**
      * Runs two step query.

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
index 786cde7..202aed0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
@@ -141,6 +141,46 @@ public class GridQueryProcessor extends GridProcessorAdapter {
     }
 
     /**
+     * @param cctx Cache context.
+     * @throws IgniteCheckedException If failed.
+     */
+    public void onCacheStarted(GridCacheContext cctx) throws IgniteCheckedException {
+        if (idx == null)
+            return;
+
+        if (!busyLock.enterBusy())
+            return;
+
+        try {
+            idx.onCacheStarted(cctx);
+        }
+        finally {
+            busyLock.leaveBusy();
+        }
+    }
+
+    /**
+     * @param cctx Cache context.
+     */
+    public void onCacheStopped(GridCacheContext cctx) {
+        if (idx == null)
+            return;
+
+        if (!busyLock.enterBusy())
+            return;
+
+        try {
+            idx.onCacheStopped(cctx);
+        }
+        catch (IgniteCheckedException e) {
+            U.error(log, "Failed to clear indexing on cache stop (will ignore): " + cctx.name(), e);
+        }
+        finally {
+            busyLock.leaveBusy();
+        }
+    }
+
+    /**
      * Returns number of objects of given type for given space of spi.
      *
      * @param space Space.

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/modules/core/src/main/java/org/apache/ignite/internal/processors/resource/GridResourceProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/resource/GridResourceProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/resource/GridResourceProcessor.java
index f08a287..3611a09 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/resource/GridResourceProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/resource/GridResourceProcessor.java
@@ -25,6 +25,7 @@ import org.apache.ignite.internal.managers.deployment.*;
 import org.apache.ignite.internal.processors.*;
 import org.apache.ignite.internal.util.lang.*;
 import org.apache.ignite.internal.util.typedef.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
 import org.apache.ignite.lifecycle.*;
 import org.apache.ignite.resources.*;
 import org.apache.ignite.services.*;
@@ -249,6 +250,7 @@ public class GridResourceProcessor extends GridProcessorAdapter {
         if (obj != null) {
             if (log.isDebugEnabled())
                 log.debug("Cleaning up resources: " + obj);
+            U.debug(log, "Cleaning up resources: " + obj);
 
             // Unwrap Proxy object.
             obj = unwrapTarget(obj);

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/aa989909/modules/core/src/test/java/org/apache/ignite/internal/GridDiscoverySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/GridDiscoverySelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/GridDiscoverySelfTest.java
index 6169cb8..4a2483d 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/GridDiscoverySelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/GridDiscoverySelfTest.java
@@ -23,6 +23,7 @@ import org.apache.ignite.cluster.*;
 import org.apache.ignite.configuration.*;
 import org.apache.ignite.events.*;
 import org.apache.ignite.internal.managers.discovery.*;
+import org.apache.ignite.internal.processors.affinity.*;
 import org.apache.ignite.internal.util.lang.*;
 import org.apache.ignite.internal.util.typedef.*;
 import org.apache.ignite.lang.*;
@@ -284,7 +285,7 @@ public class GridDiscoverySelfTest extends GridCommonAbstractTest {
                 // 6          +     +
                 // 7          +       - only local node
 
-                Collection<ClusterNode> cacheNodes = discoMgr.cacheNodes(null, ver);
+                Collection<ClusterNode> cacheNodes = discoMgr.cacheNodes(null, new AffinityTopologyVersion(ver));
 
                 Collection<UUID> act = new ArrayList<>(F.viewReadOnly(cacheNodes, new C1<ClusterNode, UUID>() {
                     @Override public UUID apply(ClusterNode n) {


Mime
View raw message