use of com.datastax.oss.driver.internal.core.channel.DriverChannel in project java-driver by datastax.
the class ControlConnectionTest method should_handle_channel_failure_if_closed_during_reconnection.
@Test
public void should_handle_channel_failure_if_closed_during_reconnection() {
// Given
when(reconnectionSchedule.nextDelay()).thenReturn(Duration.ofNanos(1));
DriverChannel channel1 = newMockDriverChannel(1);
DriverChannel channel2 = newMockDriverChannel(2);
CompletableFuture<DriverChannel> channel1Future = new CompletableFuture<>();
MockChannelFactoryHelper factoryHelper = MockChannelFactoryHelper.builder(channelFactory).success(node1, channel1).pending(node1, channel1Future).success(node2, channel2).build();
CompletionStage<Void> initFuture = controlConnection.init(false, false, false);
factoryHelper.waitForCall(node1);
assertThatStage(initFuture).isSuccess(v -> assertThat(controlConnection.channel()).isEqualTo(channel1));
verify(eventBus, VERIFY_TIMEOUT).fire(ChannelEvent.channelOpened(node1));
// the channel fails and a reconnection is scheduled
channel1.close();
verify(eventBus, VERIFY_TIMEOUT).fire(ChannelEvent.channelClosed(node1));
verify(reconnectionSchedule, VERIFY_TIMEOUT).nextDelay();
// channel1 starts initializing (but the future is not completed yet)
factoryHelper.waitForCall(node1);
// When
// the control connection gets closed before channel1 initialization fails
CompletionStage<Void> closeFuture = controlConnection.forceCloseAsync();
assertThatStage(closeFuture).isSuccess();
channel1Future.completeExceptionally(new Exception("mock failure"));
// Then
// should never try channel2 because the reconnection has detected that it can stop after the
// first failure
factoryHelper.verifyNoMoreCalls();
}
use of com.datastax.oss.driver.internal.core.channel.DriverChannel in project java-driver by datastax.
the class ControlConnectionTest method should_reconnect_if_node_became_ignored_during_reconnection_attempt.
@Test
public void should_reconnect_if_node_became_ignored_during_reconnection_attempt() {
// Given
when(reconnectionSchedule.nextDelay()).thenReturn(Duration.ofNanos(1));
DriverChannel channel1 = newMockDriverChannel(1);
DriverChannel channel2 = newMockDriverChannel(2);
CompletableFuture<DriverChannel> channel2Future = new CompletableFuture<>();
DriverChannel channel3 = newMockDriverChannel(3);
MockChannelFactoryHelper factoryHelper = MockChannelFactoryHelper.builder(channelFactory).success(node1, channel1).pending(node2, channel2Future).success(node1, channel3).build();
CompletionStage<Void> initFuture = controlConnection.init(false, false, false);
factoryHelper.waitForCall(node1);
assertThatStage(initFuture).isSuccess(v -> assertThat(controlConnection.channel()).isEqualTo(channel1));
verify(eventBus, VERIFY_TIMEOUT).fire(ChannelEvent.channelOpened(node1));
mockQueryPlan(node2, node1);
// channel1 goes down, triggering a reconnection
channel1.close();
verify(eventBus, VERIFY_TIMEOUT).fire(ChannelEvent.channelClosed(node1));
verify(reconnectionSchedule, VERIFY_TIMEOUT).nextDelay();
// the reconnection to node2 is in progress
factoryHelper.waitForCall(node2);
// When
// node2 becomes ignored
eventBus.fire(new DistanceEvent(NodeDistance.IGNORED, node2));
// the reconnection to node2 completes
channel2Future.complete(channel2);
// Then
// The channel should get closed and we should try the next node
verify(channel2, VERIFY_TIMEOUT).forceClose();
factoryHelper.waitForCall(node1);
}
use of com.datastax.oss.driver.internal.core.channel.DriverChannel in project java-driver by datastax.
the class DefaultTopologyMonitor method refreshNodeList.
@Override
public CompletionStage<Iterable<NodeInfo>> refreshNodeList() {
if (closeFuture.isDone()) {
return CompletableFutures.failedFuture(new IllegalStateException("closed"));
}
LOG.debug("[{}] Refreshing node list", logPrefix);
DriverChannel channel = controlConnection.channel();
EndPoint localEndPoint = channel.getEndPoint();
savePort(channel);
CompletionStage<AdminResult> localQuery = query(channel, "SELECT * FROM system.local");
CompletionStage<AdminResult> peersV2Query = query(channel, "SELECT * FROM system.peers_v2");
CompletableFuture<AdminResult> peersQuery = new CompletableFuture<>();
peersV2Query.whenComplete((r, t) -> {
if (t != null) {
// If system.peers_v2 does not exist, downgrade to system.peers
if (t instanceof UnexpectedResponseException && ((UnexpectedResponseException) t).message instanceof Error) {
Error error = (Error) ((UnexpectedResponseException) t).message;
if (error.code == ProtocolConstants.ErrorCode.INVALID || // 6.0.2 with search enabled)
(error.code == ProtocolConstants.ErrorCode.SERVER_ERROR && error.message.contains("Unknown keyspace/cf pair (system.peers_v2)"))) {
// We should not attempt this query in the future.
this.isSchemaV2 = false;
CompletableFutures.completeFrom(query(channel, "SELECT * FROM system.peers"), peersQuery);
return;
}
}
peersQuery.completeExceptionally(t);
} else {
peersQuery.complete(r);
}
});
return localQuery.thenCombine(peersQuery, (controlNodeResult, peersResult) -> {
List<NodeInfo> nodeInfos = new ArrayList<>();
AdminRow localRow = controlNodeResult.iterator().next();
InetSocketAddress localBroadcastRpcAddress = getBroadcastRpcAddress(localRow, localEndPoint);
nodeInfos.add(nodeInfoBuilder(localRow, localBroadcastRpcAddress, localEndPoint).build());
for (AdminRow peerRow : peersResult) {
if (isPeerValid(peerRow)) {
InetSocketAddress peerBroadcastRpcAddress = getBroadcastRpcAddress(peerRow, localEndPoint);
if (peerBroadcastRpcAddress != null) {
NodeInfo nodeInfo = nodeInfoBuilder(peerRow, peerBroadcastRpcAddress, localEndPoint).build();
nodeInfos.add(nodeInfo);
}
}
}
return nodeInfos;
});
}
use of com.datastax.oss.driver.internal.core.channel.DriverChannel in project java-driver by datastax.
the class CqlPrepareHandler method sendRequest.
private void sendRequest(PrepareRequest request, Node node, int retryCount) {
if (result.isDone()) {
return;
}
DriverChannel channel = null;
if (node == null || (channel = session.getChannel(node, logPrefix)) == null) {
while (!result.isDone() && (node = queryPlan.poll()) != null) {
channel = session.getChannel(node, logPrefix);
if (channel != null) {
break;
} else {
recordError(node, new NodeUnavailableException(node));
}
}
}
if (channel == null) {
setFinalError(AllNodesFailedException.fromErrors(this.errors));
} else {
InitialPrepareCallback initialPrepareCallback = new InitialPrepareCallback(request, node, channel, retryCount);
Prepare message = toPrepareMessage(request);
channel.write(message, false, request.getCustomPayload(), initialPrepareCallback).addListener(initialPrepareCallback);
}
}
use of com.datastax.oss.driver.internal.core.channel.DriverChannel in project java-driver by datastax.
the class CqlRequestHandler method sendRequest.
/**
* Sends the request to the next available node.
*
* @param statement The statement to execute.
* @param retriedNode if not null, it will be attempted first before the rest of the query plan.
* @param queryPlan the list of nodes to try (shared with all other executions)
* @param currentExecutionIndex 0 for the initial execution, 1 for the first speculative one, etc.
* @param retryCount the number of times that the retry policy was invoked for this execution
* already (note that some internal retries don't go through the policy, and therefore don't
* increment this counter)
* @param scheduleNextExecution whether to schedule the next speculative execution
*/
private void sendRequest(Statement<?> statement, Node retriedNode, Queue<Node> queryPlan, int currentExecutionIndex, int retryCount, boolean scheduleNextExecution) {
if (result.isDone()) {
return;
}
Node node = retriedNode;
DriverChannel channel = null;
if (node == null || (channel = session.getChannel(node, logPrefix)) == null) {
while (!result.isDone() && (node = queryPlan.poll()) != null) {
channel = session.getChannel(node, logPrefix);
if (channel != null) {
break;
} else {
recordError(node, new NodeUnavailableException(node));
}
}
}
if (channel == null) {
// We've reached the end of the query plan without finding any node to write to
if (!result.isDone() && activeExecutionsCount.decrementAndGet() == 0) {
// We're the last execution so fail the result
setFinalError(statement, AllNodesFailedException.fromErrors(this.errors), null, -1);
}
} else {
NodeResponseCallback nodeResponseCallback = new NodeResponseCallback(statement, node, queryPlan, channel, currentExecutionIndex, retryCount, scheduleNextExecution, logPrefix);
DriverExecutionProfile executionProfile = Conversions.resolveExecutionProfile(statement, context);
Message message = Conversions.toMessage(statement, executionProfile, context);
channel.write(message, statement.isTracing(), statement.getCustomPayload(), nodeResponseCallback).addListener(nodeResponseCallback);
}
}
Aggregations