use of com.couchbase.client.core.endpoint.Endpoint in project couchbase-jvm-clients by couchbase.
the class PartitionSelectionStrategy method select.
@Override
public <R extends Request<? extends Response>> Endpoint select(final R request, final List<Endpoint> endpoints) {
int size = endpoints.size();
if (size == 0) {
return null;
}
short partition = ((KeyValueRequest<?>) request).partition();
Endpoint endpoint = size == 1 ? endpoints.get(0) : endpoints.get(partition % size);
if (endpoint != null && endpoint.state() == EndpointState.CONNECTED && endpoint.freeToWrite()) {
return endpoint;
}
return null;
}
use of com.couchbase.client.core.endpoint.Endpoint in project couchbase-jvm-clients by couchbase.
the class RoundRobinSelectionStrategy method select.
@Override
public <R extends Request<? extends Response>> Endpoint select(final R request, final List<Endpoint> endpoints) {
int endpointSize = endpoints.size();
// increments skip and prevents it to overflow to a negative value
skip.set(Math.max(0, skip.get() + 1));
int offset = skip.get() % endpointSize;
// attempt to find a CONNECTED endpoint at the offset, or try following ones
for (int i = offset; i < endpointSize; i++) {
Endpoint endpoint = endpoints.get(i);
if (endpoint.state() == EndpointState.CONNECTED && endpoint.freeToWrite()) {
return endpoint;
}
}
// wrap around and try from the beginning of the array
for (int i = 0; i < offset; i++) {
Endpoint endpoint = endpoints.get(i);
if (endpoint.state() == EndpointState.CONNECTED && endpoint.freeToWrite()) {
return endpoint;
}
}
// lastly, really no eligible endpoint was found, return null
return null;
}
use of com.couchbase.client.core.endpoint.Endpoint in project couchbase-jvm-clients by couchbase.
the class PooledService method disconnect.
@Override
public synchronized void disconnect() {
if (disconnected.compareAndSet(false, true)) {
serviceContext.environment().eventBus().publish(new ServiceDisconnectInitiatedEvent(serviceContext, endpoints.size() + reservedEndpoints.size()));
for (Endpoint endpoint : endpoints) {
endpoint.disconnect();
endpointStates.deregister(endpoint);
}
for (Endpoint endpoint : reservedEndpoints) {
endpoint.disconnect();
;
endpointStates.deregister(endpoint);
}
endpoints.clear();
reservedEndpoints.clear();
}
}
use of com.couchbase.client.core.endpoint.Endpoint in project couchbase-jvm-clients by couchbase.
the class PooledServiceTest method disconnectsAllEndpoints.
/**
* Make sure that when disconnect is called, all current endpoints are disconnected
* and the service is put into a disconnected state.
*/
@Test
void disconnectsAllEndpoints() {
int minEndpoints = 2;
Endpoint mock1 = mock(Endpoint.class);
when(mock1.state()).thenReturn(EndpointState.CONNECTED);
when(mock1.states()).thenReturn(DirectProcessor.create());
Endpoint mock2 = mock(Endpoint.class);
when(mock2.state()).thenReturn(EndpointState.CONNECTED);
when(mock2.states()).thenReturn(DirectProcessor.create());
final List<Endpoint> mocks = Arrays.asList(mock1, mock2);
final AtomicInteger invocation = new AtomicInteger();
MockedService service = new MockedService(new MockedServiceConfig(minEndpoints, 2), () -> mocks.get(invocation.getAndIncrement()));
service.connect();
assertEquals(minEndpoints, service.trackedEndpoints().size());
assertEquals(ServiceState.CONNECTED, service.state());
service.disconnect();
assertEquals(ServiceState.DISCONNECTED, service.state());
verify(mock1, times(1)).disconnect();
verify(mock2, times(1)).disconnect();
assertEquals(2, eventBus.publishedEvents().size());
ServiceDisconnectInitiatedEvent event = (ServiceDisconnectInitiatedEvent) eventBus.publishedEvents().get(1);
assertEquals(2, event.disconnectingEndpoints());
assertEquals("Starting to disconnect service with 2 underlying endpoints", event.description());
}
use of com.couchbase.client.core.endpoint.Endpoint in project couchbase-jvm-clients by couchbase.
the class PooledServiceTest method retriesRequestIfEndpointCannotConnect.
/**
* With direct dispatch in the pool it is possible that endpoint for which the socket is
* waiting for to be dispatched never goes into a connected state but rather into disconnected
* (and then subsequent reconnect). As soon as we observe a disconnect state we need to retry the
* op so that it has a chance to complete somewhere else.
*/
@Test
void retriesRequestIfEndpointCannotConnect() {
int minEndpoints = 0;
Endpoint mock1 = mock(Endpoint.class);
when(mock1.state()).thenReturn(EndpointState.DISCONNECTED);
DirectProcessor<EndpointState> states = DirectProcessor.create();
when(mock1.states()).thenReturn(states);
when(mock1.outstandingRequests()).thenReturn(0L);
final List<Endpoint> mocks = Collections.singletonList(mock1);
final AtomicInteger invocation = new AtomicInteger();
MockedService service = new MockedService(new MockedServiceConfig(minEndpoints, 2, Duration.ofMillis(500), false), () -> mocks.get(invocation.getAndIncrement()), new FirstEndpointSelectionStrategy());
service.connect();
assertTrue(service.trackedEndpoints().isEmpty());
NoopRequest request = new NoopRequest(Duration.ofSeconds(1), serviceContext, BestEffortRetryStrategy.INSTANCE, CollectionIdentifier.fromDefault("bucket"));
service.send(request);
// Simulate the connecting and connected
states.onNext(EndpointState.CONNECTING);
states.onNext(EndpointState.DISCONNECTED);
waitUntilCondition(() -> !service.trackedEndpoints.isEmpty());
assertEquals(1, service.trackedEndpoints().size());
waitUntilCondition(() -> request.context().retryAttempts() >= 1);
verify(mock1, never()).send(request);
}
Aggregations