Search in sources :

Example 1 with Request

use of com.couchbase.client.core.msg.Request in project couchbase-jvm-clients by couchbase.

the class PooledService method connectReservedEndpoint.

/**
 * Connect the reserved endpoint and dispatch the request into it if possible.
 * <p>
 * Note that there are two synchronized sections in this method, because the subscription callback works on
 * a different thread.
 *
 * @param request the request that needs to bee dispatched.
 */
private synchronized <R extends Request<? extends Response>> void connectReservedEndpoint(final R request) {
    if (!disconnected.get()) {
        Endpoint endpoint = createEndpoint();
        endpointStates.register(endpoint, endpoint);
        endpoint.states().skipUntil(s -> s == EndpointState.CONNECTING).filter(s -> s == EndpointState.CONNECTED || s == EndpointState.DISCONNECTED).takeUntil(s -> s == EndpointState.CONNECTED || s == EndpointState.DISCONNECTED).publishOn(context().environment().scheduler()).subscribe(s -> {
            synchronized (PooledService.this) {
                reservedEndpoints.remove(endpoint);
                if (disconnected.get()) {
                    endpoint.disconnect();
                    endpointStates.deregister(endpoint);
                    RetryOrchestrator.maybeRetry(serviceContext, request, RetryReason.ENDPOINT_NOT_AVAILABLE);
                } else {
                    endpoints.add(endpoint);
                    if (s == EndpointState.CONNECTED) {
                        endpoint.send(request);
                    } else if (s == EndpointState.DISCONNECTED) {
                        RetryOrchestrator.maybeRetry(serviceContext, request, RetryReason.ENDPOINT_NOT_AVAILABLE);
                    }
                }
            }
        });
        endpoint.connect();
        reservedEndpoints.add(endpoint);
    }
}
Also used : RetryOrchestrator(com.couchbase.client.core.retry.RetryOrchestrator) EndpointState(com.couchbase.client.core.endpoint.EndpointState) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Endpoint(com.couchbase.client.core.endpoint.Endpoint) Request(com.couchbase.client.core.msg.Request) CompositeStateful(com.couchbase.client.core.util.CompositeStateful) HashMap(java.util.HashMap) ServiceStateChangedEvent(com.couchbase.client.core.cnc.events.service.ServiceStateChangedEvent) RetryReason(com.couchbase.client.core.retry.RetryReason) ArrayList(java.util.ArrayList) TimeUnit(java.util.concurrent.TimeUnit) Flux(reactor.core.publisher.Flux) List(java.util.List) Stream(java.util.stream.Stream) ServiceDisconnectInitiatedEvent(com.couchbase.client.core.cnc.events.service.ServiceDisconnectInitiatedEvent) Duration(java.time.Duration) Map(java.util.Map) EndpointContext(com.couchbase.client.core.endpoint.EndpointContext) EndpointDiagnostics(com.couchbase.client.core.diagnostics.EndpointDiagnostics) ServiceConnectInitiatedEvent(com.couchbase.client.core.cnc.events.service.ServiceConnectInitiatedEvent) Collections(java.util.Collections) Response(com.couchbase.client.core.msg.Response) IdleEndpointRemovedEvent(com.couchbase.client.core.cnc.events.service.IdleEndpointRemovedEvent) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) Endpoint(com.couchbase.client.core.endpoint.Endpoint)

Example 2 with Request

use of com.couchbase.client.core.msg.Request in project couchbase-jvm-clients by couchbase.

the class KeyValueMessageHandler method handleNotMyVbucket.

/**
 * Helper method to handle a "not my vbucket" response.
 *
 * @param request the request to retry.
 * @param response the response to extract the config from, potentially.
 */
