Fix tracing of concurrent range slices Patch by Tyler Hobbs; review by Aleksey Yeschenko for CASSANDRA-7626
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/948ae016 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/948ae016 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/948ae016 Branch: refs/heads/trunk Commit: 948ae016f4bf17c01e7b3320d7095c0ed9347840 Parents: 2107e30 Author: Tyler Hobbs <ty...@datastax.com> Authored: Wed Jul 30 15:58:26 2014 -0500 Committer: Tyler Hobbs <ty...@datastax.com> Committed: Wed Jul 30 15:58:26 2014 -0500 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../cassandra/net/OutboundTcpConnection.java | 2 +- .../apache/cassandra/tracing/TraceState.java | 22 ++++++++++++++++++++ .../org/apache/cassandra/tracing/Tracing.java | 7 ++++--- 4 files changed, 28 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/948ae016/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index b8990d9..d74db1a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -18,6 +18,7 @@ * Don't swap max/min col names when mutating sstable metadata (CASSANDRA-7596) * (cqlsh) Correctly handle paged result sets (CASSANDRA-7625) * (cqlsh) Improve waiting for a trace to complete (CASSANDRA-7626) + * Fix tracing of concurrent range slices and 2ary index queries (CASSANDRA-7626) Merged from 2.0: * Fix ReversedType(DateType) mapping to native protocol (CASSANDRA-7576) * Always merge ranges owned by a single node (CASSANDRA-6930) http://git-wip-us.apache.org/repos/asf/cassandra/blob/948ae016/src/java/org/apache/cassandra/net/OutboundTcpConnection.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/net/OutboundTcpConnection.java b/src/java/org/apache/cassandra/net/OutboundTcpConnection.java index 1781a5d..a0db992 100644 --- a/src/java/org/apache/cassandra/net/OutboundTcpConnection.java +++ b/src/java/org/apache/cassandra/net/OutboundTcpConnection.java @@ -219,7 +219,7 @@ public class OutboundTcpConnection extends Thread { state.trace(message); if (qm.message.verb == MessagingService.Verb.REQUEST_RESPONSE) - Tracing.instance.stopNonLocal(state); + Tracing.instance.doneWithNonLocalSession(state); } } http://git-wip-us.apache.org/repos/asf/cassandra/blob/948ae016/src/java/org/apache/cassandra/tracing/TraceState.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tracing/TraceState.java b/src/java/org/apache/cassandra/tracing/TraceState.java index 62eb891..cfff295 100644 --- a/src/java/org/apache/cassandra/tracing/TraceState.java +++ b/src/java/org/apache/cassandra/tracing/TraceState.java @@ -21,6 +21,7 @@ import java.net.InetAddress; import java.nio.ByteBuffer; import java.util.UUID; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import com.google.common.base.Stopwatch; import org.slf4j.helpers.MessageFormatter; @@ -47,6 +48,10 @@ public class TraceState public final Stopwatch watch; public final ByteBuffer sessionIdBytes; + // Multiple requests can use the same TraceState at a time, so we need to reference count. + // See CASSANDRA-7626 for more details. + private final AtomicInteger references = new AtomicInteger(1); + public TraceState(InetAddress coordinator, UUID sessionId) { assert coordinator != null; @@ -104,4 +109,21 @@ public class TraceState } }); } + + public boolean acquireReference() + { + while (true) + { + int n = references.get(); + if (n <= 0) + return false; + if (references.compareAndSet(n, n + 1)) + return true; + } + } + + public int releaseReference() + { + return references.decrementAndGet(); + } } http://git-wip-us.apache.org/repos/asf/cassandra/blob/948ae016/src/java/org/apache/cassandra/tracing/Tracing.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tracing/Tracing.java b/src/java/org/apache/cassandra/tracing/Tracing.java index f650d16..e377c6e 100644 --- a/src/java/org/apache/cassandra/tracing/Tracing.java +++ b/src/java/org/apache/cassandra/tracing/Tracing.java @@ -140,9 +140,10 @@ public class Tracing return sessionId; } - public void stopNonLocal(TraceState state) + public void doneWithNonLocalSession(TraceState state) { - sessions.remove(state.sessionId); + if (state.releaseReference() == 0) + sessions.remove(state.sessionId); } /** @@ -229,7 +230,7 @@ public class Tracing assert sessionBytes.length == 16; UUID sessionId = UUIDGen.getUUID(ByteBuffer.wrap(sessionBytes)); TraceState ts = sessions.get(sessionId); - if (ts != null) + if (ts != null && ts.acquireReference()) return ts; if (message.verb == MessagingService.Verb.REQUEST_RESPONSE)