Search in sources :

Example 16 with RequestSpan

use of com.couchbase.client.core.cnc.RequestSpan in project couchbase-jvm-clients by couchbase.

the class Observe method viaMutationToken.

private static Flux<ObserveItem> viaMutationToken(final int bucketReplicas, final ObserveContext ctx, final RequestSpan parent) {
    if (!ctx.mutationToken().isPresent()) {
        throw new IllegalStateException("MutationToken is not present, this is a bug!");
    }
    Duration timeout = ctx.timeout();
    RetryStrategy retryStrategy = ctx.retryStrategy();
    MutationToken mutationToken = ctx.mutationToken().get();
    String id = ctx.key();
    List<ObserveViaSeqnoRequest> requests = new ArrayList<>();
    if (ctx.persistTo() != ObservePersistTo.NONE) {
        final RequestSpan span = ctx.environment().requestTracer().requestSpan(TracingIdentifiers.SPAN_REQUEST_KV_OBSERVE, parent);
        requests.add(new ObserveViaSeqnoRequest(timeout, ctx, ctx.collectionIdentifier(), retryStrategy, 0, true, mutationToken.partitionUUID(), id, span));
    }
    if (ctx.persistTo().touchesReplica() || ctx.replicateTo().touchesReplica()) {
        for (short i = 1; i <= bucketReplicas; i++) {
            final RequestSpan span = ctx.environment().requestTracer().requestSpan(TracingIdentifiers.SPAN_REQUEST_KV_OBSERVE, parent);
            requests.add(new ObserveViaSeqnoRequest(timeout, ctx, ctx.collectionIdentifier(), retryStrategy, i, false, mutationToken.partitionUUID(), id, span));
        }
    }
    return Flux.fromIterable(requests).flatMap(request -> {
        ctx.core().send(request);
        return Reactor.wrap(request, request.response(), true).onErrorResume(t -> Mono.empty()).doFinally(signalType -> request.context().logicallyComplete());
    }).map(response -> ObserveItem.fromMutationToken(mutationToken, response));
}
Also used : Reactor(com.couchbase.client.core.Reactor) Repeat(com.couchbase.client.core.retry.reactor.Repeat) ReplicaNotConfiguredException(com.couchbase.client.core.error.ReplicaNotConfiguredException) FeatureNotAvailableException(com.couchbase.client.core.error.FeatureNotAvailableException) Mono(reactor.core.publisher.Mono) CouchbaseBucketConfig(com.couchbase.client.core.config.CouchbaseBucketConfig) ArrayList(java.util.ArrayList) MutationToken(com.couchbase.client.core.msg.kv.MutationToken) Flux(reactor.core.publisher.Flux) List(java.util.List) TracingIdentifiers(com.couchbase.client.core.cnc.TracingIdentifiers) ObserveViaSeqnoRequest(com.couchbase.client.core.msg.kv.ObserveViaSeqnoRequest) Duration(java.time.Duration) RequestSpan(com.couchbase.client.core.cnc.RequestSpan) RetryStrategy(com.couchbase.client.core.retry.RetryStrategy) BucketConfig(com.couchbase.client.core.config.BucketConfig) ObserveViaSeqnoRequest(com.couchbase.client.core.msg.kv.ObserveViaSeqnoRequest) MutationToken(com.couchbase.client.core.msg.kv.MutationToken) ArrayList(java.util.ArrayList) Duration(java.time.Duration) RetryStrategy(com.couchbase.client.core.retry.RetryStrategy) RequestSpan(com.couchbase.client.core.cnc.RequestSpan)

Example 17 with RequestSpan

use of com.couchbase.client.core.cnc.RequestSpan in project couchbase-jvm-clients by couchbase.

the class Observe method poll.

public static Mono<Void> poll(final ObserveContext ctx) {
    if (ctx.persistTo() == ObservePersistTo.NONE && ctx.replicateTo() == ObserveReplicateTo.NONE) {
        return Mono.empty();
    }
    if (!ctx.environment().ioConfig().mutationTokensEnabled() || !ctx.mutationToken().isPresent()) {
        return Mono.error(new FeatureNotAvailableException("To use PersistTo and/or ReplicateTo, mutation tokens must " + "be enabled on the IO configuration"));
    }
    final RequestSpan parentSpan = ctx.environment().requestTracer().requestSpan("observe", ctx.parentSpan());
    Flux<ObserveItem> observed = Flux.defer(() -> {
        BucketConfig config = ctx.core().clusterConfig().bucketConfig(ctx.collectionIdentifier().bucket());
        return Flux.just(validateReplicas(config, ctx.persistTo(), ctx.replicateTo()));
    }).flatMap(replicas -> viaMutationToken(replicas, ctx, parentSpan));
    return maybeRetry(observed, ctx).timeout(ctx.timeout(), ctx.environment().scheduler()).doFinally(t -> parentSpan.end());
}
Also used : FeatureNotAvailableException(com.couchbase.client.core.error.FeatureNotAvailableException) CouchbaseBucketConfig(com.couchbase.client.core.config.CouchbaseBucketConfig) BucketConfig(com.couchbase.client.core.config.BucketConfig) RequestSpan(com.couchbase.client.core.cnc.RequestSpan)

Example 18 with RequestSpan

use of com.couchbase.client.core.cnc.RequestSpan in project couchbase-jvm-clients by couchbase.

the class QueryRequest method toPrepareRequest.

/**
 * Returns a new request that creates a prepared statement using this request as a template.
 */
