ignite-5272
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/86065d20 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/86065d20 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/86065d20 Branch: refs/heads/ignite-5272 Commit: 86065d20f98d6d7428e51a70c332cbd471a94adb Parents: 721d568 Author: sboikov <[email protected]> Authored: Tue Jun 13 11:00:21 2017 +0300 Committer: sboikov <[email protected]> Committed: Tue Jun 13 14:53:42 2017 +0300 ---------------------------------------------------------------------- .../internal/managers/discovery/DiscoCache.java | 17 -- .../discovery/GridDiscoveryManager.java | 17 -- .../processors/cache/GridCacheIoManager.java | 213 +++++++++++---- .../processors/cache/GridCacheProcessor.java | 40 ++- .../dht/GridDhtTxPrepareRequest.java | 43 ++- .../dht/GridDhtTxPrepareResponse.java | 6 +- .../dht/atomic/GridDhtAtomicCache.java | 14 +- .../dht/atomic/GridDhtAtomicUpdateResponse.java | 11 +- .../distributed/near/GridNearCacheEntry.java | 5 - .../cache/transactions/IgniteTxEntry.java | 7 + .../cache/transactions/IgniteTxHandler.java | 13 +- .../cache/transactions/IgniteTxManager.java | 27 ++ .../IgniteDynamicClientCacheStartSelfTest.java | 49 ++++ .../cache/IgniteNearClientCacheCloseTest.java | 264 +++++++++++++++++++ .../cache/IgniteNearClientCacheTest.java | 87 ------ .../testsuites/IgniteCacheTestSuite2.java | 2 + 16 files changed, 617 insertions(+), 198 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/86065d20/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoCache.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoCache.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoCache.java index 22c2d07..2b3c4fc 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoCache.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoCache.java @@ -74,10 +74,6 @@ public class DiscoCache { /** Node map. */ private final Map<UUID, ClusterNode> nodeMap; - /** Caches where at least one node has near cache enabled. */ - @GridToStringInclude - private final Set<Integer> nearEnabledCaches; - /** Alive nodes. */ private final Set<UUID> alives = new GridConcurrentHashSet<>(); @@ -93,7 +89,6 @@ public class DiscoCache { * @param allCacheNodes Cache nodes by cache name. * @param cacheGrpAffNodes Affinity nodes by cache group ID. * @param nodeMap Node map. - * @param nearEnabledCaches Caches where at least one node has near cache enabled. * @param alives Alive nodes. */ DiscoCache(ClusterNode loc, @@ -107,7 +102,6 @@ public class DiscoCache { Map<Integer, List<ClusterNode>> allCacheNodes, Map<Integer, List<ClusterNode>> cacheGrpAffNodes, Map<UUID, ClusterNode> nodeMap, - Set<Integer> nearEnabledCaches, Set<UUID> alives) { this.loc = loc; this.rmtNodes = rmtNodes; @@ -120,7 +114,6 @@ public class DiscoCache { this.allCacheNodes = allCacheNodes; this.cacheGrpAffNodes = cacheGrpAffNodes; this.nodeMap = nodeMap; - this.nearEnabledCaches = nearEnabledCaches; this.alives.addAll(alives); } @@ -243,16 +236,6 @@ public class DiscoCache { } /** - * Checks if cache with given ID has at least one node with near cache enabled. - * - * @param cacheId Cache ID. - * @return {@code True} if cache with given name has at least one node with near cache enabled. - */ - public boolean hasNearCache(int cacheId) { - return nearEnabledCaches.contains(cacheId); - } - - /** * @param id Node ID. * @return Node. */ http://git-wip-us.apache.org/repos/asf/ignite/blob/86065d20/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 ca2b829..b7024ab 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 @@ -1866,17 +1866,6 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> { } /** - * Checks if cache with given ID has at least one node with near cache enabled. - * - * @param cacheId Cache ID. - * @param topVer Topology version. - * @return {@code True} if cache with given name has at least one node with near cache enabled. - */ - public boolean hasNearCache(int cacheId, AffinityTopologyVersion topVer) { - return resolveDiscoCache(cacheId, topVer).hasNearCache(cacheId); - } - - /** * Gets discovery cache for given topology version. * * @param grpId Cache group ID (participates in exception message). @@ -2131,8 +2120,6 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> { Set<ClusterNode> rmtNodesWithCaches = new TreeSet<>(GridNodeOrderComparator.INSTANCE); Set<ClusterNode> srvNodesWithCaches = new TreeSet<>(GridNodeOrderComparator.INSTANCE); - Set<Integer> nearEnabledCaches = new HashSet<>(); - for (ClusterNode node : allNodes) { assert node.order() != 0 : "Invalid node order [locNode=" + loc + ", node=" + node + ']'; assert !node.isDaemon(); @@ -2165,9 +2152,6 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> { rmtNodesWithCaches.add(node); addToMap(allCacheNodes, cacheName, node); - - if (filter.nearNode(node)) - nearEnabledCaches.add(CU.cacheId(cacheName)); } } } @@ -2184,7 +2168,6 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> { Collections.unmodifiableMap(allCacheNodes), Collections.unmodifiableMap(cacheGrpAffNodes), Collections.unmodifiableMap(nodeMap), - Collections.unmodifiableSet(nearEnabledCaches), alives); } http://git-wip-us.apache.org/repos/asf/ignite/blob/86065d20/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIoManager.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIoManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIoManager.java index 37e495e..09eea27 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIoManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIoManager.java @@ -36,6 +36,7 @@ import org.apache.ignite.binary.BinaryObjectException; import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.internal.IgniteInternalFuture; import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException; +import org.apache.ignite.internal.managers.communication.GridIoPolicy; import org.apache.ignite.internal.managers.communication.GridMessageListener; import org.apache.ignite.internal.managers.deployment.GridDeploymentInfo; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; @@ -301,52 +302,151 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter { */ @SuppressWarnings("unchecked") private void handleMessage(UUID nodeId, GridCacheMessage cacheMsg, MessageHandlers msgHandlers) { - int msgIdx = cacheMsg.lookupIndex(); + Lock lock = rw.readLock(); - IgniteBiInClosure<UUID, GridCacheMessage> c = null; + lock.lock(); - if (msgIdx >= 0) { - Map<Integer, IgniteBiInClosure[]> idxClsHandlers0 = msgHandlers.idxClsHandlers; + try { + int msgIdx = cacheMsg.lookupIndex(); - IgniteBiInClosure[] cacheClsHandlers = idxClsHandlers0.get(cacheMsg.handlerId()); + IgniteBiInClosure<UUID, GridCacheMessage> c = null; - if (cacheClsHandlers != null) - c = cacheClsHandlers[msgIdx]; - } + if (msgIdx >= 0) { + Map<Integer, IgniteBiInClosure[]> idxClsHandlers0 = msgHandlers.idxClsHandlers; - if (c == null) - c = msgHandlers.clsHandlers.get(new ListenerKey(cacheMsg.handlerId(), cacheMsg.getClass())); + IgniteBiInClosure[] cacheClsHandlers = idxClsHandlers0.get(cacheMsg.handlerId()); - if (c == null) { - IgniteLogger log = cacheMsg.messageLogger(cctx); + if (cacheClsHandlers != null) + c = cacheClsHandlers[msgIdx]; + } - StringBuilder msg0 = new StringBuilder("Received message without registered handler (will ignore) ["); + if (c == null) + c = msgHandlers.clsHandlers.get(new ListenerKey(cacheMsg.handlerId(), cacheMsg.getClass())); - appendMessageInfo(cacheMsg, nodeId, msg0); + if (c == null) { + if (processMissedHandler(nodeId, cacheMsg)) + return; - msg0.append(", locTopVer=").append(cctx.exchange().readyAffinityVersion()). - append(", msgTopVer=").append(cacheMsg.topologyVersion()). - append(", desc=").append(descriptorForMessage(cacheMsg)). - append(']'); + IgniteLogger log = cacheMsg.messageLogger(cctx); - msg0.append(U.nl()).append("Registered listeners:"); + StringBuilder msg0 = new StringBuilder("Received message without registered handler (will ignore) ["); - Map<Integer, IgniteBiInClosure[]> idxClsHandlers0 = msgHandlers.idxClsHandlers; + appendMessageInfo(cacheMsg, nodeId, msg0); - for (Map.Entry<Integer, IgniteBiInClosure[]> e : idxClsHandlers0.entrySet()) - msg0.append(U.nl()).append(e.getKey()).append("=").append(Arrays.toString(e.getValue())); + msg0.append(", locTopVer=").append(cctx.exchange().readyAffinityVersion()). + append(", msgTopVer=").append(cacheMsg.topologyVersion()). + append(", desc=").append(descriptorForMessage(cacheMsg)). + append(']'); - if (cctx.kernalContext().isStopping()) { - if (log.isDebugEnabled()) - log.debug(msg0.toString()); + msg0.append(U.nl()).append("Registered listeners:"); + + Map<Integer, IgniteBiInClosure[]> idxClsHandlers0 = msgHandlers.idxClsHandlers; + + for (Map.Entry<Integer, IgniteBiInClosure[]> e : idxClsHandlers0.entrySet()) + msg0.append(U.nl()).append(e.getKey()).append("=").append(Arrays.toString(e.getValue())); + + if (cctx.kernalContext().isStopping()) { + if (log.isDebugEnabled()) + log.debug(msg0.toString()); + } + else + U.error(log, msg0.toString()); + + return; } - else - U.error(log, msg0.toString()); - return; + onMessage0(nodeId, cacheMsg, c); + } + finally { + lock.unlock(); } + } + + /** + * @param nodeId Node ID. + * @param cacheMsg Message. + * @return {@code True} if message processed. + */ + private boolean processMissedHandler(UUID nodeId, GridCacheMessage cacheMsg) { + // It is possible to receive reader update after client near cache was closed. + if (cacheMsg instanceof GridDhtAtomicAbstractUpdateRequest) { + GridDhtAtomicAbstractUpdateRequest req = (GridDhtAtomicAbstractUpdateRequest)cacheMsg; + + if (req.nearSize() > 0) { + List<KeyCacheObject> nearEvicted = new ArrayList<>(req.nearSize()); + + for (int i = 0; i < req.nearSize(); i++) + nearEvicted.add(req.nearKey(i)); + + GridDhtAtomicUpdateResponse dhtRes = new GridDhtAtomicUpdateResponse(req.cacheId(), + req.partition(), + req.futureId(), + false); + + dhtRes.nearEvicted(nearEvicted); + + sendMessageForMissedHandler(cacheMsg, + nodeId, + dhtRes, + nodeId, + GridIoPolicy.SYSTEM_POOL); + + if (req.nearNodeId() != null) { + GridDhtAtomicNearResponse nearRes = new GridDhtAtomicNearResponse(req.cacheId(), + req.partition(), + req.nearFutureId(), + nodeId, + req.flags()); + + sendMessageForMissedHandler(cacheMsg, + nodeId, + nearRes, + req.nearNodeId(), + GridIoPolicy.SYSTEM_POOL); + } + + return true; + } + } + + return false; + } + + /** + * @param origMsg Message without handler. + * @param origMsgNode Node sent {@code origMsg}. + * @param nodeId Target node ID. + * @param msg Response. + * @param plc Policy. + */ + private void sendMessageForMissedHandler( + GridCacheMessage origMsg, + UUID origMsgNode, + GridCacheMessage msg, + UUID nodeId, + byte plc) { + IgniteLogger log = msg.messageLogger(cctx); - onMessage0(nodeId, cacheMsg, c); + try { + if (log.isDebugEnabled()) { + log.debug("Received message without registered handler, " + + "send response [locTopVer=" + cctx.exchange().readyAffinityVersion() + + ", msgTopVer=" + origMsg.topologyVersion() + + ", node=" + origMsgNode + + ", msg=" + origMsg + + ", resNode=" + nodeId + + ", res=" + msg + ']'); + } + + send(nodeId, msg, plc); + } + catch (ClusterTopologyCheckedException e) { + if (log.isDebugEnabled()) + log.debug("Failed to send response, node left [nodeId=" + nodeId + ", msg=" + msg + ']'); + } + catch (IgniteCheckedException e) { + U.error(log, "Failed to send response [nodeId=" + nodeId + ", msg=" + msg + ", err=" + e + ']'); + } } /** {@inheritDoc} */ @@ -359,17 +459,10 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter { cctx.gridIO().addMessageListener(TOPIC_CACHE, lsnr); } - /** {@inheritDoc} */ - @SuppressWarnings("BusyWait") - @Override protected void onKernalStop0(boolean cancel) { - cctx.gridIO().removeMessageListener(TOPIC_CACHE); - - for (Object ordTopic : cacheHandlers.orderedHandlers.keySet()) - cctx.gridIO().removeMessageListener(ordTopic); - - for (Object ordTopic : grpHandlers.orderedHandlers.keySet()) - cctx.gridIO().removeMessageListener(ordTopic); - + /** + * + */ + public void writeLock() { boolean interrupted = false; // Busy wait is intentional. @@ -389,6 +482,27 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter { if (interrupted) Thread.currentThread().interrupt(); + } + + /** + * + */ + public void writeUnlock() { + rw.writeLock().unlock(); + } + + /** {@inheritDoc} */ + @SuppressWarnings("BusyWait") + @Override protected void onKernalStop0(boolean cancel) { + cctx.gridIO().removeMessageListener(TOPIC_CACHE); + + for (Object ordTopic : cacheHandlers.orderedHandlers.keySet()) + cctx.gridIO().removeMessageListener(ordTopic); + + for (Object ordTopic : grpHandlers.orderedHandlers.keySet()) + cctx.gridIO().removeMessageListener(ordTopic); + + writeLock(); try { stopping = true; @@ -406,10 +520,6 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter { @SuppressWarnings({"unchecked", "ConstantConditions", "ThrowableResultOfMethodCallIgnored"}) private void onMessage0(final UUID nodeId, final GridCacheMessage cacheMsg, final IgniteBiInClosure<UUID, GridCacheMessage> c) { - Lock lock = rw.readLock(); - - lock.lock(); - try { if (stopping) { if (log.isDebugEnabled()) @@ -438,8 +548,6 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter { finally { if (depEnabled) cctx.deploy().ignoreOwnership(false); - - lock.unlock(); } } @@ -1527,9 +1635,18 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter { if (log.isDebugEnabled()) log.debug("Received cache ordered message [nodeId=" + nodeId + ", msg=" + msg + ']'); - final GridCacheMessage cacheMsg = (GridCacheMessage)msg; + Lock lock = rw.readLock(); - onMessage0(nodeId, cacheMsg, c); + lock.lock(); + + try { + GridCacheMessage cacheMsg = (GridCacheMessage)msg; + + onMessage0(nodeId, cacheMsg, c); + } + finally { + lock.unlock(); + } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/86065d20/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 ba5faf8..fea11e6 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 @@ -2083,25 +2083,43 @@ public class GridCacheProcessor extends GridProcessorAdapter { /** * @param cachesToClose Caches to close. + * @return Closed caches' IDs. */ - public Set<Integer> closeCaches(Set<String> cachesToClose) { + Set<Integer> closeCaches(Set<String> cachesToClose) { Set<Integer> ids = null; - for (String cacheName : cachesToClose) { - GridCacheContext ctx = blockGateway(cacheName, false); + boolean locked = false; - if (ctx == null) - continue; + try { + for (String cacheName : cachesToClose) { + GridCacheContext ctx = blockGateway(cacheName, false); - if (ids == null) - ids = U.newHashSet(cachesToClose.size()); + if (ctx == null) + continue; - ids.add(ctx.cacheId()); + if (ids == null) + ids = U.newHashSet(cachesToClose.size()); - closeCache(cacheName, false); - } + ids.add(ctx.cacheId()); + + if (!ctx.affinityNode() && !locked) { + sharedCtx.io().writeLock(); + + locked = true; + } - return ids; + if (!ctx.affinityNode() && ctx.transactional()) + sharedCtx.tm().rollbackTransactionsForCache(ctx.cacheId()); + + closeCache(cacheName, false); + } + + return ids; + } + finally { + if (locked) + sharedCtx.io().writeUnlock(); + } } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/86065d20/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareRequest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareRequest.java index c7c4280..631fe10 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareRequest.java @@ -19,10 +19,12 @@ package org.apache.ignite.internal.processors.cache.distributed.dht; import java.io.Externalizable; import java.nio.ByteBuffer; +import java.util.ArrayList; import java.util.BitSet; import java.util.Collection; import java.util.Collections; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.UUID; import org.apache.ignite.IgniteCheckedException; @@ -97,6 +99,10 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest { /** Preload keys. */ private BitSet preloadKeys; + /** */ + @GridDirectTransient + private List<IgniteTxKey> nearWritesCacheMissed; + /** * Empty constructor required for {@link Externalizable}. */ @@ -163,6 +169,13 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest { } /** + * @return Near cache writes for which cache was not found (possible if client near cache was closed). + */ + @Nullable public List<IgniteTxKey> nearWritesCacheMissed() { + return nearWritesCacheMissed; + } + + /** * @return Near transaction ID. */ public GridCacheVersion nearXidVersion() { @@ -319,13 +332,37 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest { while (keyIter.hasNext()) { IgniteTxKey key = keyIter.next(); - key.finishUnmarshal(ctx.cacheContext(key.cacheId()), ldr); + GridCacheContext<?, ?> cacheCtx = ctx.cacheContext(key.cacheId()); + + if (cacheCtx != null) { + key.finishUnmarshal(cacheCtx, ldr); - owned.put(key, valIter.next()); + owned.put(key, valIter.next()); + } } } - unmarshalTx(nearWrites, true, ctx, ldr); + if (nearWrites != null) { + for (Iterator<IgniteTxEntry> it = nearWrites.iterator(); it.hasNext();) { + IgniteTxEntry e = it.next(); + + GridCacheContext<?, ?> cacheCtx = ctx.cacheContext(e.cacheId()); + + if (cacheCtx == null) { + it.remove(); + + if (nearWritesCacheMissed == null) + nearWritesCacheMissed = new ArrayList<>(); + + nearWritesCacheMissed.add(e.txKey()); + } + else { + e.context(cacheCtx); + + e.unmarshal(ctx, true, ldr); + } + } + } } /** {@inheritDoc} */ http://git-wip-us.apache.org/repos/asf/ignite/blob/86065d20/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareResponse.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareResponse.java index 5dcb98c..0c2bf81 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareResponse.java @@ -124,7 +124,7 @@ public class GridDhtTxPrepareResponse extends GridDistributedTxPrepareResponse { /** * @return Evicted readers. */ - Collection<IgniteTxKey> nearEvicted() { + public Collection<IgniteTxKey> nearEvicted() { return nearEvicted; } @@ -194,7 +194,9 @@ public class GridDhtTxPrepareResponse extends GridDistributedTxPrepareResponse { for (IgniteTxKey key : nearEvicted) { GridCacheContext cctx = ctx.cacheContext(key.cacheId()); - key.prepareMarshal(cctx); + // Can be null if client near cache was removed, in this case assume do not need prepareMarshal. + if (cctx != null) + key.prepareMarshal(cctx); } } http://git-wip-us.apache.org/repos/asf/ignite/blob/86065d20/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 67e3ebc..3373bae 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 @@ -3240,9 +3240,17 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> { GridDhtAtomicUpdateResponse dhtRes = null; - if (isNearEnabled(cacheCfg)) { - List<KeyCacheObject> nearEvicted = - ((GridNearAtomicCache<K, V>)near()).processDhtAtomicUpdateRequest(nodeId, req, nearRes); + if (req.nearSize() > 0) { + List<KeyCacheObject> nearEvicted; + + if (isNearEnabled(cacheCfg)) + nearEvicted = ((GridNearAtomicCache<K, V>)near()).processDhtAtomicUpdateRequest(nodeId, req, nearRes); + else { + nearEvicted = new ArrayList<>(req.nearSize()); + + for (int i = 0; i < req.nearSize(); i++) + nearEvicted.add(req.nearKey(i)); + } if (nearEvicted != null) { dhtRes = new GridDhtAtomicUpdateResponse(ctx.cacheId(), http://git-wip-us.apache.org/repos/asf/ignite/blob/86065d20/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateResponse.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateResponse.java index 7b2547a..70bf6f5 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateResponse.java @@ -118,7 +118,7 @@ public class GridDhtAtomicUpdateResponse extends GridCacheIdMessage implements G /** * @param nearEvicted Evicted near cache keys. */ - void nearEvicted(List<KeyCacheObject> nearEvicted) { + public void nearEvicted(List<KeyCacheObject> nearEvicted) { this.nearEvicted = nearEvicted; } @@ -133,10 +133,13 @@ public class GridDhtAtomicUpdateResponse extends GridCacheIdMessage implements G GridCacheContext cctx = ctx.cacheContext(cacheId); - prepareMarshalCacheObjects(nearEvicted, cctx); + // Can be null if client near cache was removed, in this case assume do not need prepareMarshal. + if (cctx != null) { + prepareMarshalCacheObjects(nearEvicted, cctx); - if (errs != null) - errs.prepareMarshal(this, cctx); + if (errs != null) + errs.prepareMarshal(this, cctx); + } } /** {@inheritDoc} */ http://git-wip-us.apache.org/repos/asf/ignite/blob/86065d20/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheEntry.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheEntry.java index b17d0b5..c813afa 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheEntry.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheEntry.java @@ -292,11 +292,6 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry { @Override protected void recordNodeId(UUID primaryNodeId, AffinityTopologyVersion topVer) { assert Thread.holdsLock(this); - assert topVer.compareTo(cctx.affinity().affinityTopologyVersion()) <= 0 : "Affinity not ready [" + - "topVer=" + topVer + - ", readyVer=" + cctx.affinity().affinityTopologyVersion() + - ", cache=" + cctx.name() + ']'; - primaryNode(primaryNodeId, topVer); } http://git-wip-us.apache.org/repos/asf/ignite/blob/86065d20/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java index 527688e..71c6b65 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java @@ -327,6 +327,13 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message { } /** + * @param ctx Cache context for this tx entry. + */ + public void context(GridCacheContext<?, ?> ctx) { + this.ctx = ctx; + } + + /** * @return Flag indicating if this entry is affinity mapped to the same node. */ public boolean locallyMapped() { http://git-wip-us.apache.org/repos/asf/ignite/blob/86065d20/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java index 35ee011..b958a27 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java @@ -949,6 +949,17 @@ public class IgniteTxHandler { if (nearTx != null) res.nearEvicted(nearTx.evicted()); + List<IgniteTxKey> writesCacheMissed = req.nearWritesCacheMissed(); + + if (writesCacheMissed != null) { + Collection<IgniteTxKey> evicted0 = res.nearEvicted(); + + if (evicted0 != null) + writesCacheMissed.addAll(evicted0); + + res.nearEvicted(writesCacheMissed); + } + if (dhtTx != null) req.txState(dhtTx.txState()); else if (nearTx != null) @@ -1595,7 +1606,7 @@ public class IgniteTxHandler { * @return Remote transaction. * @throws IgniteCheckedException If failed. */ - @Nullable public GridNearTxRemote startNearRemoteTx(ClassLoader ldr, UUID nodeId, + @Nullable private GridNearTxRemote startNearRemoteTx(ClassLoader ldr, UUID nodeId, GridDhtTxPrepareRequest req) throws IgniteCheckedException { if (!F.isEmpty(req.nearWrites())) { http://git-wip-us.apache.org/repos/asf/ignite/blob/86065d20/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java index db0395f..0877305 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java @@ -276,6 +276,33 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter { cctx.gridIO().addMessageListener(TOPIC_TX, new DeadlockDetectionListener()); } + /** + * @param cacheId Cache ID. + */ + public void rollbackTransactionsForCache(int cacheId) { + rollbackTransactionsForCache(cacheId, nearIdMap); + + rollbackTransactionsForCache(cacheId, threadMap); + } + + /** + * @param cacheId Cache ID. + * @param txMap Transactions map. + */ + private void rollbackTransactionsForCache(int cacheId, ConcurrentMap<?, IgniteInternalTx> txMap) { + for (Map.Entry<?, IgniteInternalTx> e : txMap.entrySet()) { + IgniteInternalTx tx = e.getValue(); + + for (IgniteTxEntry entry : tx.allEntries()) { + if (entry.cacheId() == cacheId) { + rollbackTx(tx); + + break; + } + } + } + } + /** {@inheritDoc} */ @Override public void onDisconnected(IgniteFuture reconnectFut) { txFinishSync.onDisconnected(reconnectFut); http://git-wip-us.apache.org/repos/asf/ignite/blob/86065d20/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteDynamicClientCacheStartSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteDynamicClientCacheStartSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteDynamicClientCacheStartSelfTest.java index 57d128b..974feb5 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteDynamicClientCacheStartSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteDynamicClientCacheStartSelfTest.java @@ -373,6 +373,55 @@ public class IgniteDynamicClientCacheStartSelfTest extends GridCommonAbstractTes } /** + * @throws Exception If failed. + */ + @SuppressWarnings("unchecked") + public void testStartNewAndClientCaches() throws Exception { + final int SRVS = 4; + + Ignite srv = startGrids(SRVS); + + srv.createCaches(cacheConfigurations(null, CacheAtomicityMode.ATOMIC)); + + ccfg = null; + + client = true; + + Ignite client = startGrid(SRVS); + + List<CacheConfiguration> cfgs = new ArrayList<>(); + + cfgs.addAll(cacheConfigurations(null, CacheAtomicityMode.ATOMIC)); + cfgs.addAll(cacheConfigurations(null, CacheAtomicityMode.TRANSACTIONAL)); + + assertEquals(6, cfgs.size()); + + Collection<IgniteCache> caches = client.getOrCreateCaches(cfgs); + + assertEquals(cfgs.size(), caches.size()); + + for (CacheConfiguration cfg : cfgs) + checkCache(client, cfg.getName(), false, false); + + Map<Integer, Integer> map = new HashMap<>(); + + for (int i = 0; i < 100; i++) + map.put(i, i); + + for (IgniteCache<Object, Object> cache : caches) { + cache.putAll(map); + + checkCacheData(map, cache.getName()); + } + + for (IgniteCache cache : caches) { + cache.close(); + + checkNoCache(client, cache.getName()); + } + } + + /** * @param grp Group name. * @param atomicityMode Atomicity mode. * @return Cache configurations. http://git-wip-us.apache.org/repos/asf/ignite/blob/86065d20/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteNearClientCacheCloseTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteNearClientCacheCloseTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteNearClientCacheCloseTest.java new file mode 100644 index 0000000..8a9a46c --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteNearClientCacheCloseTest.java @@ -0,0 +1,264 @@ +/* + * 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.processors.cache; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.concurrent.Callable; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.Ignition; +import org.apache.ignite.cache.CacheAtomicityMode; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.configuration.NearCacheConfiguration; +import org.apache.ignite.internal.IgniteInternalFuture; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; +import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder; +import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; +import org.apache.ignite.testframework.GridTestUtils; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; + +import static org.apache.ignite.cache.CacheAtomicityMode.ATOMIC; +import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL; +import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC; + +/** + * + */ +public class IgniteNearClientCacheCloseTest extends GridCommonAbstractTest { + /** */ + private static final TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true); + + /** */ + private boolean client; + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName); + + ((TcpDiscoverySpi)cfg.getDiscoverySpi()).setIpFinder(ipFinder); + + cfg.setClientMode(client); + + return cfg; + } + + /** {@inheritDoc} */ + @Override protected void afterTest() throws Exception { + stopAllGrids(); + + super.afterTest(); + } + + /** + * @throws Exception If failed. + */ + public void testNearCacheCloseAtomic1() throws Exception { + nearCacheClose(1, false, ATOMIC); + + nearCacheClose(1, true, ATOMIC); + } + + /** + * @throws Exception If failed. + */ + public void testNearCacheCloseAtomic2() throws Exception { + nearCacheClose(4, false, ATOMIC); + + nearCacheClose(4, true, ATOMIC); + } + + /** + * @throws Exception If failed. + */ + public void testNearCacheCloseTx1() throws Exception { + nearCacheClose(1, false, TRANSACTIONAL); + + nearCacheClose(1, true, TRANSACTIONAL); + } + + /** + * @throws Exception If failed. + */ + public void testNearCacheCloseTx2() throws Exception { + nearCacheClose(4, false, TRANSACTIONAL); + + nearCacheClose(4, true, TRANSACTIONAL); + } + + /** + * @param srvs Number of server nodes. + * @param srvNearCache {@code True} to enable near cache on server nodes. + * @param atomicityMode Cache atomicity mode. + * @throws Exception If failed. + */ + private void nearCacheClose(int srvs, boolean srvNearCache, CacheAtomicityMode atomicityMode) throws Exception { + Ignite srv; + + if (Ignition.allGrids().isEmpty()) { + srv = startGrids(srvs); + + client = true; + + startGrid(srvs); + } + else + srv = grid(0); + + IgniteCache<Object, Object> srvCache = srv.createCache(cacheConfiguration(atomicityMode, srvNearCache)); + + List<Integer> keys = new ArrayList<>(); + + keys.add(primaryKey(srvCache)); + + if (srvs > 1) { + keys.add(backupKey(srvCache)); + keys.add(nearKey(srvCache)); + } + + for (Integer key : keys) { + IgniteCache<Object, Object> clientCache = + ignite(srvs).createNearCache(DEFAULT_CACHE_NAME, new NearCacheConfiguration<>()); + + clientCache.put(key, 1); + + clientCache.close(); + + srvCache.put(key, 2); + + assertEquals(2, srvCache.get(key)); + + srvCache.put(key, 3); + + assertEquals(3, srvCache.get(key)); + } + + srvCache.destroy(); + } + + /** + * @throws Exception If failed. + */ + public void testConcurrentUpdateAndNearCacheClose() throws Exception { + final int SRVS = 4; + + startGrids(SRVS); + + client = true; + + startGrid(SRVS); + + startGrid(SRVS + 1); + + concurrentUpdateAndNearCacheClose(ATOMIC, SRVS + 1); + + concurrentUpdateAndNearCacheClose(TRANSACTIONAL, SRVS + 1); + } + + /** + * @param atomicityMode Cache atomicity mode. + * @param nearClient Index of client node with near cache. + * @throws Exception If failed. + */ + private void concurrentUpdateAndNearCacheClose(CacheAtomicityMode atomicityMode, + final int nearClient) + throws Exception + { + final String cacheName = ignite(0).createCache(cacheConfiguration(atomicityMode, false)).getName(); + + for (int iter = 0; iter < 5; iter++) { + log.info("Iteration: " + iter); + + IgniteCache<Object, Object> nearCache = ignite(nearClient).createNearCache(cacheName, + new NearCacheConfiguration<>()); + + final int KEYS = 1000; + + for (int i = 0; i < KEYS; i++) + nearCache.put(i, i); + + final AtomicBoolean stop = new AtomicBoolean(); + + IgniteInternalFuture<?> updateFut = GridTestUtils.runMultiThreadedAsync(new Callable<Void>() { + @Override public Void call() throws Exception { + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + + while (!stop.get()) { + int node = rnd.nextInt(nearClient); + + IgniteCache<Object, Object> cache = ignite(node).cache(cacheName); + + if (rnd.nextBoolean()) { + Map<Integer, Integer> map = new TreeMap<>(); + + for (int i = 0; i < 10; i++) + map.put(rnd.nextInt(KEYS), i); + + cache.putAll(map); + } + else + cache.put(rnd.nextInt(KEYS), node); + } + + return null; + } + }, 10, "update"); + + try { + U.sleep(3000); + + nearCache.close(); + + stop.set(true); + + updateFut.get(); + } + finally { + stop.set(true); + } + } + + ignite(0).destroyCache(cacheName); + } + + /** + * @param atomicityMode Cache atomicity mode. + * @param nearCache {@code True} to enable near cache. + * @return Cache configuration. + */ + private CacheConfiguration cacheConfiguration(CacheAtomicityMode atomicityMode, boolean nearCache) { + CacheConfiguration ccfg = new CacheConfiguration(DEFAULT_CACHE_NAME); + + if (nearCache) + ccfg.setNearConfiguration(new NearCacheConfiguration()); + + ccfg.setWriteSynchronizationMode(FULL_SYNC); + ccfg.setAtomicityMode(atomicityMode); + ccfg.setBackups(1); + + return ccfg; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/86065d20/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteNearClientCacheTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteNearClientCacheTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteNearClientCacheTest.java deleted file mode 100644 index b4ceb49..0000000 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteNearClientCacheTest.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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.processors.cache; - -import org.apache.ignite.Ignite; -import org.apache.ignite.cluster.ClusterNode; -import org.apache.ignite.configuration.CacheConfiguration; -import org.apache.ignite.configuration.IgniteConfiguration; -import org.apache.ignite.configuration.NearCacheConfiguration; -import org.apache.ignite.internal.IgniteKernal; -import org.apache.ignite.internal.managers.discovery.GridDiscoveryManager; -import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; -import org.apache.ignite.internal.util.lang.GridAbsPredicate; -import org.apache.ignite.internal.util.typedef.internal.CU; -import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; -import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder; -import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; -import org.apache.ignite.testframework.GridTestUtils; -import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; - -/** - * - */ -public class IgniteNearClientCacheTest extends GridCommonAbstractTest { - /** */ - private static final TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true); - - /** */ - private boolean client; - - /** {@inheritDoc} */ - @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { - IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName); - - ((TcpDiscoverySpi)cfg.getDiscoverySpi()).setIpFinder(ipFinder); - - cfg.setClientMode(client); - - return cfg; - } - - public void testNearCache() throws Exception { - Ignite srv = startGrid(0); - - srv.createCache(new CacheConfiguration(DEFAULT_CACHE_NAME)); - - client = true; - - Ignite c = startGrid(1); - - c.createNearCache(DEFAULT_CACHE_NAME, new NearCacheConfiguration<>()); - - checkNearNode(srv, new AffinityTopologyVersion(2), true); - checkNearNode(c, new AffinityTopologyVersion(2), true); - - c.cache(DEFAULT_CACHE_NAME); - - checkNearNode(srv, new AffinityTopologyVersion(2), false); - checkNearNode(c, new AffinityTopologyVersion(2), false); - } - - private void checkNearNode(final Ignite node, final AffinityTopologyVersion topVer, final boolean exp) - throws Exception { - final GridDiscoveryManager mgr = ((IgniteKernal)node).context().discovery(); - - GridTestUtils.waitForCondition(new GridAbsPredicate() { - @Override public boolean apply() { - return exp == mgr.hasNearCache(CU.cacheId(DEFAULT_CACHE_NAME), topVer); - } - }, 5000); - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/86065d20/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java index 43f6b13..5851551 100644 --- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java +++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java @@ -43,6 +43,7 @@ import org.apache.ignite.internal.processors.cache.IgniteCacheIncrementTxTest; import org.apache.ignite.internal.processors.cache.IgniteCacheNoSyncForGetTest; import org.apache.ignite.internal.processors.cache.IgniteCachePartitionMapUpdateTest; import org.apache.ignite.internal.processors.cache.IgniteDynamicCacheAndNodeStop; +import org.apache.ignite.internal.processors.cache.IgniteNearClientCacheCloseTest; import org.apache.ignite.internal.processors.cache.IgniteOnePhaseCommitInvokeTest; import org.apache.ignite.internal.processors.cache.IgniteOnePhaseCommitNearReadersTest; import org.apache.ignite.internal.processors.cache.MemoryPolicyConfigValidationTest; @@ -272,6 +273,7 @@ public class IgniteCacheTestSuite2 extends TestSuite { suite.addTest(new TestSuite(IgniteCacheNoSyncForGetTest.class)); suite.addTest(new TestSuite(IgniteOnePhaseCommitNearReadersTest.class)); + suite.addTest(new TestSuite(IgniteNearClientCacheCloseTest.class)); return suite; }
