mirror of https://github.com/apache/cassandra
Wait for tracing events before returning response and query at same consistency level client side
patch by Stefania Alborghetti; reviewed by Paulo Motta for CASSANDRA-11465
This commit is contained in:
parent
04ef62cba2
commit
7bd65a129c
|
|
@ -1,4 +1,5 @@
|
|||
2.2.8
|
||||
* Wait for tracing events before returning response and query at same consistency level client side (CASSANDRA-11465)
|
||||
* cqlsh copyutil should get host metadata by connected address (CASSANDRA-11979)
|
||||
* Fixed cqlshlib.test.remove_test_db (CASSANDRA-12214)
|
||||
* Synchronize ThriftServer::stop() (CASSANDRA-12105)
|
||||
|
|
|
|||
|
|
@ -1211,7 +1211,7 @@ class Shell(cmd.Cmd):
|
|||
|
||||
if self.tracing_enabled:
|
||||
try:
|
||||
for trace in future.get_all_query_traces(self.max_trace_wait):
|
||||
for trace in future.get_all_query_traces(max_wait_per=self.max_trace_wait, query_cl=self.consistency_level):
|
||||
print_trace(self, trace)
|
||||
except TraceUnavailable:
|
||||
msg = "Statement trace did not complete within %d seconds; trace data may be incomplete." % (self.session.max_trace_wait,)
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.apache.cassandra.net.MessagingService;
|
||||
import org.apache.cassandra.tracing.TraceState;
|
||||
import org.apache.cassandra.utils.FBUtilities;
|
||||
|
||||
import static org.apache.cassandra.config.DatabaseDescriptor.*;
|
||||
|
|
@ -112,9 +111,19 @@ public class StageManager
|
|||
}
|
||||
}
|
||||
|
||||
public final static Runnable NO_OP_TASK = new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A TPE that disallows submit so that we don't need to worry about unwrapping exceptions on the
|
||||
* tracing stage. See CASSANDRA-1123 for background.
|
||||
* tracing stage. See CASSANDRA-1123 for background. We allow submitting NO_OP tasks, to allow
|
||||
* a final wait on pending trace events since typically the tracing executor is single-threaded, see
|
||||
* CASSANDRA-11465.
|
||||
*/
|
||||
private static class ExecuteOnlyExecutor extends ThreadPoolExecutor implements LocalAwareExecutorService
|
||||
{
|
||||
|
|
@ -137,6 +146,11 @@ public class StageManager
|
|||
@Override
|
||||
public Future<?> submit(Runnable task)
|
||||
{
|
||||
if (task.equals(NO_OP_TASK))
|
||||
{
|
||||
assert getMaximumPoolSize() == 1 : "Cannot wait for pending tasks if running more than 1 thread";
|
||||
return super.submit(task);
|
||||
}
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ import java.util.concurrent.TimeUnit;
|
|||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.google.common.base.Stopwatch;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.helpers.MessageFormatter;
|
||||
|
||||
import org.apache.cassandra.concurrent.Stage;
|
||||
|
|
@ -36,6 +38,7 @@ import org.apache.cassandra.db.Mutation;
|
|||
import org.apache.cassandra.exceptions.OverloadedException;
|
||||
import org.apache.cassandra.service.StorageProxy;
|
||||
import org.apache.cassandra.utils.ByteBufferUtil;
|
||||
import org.apache.cassandra.utils.JVMStabilityInspector;
|
||||
import org.apache.cassandra.utils.WrappedRunnable;
|
||||
import org.apache.cassandra.utils.progress.ProgressEvent;
|
||||
import org.apache.cassandra.utils.progress.ProgressEventNotifier;
|
||||
|
|
@ -47,6 +50,10 @@ import org.apache.cassandra.utils.progress.ProgressListener;
|
|||
*/
|
||||
public class TraceState implements ProgressEventNotifier
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(TraceState.class);
|
||||
private static final int WAIT_FOR_PENDING_EVENTS_TIMEOUT_SECS =
|
||||
Integer.valueOf(System.getProperty("cassandra.wait_for_tracing_events_timeout_secs", "1"));
|
||||
|
||||
public final UUID sessionId;
|
||||
public final InetAddress coordinator;
|
||||
public final Stopwatch watch;
|
||||
|
|
@ -119,6 +126,8 @@ public class TraceState implements ProgressEventNotifier
|
|||
|
||||
public synchronized void stop()
|
||||
{
|
||||
waitForPendingEvents();
|
||||
|
||||
status = Status.STOPPED;
|
||||
notifyAll();
|
||||
}
|
||||
|
|
@ -181,6 +190,8 @@ public class TraceState implements ProgressEventNotifier
|
|||
final int elapsed = elapsed();
|
||||
|
||||
executeMutation(TraceKeyspace.makeEventMutation(sessionIdBytes, message, elapsed, threadName, ttl));
|
||||
if (logger.isTraceEnabled())
|
||||
logger.trace("Adding <{}> to trace events", message);
|
||||
|
||||
for (ProgressListener listener : listeners)
|
||||
{
|
||||
|
|
@ -194,7 +205,7 @@ public class TraceState implements ProgressEventNotifier
|
|||
{
|
||||
protected void runMayThrow() throws Exception
|
||||
{
|
||||
mutateWithCatch(mutation);
|
||||
mutateWithCatch(mutation);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -228,6 +239,33 @@ public class TraceState implements ProgressEventNotifier
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Post a no-op event to the TRACING stage, so that we can be sure that any previous mutations
|
||||
* have at least been applied to one replica. This works because the tracking executor only
|
||||
* has one thread in its pool, see {@link StageManager#tracingExecutor()}.
|
||||
*/
|
||||
protected void waitForPendingEvents()
|
||||
{
|
||||
if (WAIT_FOR_PENDING_EVENTS_TIMEOUT_SECS <= 0)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
if (logger.isTraceEnabled())
|
||||
logger.trace("Waiting for up to {} seconds for trace events to complete",
|
||||
+WAIT_FOR_PENDING_EVENTS_TIMEOUT_SECS);
|
||||
|
||||
StageManager.getStage(Stage.TRACING).submit(StageManager.NO_OP_TASK)
|
||||
.get(WAIT_FOR_PENDING_EVENTS_TIMEOUT_SECS, TimeUnit.SECONDS);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
JVMStabilityInspector.inspectThrowable(t);
|
||||
logger.debug("Failed to wait for tracing events to complete: {}", t);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean acquireReference()
|
||||
{
|
||||
while (true)
|
||||
|
|
@ -242,6 +280,7 @@ public class TraceState implements ProgressEventNotifier
|
|||
|
||||
public int releaseReference()
|
||||
{
|
||||
waitForPendingEvents();
|
||||
return references.decrementAndGet();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue