use of com.datastax.oss.driver.internal.core.util.concurrent.CapturingTimer.CapturedTimeout in project java-driver by datastax.
the class CqlRequestHandlerSpeculativeExecutionTest method should_not_start_execution_if_result_complete.
@Test
@UseDataProvider("idempotentConfig")
public void should_not_start_execution_if_result_complete(boolean defaultIdempotence, Statement<?> statement) throws Exception {
RequestHandlerTestHarness.Builder harnessBuilder = RequestHandlerTestHarness.builder().withDefaultIdempotence(defaultIdempotence);
PoolBehavior node1Behavior = harnessBuilder.customBehavior(node1);
PoolBehavior node2Behavior = harnessBuilder.customBehavior(node2);
try (RequestHandlerTestHarness harness = harnessBuilder.build()) {
SpeculativeExecutionPolicy speculativeExecutionPolicy = harness.getContext().getSpeculativeExecutionPolicy(DriverExecutionProfile.DEFAULT_NAME);
long firstExecutionDelay = 100L;
when(speculativeExecutionPolicy.nextExecution(any(Node.class), eq(null), eq(statement), eq(1))).thenReturn(firstExecutionDelay);
CqlRequestHandler requestHandler = new CqlRequestHandler(statement, harness.getSession(), harness.getContext(), "test");
CompletionStage<AsyncResultSet> resultSetFuture = requestHandler.handle();
node1Behavior.verifyWrite();
node1Behavior.setWriteSuccess();
// Discard the timeout task
harness.nextScheduledTimeout();
// Check that the first execution was scheduled but don't run it yet
CapturedTimeout speculativeExecution1 = harness.nextScheduledTimeout();
assertThat(speculativeExecution1.getDelay(TimeUnit.MILLISECONDS)).isEqualTo(firstExecutionDelay);
// Complete the request from the initial execution
node1Behavior.setResponseSuccess(defaultFrameOf(singleRow()));
assertThatStage(resultSetFuture).isSuccess();
// Pending speculative executions should have been cancelled. However we don't check
// firstExecutionTask directly because the request handler's onResponse can sometimes be
// invoked before operationComplete (this is very unlikely in practice, but happens in our
// Travis CI build). When that happens, the speculative execution is not recorded yet when
// cancelScheduledTasks runs.
// So check the timeout future instead, since it's cancelled in the same method.
assertThat(requestHandler.scheduledTimeout.isCancelled()).isTrue();
// The fact that we missed the speculative execution is not a problem; even if it starts, it
// will eventually find out that the result is already complete and cancel itself:
speculativeExecution1.task().run(speculativeExecution1);
node2Behavior.verifyNoWrite();
verify(nodeMetricUpdater1).isEnabled(DefaultNodeMetric.CQL_MESSAGES, DriverExecutionProfile.DEFAULT_NAME);
verify(nodeMetricUpdater1).updateTimer(eq(DefaultNodeMetric.CQL_MESSAGES), eq(DriverExecutionProfile.DEFAULT_NAME), anyLong(), eq(TimeUnit.NANOSECONDS));
verifyNoMoreInteractions(nodeMetricUpdater1);
}
}
use of com.datastax.oss.driver.internal.core.util.concurrent.CapturingTimer.CapturedTimeout in project java-driver by datastax.
the class CqlRequestHandlerSpeculativeExecutionTest method should_stop_retrying_other_executions_if_result_complete.
@Test
@UseDataProvider("idempotentConfig")
public void should_stop_retrying_other_executions_if_result_complete(boolean defaultIdempotence, Statement<?> statement) throws Exception {
RequestHandlerTestHarness.Builder harnessBuilder = RequestHandlerTestHarness.builder().withDefaultIdempotence(defaultIdempotence);
PoolBehavior node1Behavior = harnessBuilder.customBehavior(node1);
PoolBehavior node2Behavior = harnessBuilder.customBehavior(node2);
PoolBehavior node3Behavior = harnessBuilder.customBehavior(node3);
try (RequestHandlerTestHarness harness = harnessBuilder.build()) {
SpeculativeExecutionPolicy speculativeExecutionPolicy = harness.getContext().getSpeculativeExecutionPolicy(DriverExecutionProfile.DEFAULT_NAME);
long firstExecutionDelay = 100L;
when(speculativeExecutionPolicy.nextExecution(any(Node.class), eq(null), eq(statement), eq(1))).thenReturn(firstExecutionDelay);
CompletionStage<AsyncResultSet> resultSetFuture = new CqlRequestHandler(statement, harness.getSession(), harness.getContext(), "test").handle();
node1Behavior.verifyWrite();
node1Behavior.setWriteSuccess();
// Discard the timeout task
harness.nextScheduledTimeout();
// next scheduled timeout should be the first speculative execution. Get it and run it.
CapturedTimeout speculativeExecution1 = harness.nextScheduledTimeout();
assertThat(speculativeExecution1.getDelay(TimeUnit.MILLISECONDS)).isEqualTo(firstExecutionDelay);
speculativeExecution1.task().run(speculativeExecution1);
node2Behavior.verifyWrite();
node2Behavior.setWriteSuccess();
// Complete the request from the initial execution
node1Behavior.setResponseSuccess(defaultFrameOf(singleRow()));
assertThatStage(resultSetFuture).isSuccess();
// node2 replies with a response that would trigger a RETRY_NEXT if the request was still
// running
node2Behavior.setResponseSuccess(defaultFrameOf(new Error(ProtocolConstants.ErrorCode.IS_BOOTSTRAPPING, "mock message")));
// The speculative execution should not move to node3 because it is stopped
node3Behavior.verifyNoWrite();
}
}
Aggregations