@Stability.Internal
public QueryRequest toPrepareRequest(boolean autoExecute, RequestTracer requestTracer) {
    String newStatement = "PREPARE " + statement();
    byte[] newQuery = transformQuery(query -> {
        query.put("statement", newStatement);
        if (autoExecute) {
            query.put("auto_execute", true);
        } else {
            // Keep only the fields required for preparation.
            // Discard things like arguments, scan vectors, etc.
            query.retain("statement", "timeout", "client_context_id", "query_context");
        }
    });
    RequestSpan newSpan = requestTracer.requestSpan("prepare", requestSpan());
    boolean newIdempotent = !autoExecute || idempotent();
    return copy(newStatement, newQuery, newIdempotent, newSpan);
}
Also used : RequestSpan(com.couchbase.client.core.cnc.RequestSpan)

Example 19 with RequestSpan

use of com.couchbase.client.core.cnc.RequestSpan in project couchbase-jvm-clients by couchbase.

the class KeyValueMessageHandler method write.

@Override
@SuppressWarnings({ "unchecked" })
public void write(final ChannelHandlerContext ctx, final Object msg, final ChannelPromise promise) {
    if (msg instanceof KeyValueRequest) {
        KeyValueRequest<Response> request = (KeyValueRequest<Response>) msg;
        int opaque = request.opaque();
        writtenRequests.put(opaque, request);
        try {
            ctx.write(request.encode(ctx.alloc(), opaque, channelContext), promise);
            writtenRequestDispatchTimings.put(opaque, (Long) System.nanoTime());
            if (request.requestSpan() != null) {
                RequestTracer tracer = endpointContext.environment().requestTracer();
                RequestSpan dispatchSpan = tracer.requestSpan(TracingIdentifiers.SPAN_DISPATCH, request.requestSpan());
                if (!isInternalTracer) {
                    setCommonDispatchSpanAttributes(dispatchSpan, ctx.channel().attr(ChannelAttributes.CHANNEL_ID_KEY).get(), ioContext.localHostname(), ioContext.localPort(), endpoint.remoteHostname(), endpoint.remotePort(), null);
                    setNumericOperationId(dispatchSpan, request.opaque());
                    setCommonKVSpanAttributes(dispatchSpan, request);
                }
                writtenRequestDispatchSpans.put(opaque, dispatchSpan);
            }
        } catch (Throwable err) {
            writtenRequests.remove(opaque);
            if (err instanceof CollectionNotFoundException) {
                if (channelContext.collectionsEnabled()) {
                    ConfigurationProvider cp = ioContext.core().configurationProvider();
                    if (cp.collectionRefreshInProgress(request.collectionIdentifier())) {
                        RetryOrchestrator.maybeRetry(ioContext, request, RetryReason.COLLECTION_MAP_REFRESH_IN_PROGRESS);
                    } else if (cp.config().bucketConfig(request.bucket()) instanceof MemcachedBucketConfig) {
                        request.fail(FeatureNotAvailableException.collectionsForMemcached());
                    } else {
                        handleOutdatedCollection(request, RetryReason.COLLECTION_NOT_FOUND);
                    }
                    return;
                }
            }
            request.fail(err);
        }
    } else {
        eventBus.publish(new InvalidRequestDetectedEvent(ioContext, ServiceType.KV, msg));
        ctx.channel().close().addListener(f -> eventBus.publish(new ChannelClosedProactivelyEvent(ioContext, ChannelClosedProactivelyEvent.Reason.INVALID_REQUEST_DETECTED)));
    }
}
Also used : Response(com.couchbase.client.core.msg.Response) KeyValueRequest(com.couchbase.client.core.msg.kv.KeyValueRequest) ChannelClosedProactivelyEvent(com.couchbase.client.core.cnc.events.io.ChannelClosedProactivelyEvent) ConfigurationProvider(com.couchbase.client.core.config.ConfigurationProvider) MemcachedBucketConfig(com.couchbase.client.core.config.MemcachedBucketConfig) RequestTracer(com.couchbase.client.core.cnc.RequestTracer) BaseEndpoint(com.couchbase.client.core.endpoint.BaseEndpoint) CollectionNotFoundException(com.couchbase.client.core.error.CollectionNotFoundException) InvalidRequestDetectedEvent(com.couchbase.client.core.cnc.events.io.InvalidRequestDetectedEvent) RequestSpan(com.couchbase.client.core.cnc.RequestSpan)

Example 20 with RequestSpan

use of com.couchbase.client.core.cnc.RequestSpan 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)

Aggregations

RequestSpan (com.couchbase.client.core.cnc.RequestSpan)42 Duration (java.time.Duration)30 RetryStrategy (com.couchbase.client.core.retry.RetryStrategy)28 TracingIdentifiers (com.couchbase.client.core.cnc.TracingIdentifiers)12 CompletableFuture (java.util.concurrent.CompletableFuture)11 Stability (com.couchbase.client.core.annotation.Stability)10 Validators.notNullOrEmpty (com.couchbase.client.core.util.Validators.notNullOrEmpty)10 List (java.util.List)10 Core (com.couchbase.client.core.Core)9 ArrayList (java.util.ArrayList)9 Map (java.util.Map)9 BucketConfig (com.couchbase.client.core.config.BucketConfig)8 CouchbaseException (com.couchbase.client.core.error.CouchbaseException)8 Objects.requireNonNull (java.util.Objects.requireNonNull)8 Mono (reactor.core.publisher.Mono)8 Reactor (com.couchbase.client.core.Reactor)7 InvalidArgumentException (com.couchbase.client.core.error.InvalidArgumentException)7 GetRequest (com.couchbase.client.core.msg.kv.GetRequest)7 Function (java.util.function.Function)7 CoreContext (com.couchbase.client.core.CoreContext)6