You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by av...@apache.org on 2018/08/15 22:03:58 UTC
[11/19] ignite git commit: IGNITE-1905 Fixed assertion when
CacheLockImpl is contented - Fixes #4490.
IGNITE-1905 Fixed assertion when CacheLockImpl is contented - Fixes #4490.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/18356a87
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/18356a87
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/18356a87
Branch: refs/heads/ignite-9053
Commit: 18356a876c9ed633c74b855b66b70d777e92cbd6
Parents: 3e0f04e
Author: Vitaliy Biryukov <Bi...@gmail.com>
Authored: Wed Aug 15 17:16:17 2018 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Wed Aug 15 17:16:17 2018 +0300
----------------------------------------------------------------------
.../dht/GridDhtTransactionalCacheAdapter.java | 12 +--
.../colocated/GridDhtColocatedLockFuture.java | 76 +++++++++++++------
.../distributed/near/GridNearLockFuture.java | 80 ++++++++++++++------
.../testsuites/IgniteCacheTestSuite6.java | 2 +
4 files changed, 117 insertions(+), 53 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/18356a87/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
index 46d7579..30b066f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
@@ -44,7 +44,6 @@ import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedExceptio
import org.apache.ignite.internal.processors.cache.GridCacheLockTimeoutException;
import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate;
import org.apache.ignite.internal.processors.cache.GridCacheReturn;
-import org.apache.ignite.internal.processors.cache.GridCacheVersionedFuture;
import org.apache.ignite.internal.processors.cache.KeyCacheObject;
import org.apache.ignite.internal.processors.cache.distributed.GridDistributedCacheEntry;
import org.apache.ignite.internal.processors.cache.distributed.GridDistributedLockCancelledException;
@@ -77,7 +76,6 @@ import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.X;
import org.apache.ignite.internal.util.typedef.internal.CU;
import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.lang.IgniteInClosure;
import org.apache.ignite.thread.IgniteThread;
import org.apache.ignite.transactions.TransactionIsolation;
import org.jetbrains.annotations.Nullable;
@@ -1528,15 +1526,14 @@ public abstract class GridDhtTransactionalCacheAdapter<K, V> extends GridDhtCach
* @param readers Readers for this entry.
* @param dhtMap DHT map.
* @param nearMap Near map.
- * @throws IgniteCheckedException If failed.
*/
private void map(UUID nodeId,
AffinityTopologyVersion topVer,
GridCacheEntryEx cached,
Collection<UUID> readers,
Map<ClusterNode, List<KeyCacheObject>> dhtMap,
- Map<ClusterNode, List<KeyCacheObject>> nearMap)
- throws IgniteCheckedException {
+ Map<ClusterNode, List<KeyCacheObject>> nearMap
+ ) {
List<ClusterNode> dhtNodes = ctx.dht().topology().nodes(cached.partition(), topVer);
ClusterNode primary = dhtNodes.get(0);
@@ -1609,6 +1606,8 @@ public abstract class GridDhtTransactionalCacheAdapter<K, V> extends GridDhtCach
// Remove mapped versions.
GridCacheVersion dhtVer = unmap ? ctx.mvcc().unmapVersion(ver) : ver;
+ ctx.mvcc().addRemoved(ctx, ver);
+
Map<ClusterNode, List<KeyCacheObject>> dhtMap = new HashMap<>();
Map<ClusterNode, List<KeyCacheObject>> nearMap = new HashMap<>();
@@ -1690,9 +1689,6 @@ public abstract class GridDhtTransactionalCacheAdapter<K, V> extends GridDhtCach
if (log.isDebugEnabled())
log.debug("Received remove lock request for removed entry (will retry): " + entry);
}
- catch (IgniteCheckedException e) {
- U.error(log, "Failed to remove locks for keys: " + keys, e);
- }
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/18356a87/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java
index da0858f..a5ff2f3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java
@@ -134,7 +134,7 @@ public final class GridDhtColocatedLockFuture extends GridCacheCompoundIdentityF
/** Timeout object. */
@GridToStringExclude
- private LockTimeoutObject timeoutObj;
+ private volatile LockTimeoutObject timeoutObj;
/** Lock timeout. */
private final long timeout;
@@ -444,32 +444,59 @@ public final class GridDhtColocatedLockFuture extends GridCacheCompoundIdentityF
* @param nodeId Sender.
* @param res Result.
*/
+ @SuppressWarnings("SynchronizeOnNonFinalField")
void onResult(UUID nodeId, GridNearLockResponse res) {
- if (!isDone()) {
- MiniFuture mini = miniFuture(res.miniId());
-
- if (mini != null) {
- assert mini.node().id().equals(nodeId);
+ boolean done = isDone();
- mini.onResult(res);
+ if (!done) {
+ // onResult is always called after map() and timeoutObj is never reset to null, so this is
+ // a race-free null check.
+ if (timeoutObj == null) {
+ onResult0(nodeId, res);
return;
}
- // This warning can be triggered by deadlock detection code which clears pending futures.
- U.warn(msgLog, "Collocated lock fut, failed to find mini future [txId=" + lockVer +
- ", tx=" + (inTx() ? CU.txString(tx) : "N/A") +
- ", node=" + nodeId +
- ", res=" + res +
- ", fut=" + this + ']');
- }
- else {
- if (msgLog.isDebugEnabled()) {
- msgLog.debug("Collocated lock fut, response for finished future [txId=" + lockVer +
- ", inTx=" + inTx() +
- ", node=" + nodeId + ']');
+ synchronized (timeoutObj) {
+ if (!isDone()) {
+ if (onResult0(nodeId, res))
+ return;
+ }
+ else
+ done = true;
}
}
+
+ if (done && msgLog.isDebugEnabled()) {
+ msgLog.debug("Collocated lock fut, response for finished future [txId=" + lockVer +
+ ", inTx=" + inTx() +
+ ", node=" + nodeId + ']');
+ }
+ }
+
+ /**
+ * @param nodeId Sender.
+ * @param res Result.
+ */
+ private boolean onResult0(UUID nodeId, GridNearLockResponse res) {
+ MiniFuture mini = miniFuture(res.miniId());
+
+ if (mini != null) {
+ assert mini.node().id().equals(nodeId);
+
+ mini.onResult(res);
+
+ return true;
+ }
+
+ // This warning can be triggered by deadlock detection code which clears pending futures.
+ U.warn(msgLog, "Collocated lock fut, failed to find mini future [txId=" + lockVer +
+ ", tx=" + (inTx() ? CU.txString(tx) : "N/A") +
+ ", node=" + nodeId +
+ ", res=" + res +
+ ", fut=" + this + ']');
+
+ return false;
}
/**
@@ -1452,15 +1479,20 @@ public final class GridDhtColocatedLockFuture extends GridCacheCompoundIdentityF
U.warn(log, "Failed to detect deadlock.", e);
}
- onComplete(false, true);
+ synchronized (LockTimeoutObject.this) {
+ onComplete(false, true);
+ }
}
});
}
else
err = tx.timeoutException();
}
- else
- onComplete(false, true);
+ else {
+ synchronized (this) {
+ onComplete(false, true);
+ }
+ }
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/18356a87/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java
index 4b46bda..6cd4514 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java
@@ -129,7 +129,7 @@ public final class GridNearLockFuture extends GridCacheCompoundIdentityFuture<Bo
/** Timeout object. */
@GridToStringExclude
- private LockTimeoutObject timeoutObj;
+ private volatile LockTimeoutObject timeoutObj;
/** Lock timeout. */
private final long timeout;
@@ -481,37 +481,66 @@ public final class GridNearLockFuture extends GridCacheCompoundIdentityFuture<Bo
* @param nodeId Sender.
* @param res Result.
*/
+ @SuppressWarnings("SynchronizeOnNonFinalField")
void onResult(UUID nodeId, GridNearLockResponse res) {
- if (!isDone()) {
- if (log.isDebugEnabled())
- log.debug("Received lock response from node [nodeId=" + nodeId + ", res=" + res + ", fut=" + this + ']');
-
- MiniFuture mini = miniFuture(res.miniId());
-
- if (mini != null) {
- assert mini.node().id().equals(nodeId);
-
- if (log.isDebugEnabled())
- log.debug("Found mini future for response [mini=" + mini + ", res=" + res + ']');
+ boolean done = isDone();
- mini.onResult(res);
-
- if (log.isDebugEnabled())
- log.debug("Future after processed lock response [fut=" + this + ", mini=" + mini +
- ", res=" + res + ']');
+ if (!done) {
+ // onResult is always called after map() and timeoutObj is never reset to null, so this is
+ // a race-free null check.
+ if (timeoutObj == null) {
+ onResult0(nodeId, res);
return;
}
- U.warn(log, "Failed to find mini future for response (perhaps due to stale message) [res=" + res +
- ", fut=" + this + ']');
+ synchronized (timeoutObj) {
+ if (!isDone()) {
+ if (onResult0(nodeId, res))
+ return;
+ }
+ else
+ done = true;
+ }
}
- else if (log.isDebugEnabled())
+
+ if (done && log.isDebugEnabled())
log.debug("Ignoring lock response from node (future is done) [nodeId=" + nodeId + ", res=" + res +
", fut=" + this + ']');
}
/**
+ * @param nodeId Sender.
+ * @param res Result.
+ */
+ private boolean onResult0(UUID nodeId, GridNearLockResponse res) {
+ if (log.isDebugEnabled())
+ log.debug("Received lock response from node [nodeId=" + nodeId + ", res=" + res + ", fut=" + this + ']');
+
+ MiniFuture mini = miniFuture(res.miniId());
+
+ if (mini != null) {
+ assert mini.node().id().equals(nodeId);
+
+ if (log.isDebugEnabled())
+ log.debug("Found mini future for response [mini=" + mini + ", res=" + res + ']');
+
+ mini.onResult(res);
+
+ if (log.isDebugEnabled())
+ log.debug("Future after processed lock response [fut=" + this + ", mini=" + mini +
+ ", res=" + res + ']');
+
+ return true;
+ }
+
+ U.warn(log, "Failed to find mini future for response (perhaps due to stale message) [res=" + res +
+ ", fut=" + this + ']');
+
+ return false;
+ }
+
+ /**
* @return Keys for which locks requested from remote nodes but response isn't received.
*/
public synchronized Set<IgniteTxKey> requestedKeys() {
@@ -1496,15 +1525,20 @@ public final class GridNearLockFuture extends GridCacheCompoundIdentityFuture<Bo
U.warn(log, "Failed to detect deadlock.", e);
}
- onComplete(false, true);
+ synchronized (LockTimeoutObject.this) {
+ onComplete(false, true);
+ }
}
});
}
else
err = tx.timeoutException();
}
- else
- onComplete(false, true);
+ else {
+ synchronized (this) {
+ onComplete(false, true);
+ }
+ }
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/18356a87/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite6.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite6.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite6.java
index 6f3df0b..b52e339 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite6.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite6.java
@@ -109,6 +109,8 @@ public class IgniteCacheTestSuite6 extends TestSuite {
suite.addTestSuite(IgniteExchangeLatchManagerCoordinatorFailTest.class);
+ suite.addTestSuite(CacheTryLockMultithreadedTest.class);
+
//suite.addTestSuite(CacheClientsConcurrentStartTest.class);
//suite.addTestSuite(CacheTryLockMultithreadedTest.class);
//suite.addTestSuite(GridCacheRebalancingOrderingTest.class);