Search in sources :

Example 1 with RetryReason

use of com.couchbase.client.core.retry.RetryReason in project couchbase-jvm-clients by couchbase.

the class ChunkedMessageHandler method maybeCompleteResponseWithFailure.

private void maybeCompleteResponseWithFailure() {
    if (!currentRequest.completed()) {
        final CouchbaseException cause = chunkResponseParser.decodingFailure().orElseGet(() -> chunkResponseParser.error().orElseGet(() -> new CouchbaseException("Request failed, but no more information available")));
        Optional<RetryReason> qualifies = qualifiesForRetry(cause);
        if (qualifies.isPresent()) {
            RetryOrchestrator.maybeRetry(ioContext, currentRequest, qualifies.get());
        } else {
            currentRequest.fail(cause);
        }
    } else {
        ioContext.environment().orphanReporter().report(currentRequest);
    }
}
Also used : CouchbaseException(com.couchbase.client.core.error.CouchbaseException) RetryReason(com.couchbase.client.core.retry.RetryReason)

Example 2 with RetryReason

use of com.couchbase.client.core.retry.RetryReason in project couchbase-jvm-clients by couchbase.

the class KeyValueMessageHandler method decode.

/**
 * Main method to start dispatching the decode.
 *
 * @param ctx the channel handler context from netty.
 * @param response the response to decode and handle.
 */
private void decode(final ChannelHandlerContext ctx, final ByteBuf response) {
    int opaque = MemcacheProtocol.opaque(response);
    KeyValueRequest<Response> request = writtenRequests.remove(opaque);
    if (request == null) {
        handleUnknownResponseReceived(ctx, response);
        return;
    }
    long serverTime = MemcacheProtocol.parseServerDurationFromResponse(response);
    request.context().serverLatency(serverTime);
    long start = writtenRequestDispatchTimings.remove(opaque);
    request.context().dispatchLatency(System.nanoTime() - start);
    RequestSpan dispatchSpan = writtenRequestDispatchSpans.remove(opaque);
    if (dispatchSpan != null) {
        if (!isInternalTracer) {
            TracingUtils.setServerDurationAttribute(dispatchSpan, serverTime);
        }
        dispatchSpan.end();
    }
    short statusCode = MemcacheProtocol.status(response);
    ResponseStatus status = MemcacheProtocol.decodeStatus(statusCode);
    ErrorMap.ErrorCode errorCode = status != ResponseStatus.SUCCESS ? decodeErrorCode(statusCode) : null;
    if (errorCode != null) {
        request.errorCode(errorCode);
    }
    boolean errorUnknown = false;
    if (status == ResponseStatus.UNKNOWN) {
        errorUnknown = true;
        if (errorCode != null) {
            ioContext.environment().eventBus().publish(new KeyValueErrorMapCodeHandledEvent(ioContext, errorCode));
            status = handleErrorCode(ctx, errorCode);
        }
        ioContext.environment().eventBus().publish(new UnknownResponseStatusReceivedEvent(ioContext, statusCode));
    }
    if (status == ResponseStatus.NOT_MY_VBUCKET) {
        handleNotMyVbucket(request, response);
    } else if (status == ResponseStatus.UNKNOWN_COLLECTION) {
        handleOutdatedCollection(request, RetryReason.KV_COLLECTION_OUTDATED);
    } else if (errorUnknown && errorMapIndicatesRetry(errorCode)) {
        RetryOrchestrator.maybeRetry(ioContext, request, RetryReason.KV_ERROR_MAP_INDICATED);
    } else if (statusIndicatesInvalidChannel(status)) {
        closeChannelWithReason(ioContext, ctx, ChannelClosedProactivelyEvent.Reason.KV_RESPONSE_CONTAINED_CLOSE_INDICATION);
    } else {
        RetryReason retryReason = statusCodeIndicatesRetry(status, request);
        if (retryReason == null) {
            if (!request.completed()) {
                decodeAndComplete(request, response);
            } else {
                ioContext.environment().orphanReporter().report(request);
            }
        } else {
            RetryOrchestrator.maybeRetry(ioContext, request, retryReason);
        }
    }
}
Also used : BaseEndpoint(com.couchbase.client.core.endpoint.BaseEndpoint) RequestSpan(com.couchbase.client.core.cnc.RequestSpan) Response(com.couchbase.client.core.msg.Response) RetryReason(com.couchbase.client.core.retry.RetryReason) ResponseStatus(com.couchbase.client.core.msg.ResponseStatus) UnknownResponseStatusReceivedEvent(com.couchbase.client.core.cnc.events.io.UnknownResponseStatusReceivedEvent) KeyValueErrorMapCodeHandledEvent(com.couchbase.client.core.cnc.events.io.KeyValueErrorMapCodeHandledEvent)