private void handleNotMyVbucket(final KeyValueRequest<Response> request, final ByteBuf response) {
    request.indicateRejectedWithNotMyVbucket();
    eventBus.publish(new NotMyVbucketReceivedEvent(ioContext, request.partition()));
    final String origin = request.context().lastDispatchedTo() != null ? request.context().lastDispatchedTo().hostname() : null;
    RetryOrchestrator.maybeRetry(ioContext, request, RetryReason.KV_NOT_MY_VBUCKET);
    body(response).map(b -> b.toString(UTF_8).trim()).filter(c -> c.startsWith("{")).ifPresent(c -> ioContext.core().configurationProvider().proposeBucketConfig(new ProposedBucketConfigContext(request.bucket(), c, origin)));
}
Also used : IoContext(com.couchbase.client.core.io.IoContext) UnsignedLEB128(com.couchbase.client.core.util.UnsignedLEB128) HandlerUtils.closeChannelWithReason(com.couchbase.client.core.io.netty.HandlerUtils.closeChannelWithReason) ReferenceCountUtil(com.couchbase.client.core.deps.io.netty.util.ReferenceCountUtil) Request(com.couchbase.client.core.msg.Request) CompressionConfig(com.couchbase.client.core.env.CompressionConfig) RETRY_NOW(com.couchbase.client.core.io.netty.kv.ErrorMap.ErrorAttribute.RETRY_NOW) EventBus(com.couchbase.client.core.cnc.EventBus) TracingUtils.setCommonKVSpanAttributes(com.couchbase.client.core.io.netty.TracingUtils.setCommonKVSpanAttributes) ServiceType(com.couchbase.client.core.service.ServiceType) CoreContext(com.couchbase.client.core.CoreContext) Map(java.util.Map) TracingUtils.setCommonDispatchSpanAttributes(com.couchbase.client.core.io.netty.TracingUtils.setCommonDispatchSpanAttributes) EndpointContext(com.couchbase.client.core.endpoint.EndpointContext) ITEM_LOCKED(com.couchbase.client.core.io.netty.kv.ErrorMap.ErrorAttribute.ITEM_LOCKED) RequestSpan(com.couchbase.client.core.cnc.RequestSpan) CbTracing(com.couchbase.client.core.cnc.CbTracing) RetryOrchestrator(com.couchbase.client.core.retry.RetryOrchestrator) ChannelHandlerContext(com.couchbase.client.core.deps.io.netty.channel.ChannelHandlerContext) TEMP(com.couchbase.client.core.io.netty.kv.ErrorMap.ErrorAttribute.TEMP) BaseEndpoint(com.couchbase.client.core.endpoint.BaseEndpoint) Set(java.util.Set) KeyValueRequest(com.couchbase.client.core.msg.kv.KeyValueRequest) Collectors(java.util.stream.Collectors) TracingUtils(com.couchbase.client.core.io.netty.TracingUtils) RetryReason(com.couchbase.client.core.retry.RetryReason) ResponseStatus(com.couchbase.client.core.msg.ResponseStatus) DecodingFailureException(com.couchbase.client.core.error.DecodingFailureException) Optional(java.util.Optional) ChannelPromise(com.couchbase.client.core.deps.io.netty.channel.ChannelPromise) Response(com.couchbase.client.core.msg.Response) TracingUtils.setNumericOperationId(com.couchbase.client.core.io.netty.TracingUtils.setNumericOperationId) CollectionNotFoundException(com.couchbase.client.core.error.CollectionNotFoundException) UnsupportedResponseTypeReceivedEvent(com.couchbase.client.core.cnc.events.io.UnsupportedResponseTypeReceivedEvent) HashMap(java.util.HashMap) KeyValueErrorMapCodeHandledEvent(com.couchbase.client.core.cnc.events.io.KeyValueErrorMapCodeHandledEvent) IntObjectMap(com.couchbase.client.core.deps.io.netty.util.collection.IntObjectMap) TracingIdentifiers(com.couchbase.client.core.cnc.TracingIdentifiers) RETRY_LATER(com.couchbase.client.core.io.netty.kv.ErrorMap.ErrorAttribute.RETRY_LATER) NotMyVbucketReceivedEvent(com.couchbase.client.core.cnc.events.io.NotMyVbucketReceivedEvent) MemcachedBucketConfig(com.couchbase.client.core.config.MemcachedBucketConfig) ProposedBucketConfigContext(com.couchbase.client.core.config.ProposedBucketConfigContext) ByteBuf(com.couchbase.client.core.deps.io.netty.buffer.ByteBuf) ChannelDuplexHandler(com.couchbase.client.core.deps.io.netty.channel.ChannelDuplexHandler) CollectionOutdatedHandledEvent(com.couchbase.client.core.cnc.events.io.CollectionOutdatedHandledEvent) RequestTracer(com.couchbase.client.core.cnc.RequestTracer) InvalidRequestDetectedEvent(com.couchbase.client.core.cnc.events.io.InvalidRequestDetectedEvent) ConfigurationProvider(com.couchbase.client.core.config.ConfigurationProvider) UnknownResponseReceivedEvent(com.couchbase.client.core.cnc.events.io.UnknownResponseReceivedEvent) UTF_8(java.nio.charset.StandardCharsets.UTF_8) FeatureNotAvailableException(com.couchbase.client.core.error.FeatureNotAvailableException) UnlockRequest(com.couchbase.client.core.msg.kv.UnlockRequest) CollectionMap(com.couchbase.client.core.io.CollectionMap) ByteBufUtil(com.couchbase.client.core.deps.io.netty.buffer.ByteBufUtil) CONN_STATE_INVALIDATED(com.couchbase.client.core.io.netty.kv.ErrorMap.ErrorAttribute.CONN_STATE_INVALIDATED) UnknownResponseStatusReceivedEvent(com.couchbase.client.core.cnc.events.io.UnknownResponseStatusReceivedEvent) ChannelClosedProactivelyEvent(com.couchbase.client.core.cnc.events.io.ChannelClosedProactivelyEvent) IntObjectHashMap(com.couchbase.client.core.deps.io.netty.util.collection.IntObjectHashMap) AUTH(com.couchbase.client.core.io.netty.kv.ErrorMap.ErrorAttribute.AUTH) MemcacheProtocol.body(com.couchbase.client.core.io.netty.kv.MemcacheProtocol.body) NotMyVbucketReceivedEvent(com.couchbase.client.core.cnc.events.io.NotMyVbucketReceivedEvent) ProposedBucketConfigContext(com.couchbase.client.core.config.ProposedBucketConfigContext)

