use of com.couchbase.client.core.cnc.events.endpoint.UnexpectedEndpointDisconnectedEvent in project couchbase-jvm-clients by couchbase.
the class BaseEndpointIntegrationTest method mustReconnectWhenChannelCloses.
/**
* When the underlying channel closes, the endpoint must continue to reconnect until being instructed
* to stop with an explicit disconnect command.
*/
@Test
void mustReconnectWhenChannelCloses() {
LocalServerController localServerController = startLocalServer(eventLoopGroup);
ServiceContext serviceContext = new ServiceContext(new CoreContext(null, 1, env, authenticator()), "127.0.0.1", 1234, ServiceType.KV, Optional.empty());
BaseEndpoint endpoint = new BaseEndpoint("127.0.0.1", 1234, eventLoopGroup, serviceContext, CircuitBreakerConfig.enabled(false).build(), ServiceType.QUERY, false) {
@Override
protected PipelineInitializer pipelineInitializer() {
return (endpoint, pipeline) -> {
};
}
@Override
protected SocketAddress remoteAddress() {
return new LocalAddress("server");
}
};
List<EndpointState> transitions = Collections.synchronizedList(new ArrayList<>());
endpoint.states().subscribe(transitions::add);
assertEquals(0, localServerController.connectAttempts.get());
assertNull(localServerController.channel.get());
endpoint.connect();
waitUntilCondition(() -> endpoint.state() == EndpointState.CONNECTED);
waitUntilCondition(() -> localServerController.connectAttempts.get() == 1);
assertNotNull(localServerController.channel.get());
localServerController.channel.get().close().awaitUninterruptibly();
List<EndpointState> expectedTransitions = Arrays.asList(// initial state
EndpointState.DISCONNECTED, // initial connect attempt
EndpointState.CONNECTING, // properly connected the first time
EndpointState.CONNECTED, // disconnected when we kill the channel from the server side
EndpointState.DISCONNECTED, // endpoint should be reconnecting now
EndpointState.CONNECTING, // finally, we are able to reconnect completely
EndpointState.CONNECTED);
waitUntilCondition(() -> transitions.size() == expectedTransitions.size());
assertEquals(expectedTransitions, transitions);
waitUntilCondition(() -> localServerController.connectAttempts.get() >= 2);
endpoint.disconnect();
waitUntilCondition(() -> endpoint.state() == EndpointState.DISCONNECTED);
boolean hasDisconnectEvent = false;
for (Event event : eventBus.publishedEvents()) {
if (event instanceof UnexpectedEndpointDisconnectedEvent) {
hasDisconnectEvent = true;
break;
}
}
assertTrue(hasDisconnectEvent);
}
use of com.couchbase.client.core.cnc.events.endpoint.UnexpectedEndpointDisconnectedEvent in project couchbase-jvm-clients by couchbase.
the class BaseEndpoint method notifyChannelInactive.
/**
* This method is called from inside the channel to tell the endpoint hat it got inactive.
*
* <p>The endpoint needs to perform certain steps when the channel is inactive so that it quickly tries
* to reconnect, as long as it should (i.e. don't do it if already disconnected)</p>
*/
@Stability.Internal
public void notifyChannelInactive() {
int outstandingBeforeInactive = outstandingRequests.getAndSet(0);
if (disconnect.get()) {
// We don't need to do anything if we've been already instructed to disconnect.
return;
}
long connectedSince = System.nanoTime() - lastConnectedAt;
if (state() == EndpointState.CONNECTED) {
endpointContext.get().environment().eventBus().publish(new UnexpectedEndpointDisconnectedEvent(endpointContext.get(), outstandingBeforeInactive, connectedSince));
state.transition(EndpointState.DISCONNECTED);
connect();
}
}
Aggregations