Example 3 with RetryReason

use of com.couchbase.client.core.retry.RetryReason in project couchbase-jvm-clients by couchbase.

the class BaseEndpoint method send.

@Override
public <R extends Request<? extends Response>> void send(final R request) {
    if (request.timeoutElapsed()) {
        request.cancel(CancellationReason.TIMEOUT);
    }
    if (request.completed()) {
        return;
    }
    final EndpointContext ctx = endpointContext.get();
    if (canWrite()) {
        request.context().lastDispatchedFrom(ctx.localSocket().orElse(null)).lastDispatchedTo(ctx.remoteSocket()).lastChannelId(ctx.channelId().orElse(null));
        if (!pipelined) {
            outstandingRequests.incrementAndGet();
        }
        if (circuitBreakerEnabled) {
            circuitBreaker.track();
            request.response().whenComplete((response, throwable) -> {
                if (circuitBreakerCallback.apply(response, throwable)) {
                    circuitBreaker.markSuccess();
                } else {
                    circuitBreaker.markFailure();
                }
            });
        }
        channel.writeAndFlush(request).addListener(f -> {
            if (!f.isSuccess()) {
                EndpointContext context = endpointContext.get();
                Event.Severity severity = disconnect.get() ? Event.Severity.DEBUG : Event.Severity.WARN;
                context.environment().eventBus().publish(new EndpointWriteFailedEvent(severity, context, f.cause()));
                RetryOrchestrator.maybeRetry(context, request, RetryReason.ENDPOINT_NOT_WRITABLE);
            }
        });
    } else {
        RetryReason retryReason = circuitBreaker.allowsRequest() ? RetryReason.ENDPOINT_NOT_WRITABLE : RetryReason.ENDPOINT_CIRCUIT_OPEN;
        RetryOrchestrator.maybeRetry(endpointContext.get(), request, retryReason);
    }
}
Also used : RetryReason(com.couchbase.client.core.retry.RetryReason) EndpointDisconnectionFailedEvent(com.couchbase.client.core.cnc.events.endpoint.EndpointDisconnectionFailedEvent) EndpointConnectionAbortedEvent(com.couchbase.client.core.cnc.events.endpoint.EndpointConnectionAbortedEvent) EndpointConnectedEvent(com.couchbase.client.core.cnc.events.endpoint.EndpointConnectedEvent) UnexpectedEndpointDisconnectedEvent(com.couchbase.client.core.cnc.events.endpoint.UnexpectedEndpointDisconnectedEvent) EndpointWriteFailedEvent(com.couchbase.client.core.cnc.events.endpoint.EndpointWriteFailedEvent) EndpointConnectionFailedEvent(com.couchbase.client.core.cnc.events.endpoint.EndpointConnectionFailedEvent) UnexpectedEndpointConnectionFailedEvent(com.couchbase.client.core.cnc.events.endpoint.UnexpectedEndpointConnectionFailedEvent) EndpointConnectionIgnoredEvent(com.couchbase.client.core.cnc.events.endpoint.EndpointConnectionIgnoredEvent) Event(com.couchbase.client.core.cnc.Event) EndpointStateChangedEvent(com.couchbase.client.core.cnc.events.endpoint.EndpointStateChangedEvent) EndpointDisconnectedEvent(com.couchbase.client.core.cnc.events.endpoint.EndpointDisconnectedEvent) EndpointWriteFailedEvent(com.couchbase.client.core.cnc.events.endpoint.EndpointWriteFailedEvent)

Example 4 with RetryReason

use of com.couchbase.client.core.retry.RetryReason in project couchbase-jvm-clients by couchbase.

the class KeyValueMessageHandlerTest method retriesCertainResponseStatusCodes.

/**
 * Certain status codes are identified that should be passed to the retry orchestrator rathen than complete
 * the response right away.
 */