Example 3 with Request

use of com.couchbase.client.core.msg.Request in project couchbase-jvm-clients by couchbase.

the class NodeTest method retriesIfGlobalServiceNotFound.

@Test
void retriesIfGlobalServiceNotFound() {
    final Service s = mock(Service.class);
    final AtomicReference<Request<?>> retried = new AtomicReference<>();
    Node node = new Node(CTX, mock(NodeIdentifier.class), NO_ALTERNATE) {

        @Override
        protected Service createService(ServiceType serviceType, int port, Optional<String> bucket) {
            when(s.state()).thenReturn(ServiceState.CONNECTED);
            when(s.states()).thenReturn(DirectProcessor.create());
            when(s.type()).thenReturn(serviceType);
            return s;
        }

        @Override
        protected <R extends Request<? extends Response>> void sendIntoRetry(R request) {
            retried.set(request);
        }
    };
    QueryRequest r = mock(QueryRequest.class);
    when(r.serviceType()).thenReturn(ServiceType.QUERY);
    node.send(r);
    verify(s, never()).send(eq(r));
    assertEquals(r, retried.get());
}
Also used : Response(com.couchbase.client.core.msg.Response) Optional(java.util.Optional) QueryRequest(com.couchbase.client.core.msg.query.QueryRequest) ServiceType(com.couchbase.client.core.service.ServiceType) QueryRequest(com.couchbase.client.core.msg.query.QueryRequest) Request(com.couchbase.client.core.msg.Request) KeyValueRequest(com.couchbase.client.core.msg.kv.KeyValueRequest) Service(com.couchbase.client.core.service.Service) AtomicReference(java.util.concurrent.atomic.AtomicReference) Test(org.junit.jupiter.api.Test)

Example 4 with Request

use of com.couchbase.client.core.msg.Request in project couchbase-jvm-clients by couchbase.

the class RetryOrchestratorTest method retryWithDelay.

@Test
@SuppressWarnings({ "unchecked" })
void retryWithDelay() {
    Timer timer = Timer.createAndStart(CoreEnvironment.DEFAULT_MAX_NUM_REQUESTS_IN_RETRY);
    RetryStrategy retryStrategy = mock(RetryStrategy.class);
    when(retryStrategy.shouldRetry(any(Request.class), any(RetryReason.class))).thenReturn(CompletableFuture.completedFuture(RetryAction.withDuration(Duration.ofMillis(200))));
    Request<?> request = mock(Request.class);
    RequestContext requestContext = mock(RequestContext.class);
    when(request.completed()).thenReturn(false);
    when(request.context()).thenReturn(requestContext);
    when(request.retryStrategy()).thenReturn(retryStrategy);
    when(request.absoluteTimeout()).thenReturn(System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(2500));
    Core core = mock(Core.class);
    CoreEnvironment env = mock(CoreEnvironment.class);
    SimpleEventBus eventBus = new SimpleEventBus(true);
    when(env.timer()).thenReturn(timer);
    when(env.eventBus()).thenReturn(eventBus);
    CoreContext ctx = new CoreContext(core, 1, env, mock(Authenticator.class));
    long start = System.nanoTime();
    RetryOrchestrator.maybeRetry(ctx, request, RetryReason.UNKNOWN);
    verify(requestContext, times(1)).incrementRetryAttempts(Duration.ofMillis(200), RetryReason.UNKNOWN);
    verify(request, never()).cancel(CancellationReason.noMoreRetries(RetryReason.UNKNOWN));
    waitUntilCondition(() -> !Mockito.mockingDetails(core).getInvocations().isEmpty());
    long end = System.nanoTime();
    verify(core, times(1)).send(request, false);
    verify(core, never()).send(request);
    assertTrue(TimeUnit.NANOSECONDS.toMillis(end - start) >= 200);
    timer.stop();
    assertEquals(1, eventBus.publishedEvents().size());
    RequestRetryScheduledEvent retryEvent = (RequestRetryScheduledEvent) eventBus.publishedEvents().get(0);
    assertEquals(Event.Severity.DEBUG, retryEvent.severity());
    assertEquals(Event.Category.REQUEST.path(), retryEvent.category());
    assertEquals(requestContext, retryEvent.context());
    assertEquals(RetryReason.UNKNOWN, retryEvent.retryReason());
}
Also used : CoreContext(com.couchbase.client.core.CoreContext) RequestRetryScheduledEvent(com.couchbase.client.core.cnc.events.request.RequestRetryScheduledEvent) CoreEnvironment(com.couchbase.client.core.env.CoreEnvironment) Request(com.couchbase.client.core.msg.Request) Timer(com.couchbase.client.core.Timer) SimpleEventBus(com.couchbase.client.core.cnc.SimpleEventBus) RequestContext(com.couchbase.client.core.msg.RequestContext) Authenticator(com.couchbase.client.core.env.Authenticator) Core(com.couchbase.client.core.Core) Test(org.junit.jupiter.api.Test)

Example 5 with Request

use of com.couchbase.client.core.msg.Request in project couchbase-jvm-clients by couchbase.

the class RetryOrchestratorTest method capsRetryDelay.

@Test
@SuppressWarnings({ "unchecked" })
void capsRetryDelay() {
    Timer timer = Timer.createAndStart(CoreEnvironment.DEFAULT_MAX_NUM_REQUESTS_IN_RETRY);
    RetryStrategy retryStrategy = mock(RetryStrategy.class);
    when(retryStrategy.shouldRetry(any(Request.class), any(RetryReason.class))).thenReturn(CompletableFuture.completedFuture(RetryAction.withDuration(Duration.ofMillis(200))));
    Request<?> request = mock(Request.class);
    RequestContext requestContext = mock(RequestContext.class);
    when(request.completed()).thenReturn(false);
    when(request.context()).thenReturn(requestContext);
    when(request.retryStrategy()).thenReturn(retryStrategy);
    when(request.absoluteTimeout()).thenAnswer(invocationOnMock -> System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(10));
    Core core = mock(Core.class);
    CoreEnvironment env = mock(CoreEnvironment.class);
    SimpleEventBus eventBus = new SimpleEventBus(true);
    when(env.timer()).thenReturn(timer);
    when(env.eventBus()).thenReturn(eventBus);
    CoreContext ctx = new CoreContext(core, 1, env, mock(Authenticator.class));
    long start = System.nanoTime();
    RetryOrchestrator.maybeRetry(ctx, request, RetryReason.UNKNOWN);
    verify(requestContext, never()).incrementRetryAttempts((Duration.ofMillis(200)), RetryReason.UNKNOWN);
    verify(request, never()).cancel(CancellationReason.noMoreRetries(RetryReason.UNKNOWN));
    waitUntilCondition(() -> !Mockito.mockingDetails(core).getInvocations().isEmpty());
    long end = System.nanoTime();
    verify(core, times(1)).send(request, false);
    verify(core, never()).send(request);
    assertTrue(TimeUnit.NANOSECONDS.toMillis(end - start) < 200);
    timer.stop();
    assertEquals(1, eventBus.publishedEvents().size());
    RequestRetryScheduledEvent retryEvent = (RequestRetryScheduledEvent) eventBus.publishedEvents().get(0);
    assertEquals(Event.Severity.DEBUG, retryEvent.severity());
    assertEquals(Event.Category.REQUEST.path(), retryEvent.category());
    assertEquals(requestContext, retryEvent.context());
    assertEquals(RetryReason.UNKNOWN, retryEvent.retryReason());
}
Also used : CoreContext(com.couchbase.client.core.CoreContext) RequestRetryScheduledEvent(com.couchbase.client.core.cnc.events.request.RequestRetryScheduledEvent) CoreEnvironment(com.couchbase.client.core.env.CoreEnvironment) Request(com.couchbase.client.core.msg.Request) Timer(com.couchbase.client.core.Timer) SimpleEventBus(com.couchbase.client.core.cnc.SimpleEventBus) RequestContext(com.couchbase.client.core.msg.RequestContext) Authenticator(com.couchbase.client.core.env.Authenticator) Core(com.couchbase.client.core.Core) Test(org.junit.jupiter.api.Test)

Aggregations

Request (com.couchbase.client.core.msg.Request)8 Test (org.junit.jupiter.api.Test)6 CoreContext (com.couchbase.client.core.CoreContext)4 Response (com.couchbase.client.core.msg.Response)4 Core (com.couchbase.client.core.Core)3 SimpleEventBus (com.couchbase.client.core.cnc.SimpleEventBus)3 Authenticator (com.couchbase.client.core.env.Authenticator)3 CoreEnvironment (com.couchbase.client.core.env.CoreEnvironment)3 RequestContext (com.couchbase.client.core.msg.RequestContext)3 KeyValueRequest (com.couchbase.client.core.msg.kv.KeyValueRequest)3 ServiceType (com.couchbase.client.core.service.ServiceType)3 Optional (java.util.Optional)3 Timer (com.couchbase.client.core.Timer)2 RequestRetryScheduledEvent (com.couchbase.client.core.cnc.events.request.RequestRetryScheduledEvent)2 EndpointContext (com.couchbase.client.core.endpoint.EndpointContext)2 RetryOrchestrator (com.couchbase.client.core.retry.RetryOrchestrator)2 RetryReason (com.couchbase.client.core.retry.RetryReason)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 CbTracing (com.couchbase.client.core.cnc.CbTracing)1