@Test
void retriesCertainResponseStatusCodes() {
    List<MemcacheProtocol.Status> retryOnThese = Arrays.asList(MemcacheProtocol.Status.LOCKED, MemcacheProtocol.Status.TEMPORARY_FAILURE, MemcacheProtocol.Status.SYNC_WRITE_IN_PROGRESS, MemcacheProtocol.Status.SYNC_WRITE_RE_COMMIT_IN_PROGRESS);
    List<RetryReason> retryReasons = Arrays.asList(RetryReason.KV_LOCKED, RetryReason.KV_TEMPORARY_FAILURE, RetryReason.KV_SYNC_WRITE_IN_PROGRESS, RetryReason.KV_SYNC_WRITE_RE_COMMIT_IN_PROGRESS);
    int i = 0;
    for (MemcacheProtocol.Status status : retryOnThese) {
        EmbeddedChannel channel = new EmbeddedChannel(new KeyValueMessageHandler(null, CTX, Optional.of(BUCKET)));
        try {
            GetRequest request = new GetRequest("key", Duration.ofSeconds(1), CTX, CID, FailFastRetryStrategy.INSTANCE, null);
            channel.writeOutbound(request);
            ByteBuf getResponse = MemcacheProtocol.response(channel.alloc(), MemcacheProtocol.Opcode.GET, (byte) 0, status.status(), request.opaque(), 0, Unpooled.EMPTY_BUFFER, Unpooled.EMPTY_BUFFER, Unpooled.EMPTY_BUFFER);
            channel.writeInbound(getResponse);
            assertEquals(CancellationReason.noMoreRetries(retryReasons.get(i)), request.cancellationReason());
            assertEquals(0, getResponse.refCnt());
            i++;
        } finally {
            channel.finishAndReleaseAll();
        }
    }
}
Also used : RetryReason(com.couchbase.client.core.retry.RetryReason) GetRequest(com.couchbase.client.core.msg.kv.GetRequest) EmbeddedChannel(com.couchbase.client.core.deps.io.netty.channel.embedded.EmbeddedChannel) ByteBuf(com.couchbase.client.core.deps.io.netty.buffer.ByteBuf) Test(org.junit.jupiter.api.Test)

Aggregations

RetryReason (com.couchbase.client.core.retry.RetryReason)4 Event (com.couchbase.client.core.cnc.Event)1 RequestSpan (com.couchbase.client.core.cnc.RequestSpan)1 EndpointConnectedEvent (com.couchbase.client.core.cnc.events.endpoint.EndpointConnectedEvent)1 EndpointConnectionAbortedEvent (com.couchbase.client.core.cnc.events.endpoint.EndpointConnectionAbortedEvent)1 EndpointConnectionFailedEvent (com.couchbase.client.core.cnc.events.endpoint.EndpointConnectionFailedEvent)1 EndpointConnectionIgnoredEvent (com.couchbase.client.core.cnc.events.endpoint.EndpointConnectionIgnoredEvent)1 EndpointDisconnectedEvent (com.couchbase.client.core.cnc.events.endpoint.EndpointDisconnectedEvent)1 EndpointDisconnectionFailedEvent (com.couchbase.client.core.cnc.events.endpoint.EndpointDisconnectionFailedEvent)1 EndpointStateChangedEvent (com.couchbase.client.core.cnc.events.endpoint.EndpointStateChangedEvent)1 EndpointWriteFailedEvent (com.couchbase.client.core.cnc.events.endpoint.EndpointWriteFailedEvent)1 UnexpectedEndpointConnectionFailedEvent (com.couchbase.client.core.cnc.events.endpoint.UnexpectedEndpointConnectionFailedEvent)1 UnexpectedEndpointDisconnectedEvent (com.couchbase.client.core.cnc.events.endpoint.UnexpectedEndpointDisconnectedEvent)1 KeyValueErrorMapCodeHandledEvent (com.couchbase.client.core.cnc.events.io.KeyValueErrorMapCodeHandledEvent)1 UnknownResponseStatusReceivedEvent (com.couchbase.client.core.cnc.events.io.UnknownResponseStatusReceivedEvent)1 ByteBuf (com.couchbase.client.core.deps.io.netty.buffer.ByteBuf)1 EmbeddedChannel (com.couchbase.client.core.deps.io.netty.channel.embedded.EmbeddedChannel)1 BaseEndpoint (com.couchbase.client.core.endpoint.BaseEndpoint)1 CouchbaseException (com.couchbase.client.core.error.CouchbaseException)1 Response (com.couchbase.client.core.msg.Response)1