Search in sources :

Example 1 with TrackingBackupRequestsStrategy

use of com.linkedin.d2.backuprequests.TrackingBackupRequestsStrategy in project rest.li by linkedin.

the class BackupRequestsClient method getStrategyAfterUpdate.

/*private*/
Optional<TrackingBackupRequestsStrategy> getStrategyAfterUpdate(final String serviceName, final String operation) {
    Map<String, BackupRequestsStrategyFromConfig> strategiesForOperation = _strategies.get(serviceName);
    if (strategiesForOperation != null) {
        BackupRequestsStrategyFromConfig backupRequestsStrategyFromConfig = strategiesForOperation.get(operation);
        if (backupRequestsStrategyFromConfig != null) {
            return backupRequestsStrategyFromConfig.getStrategy();
        }
    }
    LOG.debug("No backup requests strategy found");
    return Optional.empty();
}
Also used : ByteString(com.linkedin.data.ByteString) BackupRequestsStrategyFromConfig(com.linkedin.d2.backuprequests.BackupRequestsStrategyFromConfig)

Example 2 with TrackingBackupRequestsStrategy

use of com.linkedin.d2.backuprequests.TrackingBackupRequestsStrategy in project rest.li by linkedin.

the class BackupRequestsClient method decorateCallbackWithBackupRequest.

private <R extends Request, T> Callback<T> decorateCallbackWithBackupRequest(R request, RequestContext requestContext, DecoratorClient<R, T> client, Callback<T> callback, TrackingBackupRequestsStrategy strategy, String serviceName, String operation) {
    final long startNano = System.nanoTime();
    URI targetHostUri = KeyMapper.TargetHostHints.getRequestContextTargetHost(requestContext);
    Boolean backupRequestAcceptable = KeyMapper.TargetHostHints.getRequestContextOtherHostAcceptable(requestContext);
    if (targetHostUri == null || (backupRequestAcceptable != null && backupRequestAcceptable)) {
        Optional<Long> delayNano = strategy.getTimeUntilBackupRequestNano();
        if (delayNano.isPresent()) {
            return new DecoratedCallback<>(request, requestContext, client, callback, strategy, delayNano.get(), _executorService, startNano, serviceName, operation);
        }
    }
    // 2. backup strategy is not ready yet
    return new Callback<T>() {

        @Override
        public void onSuccess(T result) {
            recordLatency();
            callback.onSuccess(result);
        }

        private void recordLatency() {
            long latency = System.nanoTime() - startNano;
            strategy.recordCompletion(latency);
            strategy.getLatencyWithoutBackup().record(latency, histogram -> notifyLatency(serviceName, operation, histogram, false));
            strategy.getLatencyWithBackup().record(latency, histogram -> notifyLatency(serviceName, operation, histogram, true));
        }

        @Override
        public void onError(Throwable e) {
            // disregard latency if request was not made
            if (!(e instanceof ServiceUnavailableException)) {
                recordLatency();
            }
            callback.onError(e);
        }
    };
}
Also used : FutureCallback(com.linkedin.common.callback.FutureCallback) Callback(com.linkedin.common.callback.Callback) ServiceUnavailableException(com.linkedin.d2.balancer.ServiceUnavailableException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) URI(java.net.URI)

Example 3 with TrackingBackupRequestsStrategy

use of com.linkedin.d2.backuprequests.TrackingBackupRequestsStrategy in project rest.li by linkedin.

the class BackupRequestsClient method requestAsync.

/**
 * Send rest request with backup request support asynchronously
 * This method will make the D2 property call in async manner
 */
private <R extends Request, T> void requestAsync(final R request, final RequestContext requestContext, DecoratorClient<R, T> client, final Callback<T> callback) {
    final String serviceName = LoadBalancerUtil.getServiceNameFromUri(request.getURI());
    final Object operationObject = requestContext.getLocalAttr(R2Constants.OPERATION);
    if (operationObject == null) {
        client.doRequest(request, requestContext, callback);
        return;
    }
    final String operation = operationObject.toString();
    Callback<Optional<TrackingBackupRequestsStrategy>> maybeStrategyCallback = new Callback<Optional<TrackingBackupRequestsStrategy>>() {

        @Override
        public void onError(Throwable e) {
            LOG.error("Error attempting to use backup requests, falling back to request without a backup", e);
            client.doRequest(request, requestContext, callback);
        }

        @Override
        public void onSuccess(Optional<TrackingBackupRequestsStrategy> maybeStrategy) {
            if (maybeStrategy.isPresent()) {
                Callback<T> decoratedCallback = decorateCallbackWithBackupRequest(request, requestContext, client, callback, maybeStrategy.get(), serviceName, operation);
                client.doRequest(request, requestContext, decoratedCallback);
            } else {
                client.doRequest(request, requestContext, callback);
            }
        }
    };
    getStrategyAsync(serviceName, operation, maybeStrategyCallback);
}
Also used : FutureCallback(com.linkedin.common.callback.FutureCallback) Callback(com.linkedin.common.callback.Callback) Optional(java.util.Optional) ByteString(com.linkedin.data.ByteString) TrackingBackupRequestsStrategy(com.linkedin.d2.backuprequests.TrackingBackupRequestsStrategy)

Example 4 with TrackingBackupRequestsStrategy

use of com.linkedin.d2.backuprequests.TrackingBackupRequestsStrategy in project rest.li by linkedin.

the class BackupRequestsClient method decorateCallbackSync.

private <R extends Request, T> Callback<T> decorateCallbackSync(R request, RequestContext requestContext, DecoratorClient<R, T> client, Callback<T> callback) {
    try {
        final String serviceName = LoadBalancerUtil.getServiceNameFromUri(request.getURI());
        final Object operationObject = requestContext.getLocalAttr(R2Constants.OPERATION);
        if (operationObject != null) {
            final String operation = operationObject.toString();
            final Optional<TrackingBackupRequestsStrategy> strategy = getStrategySync(serviceName, operation);
            if (strategy.isPresent()) {
                return decorateCallbackWithBackupRequest(request, requestContext, client, callback, strategy.get(), serviceName, operation);
            } else {
                // defined for this request
                return callback;
            }
        } else {
            // request context
            return callback;
        }
    } catch (Throwable t) {
        LOG.error("Error attempting to use backup requests, falling back to request without a backup", t);
        return callback;
    }
}
Also used : ByteString(com.linkedin.data.ByteString) TrackingBackupRequestsStrategy(com.linkedin.d2.backuprequests.TrackingBackupRequestsStrategy)

Example 5 with TrackingBackupRequestsStrategy

use of com.linkedin.d2.backuprequests.TrackingBackupRequestsStrategy in project rest.li by linkedin.

the class BackupRequestsClient method getStrategySync.

/**
 * Get backup request strategy after the D2 Zookeeper blocking call finishes
 * TODO: Remove this blocking call once the async path has been verified
 */
private Optional<TrackingBackupRequestsStrategy> getStrategySync(final String serviceName, final String operation) {
    try {
        ServiceProperties serviceProperties = _loadBalancer.getLoadBalancedServiceProperties(serviceName);
        updateServiceProperties(serviceName, serviceProperties);
    } catch (ServiceUnavailableException e) {
        LOG.debug("Failed to fetch backup requests strategy ", e);
    }
    return getStrategyAfterUpdate(serviceName, operation);
}
Also used : ServiceProperties(com.linkedin.d2.balancer.properties.ServiceProperties) ServiceUnavailableException(com.linkedin.d2.balancer.ServiceUnavailableException)

Aggregations

ByteString (com.linkedin.data.ByteString)4 TrackingBackupRequestsStrategy (com.linkedin.d2.backuprequests.TrackingBackupRequestsStrategy)3 Callback (com.linkedin.common.callback.Callback)2 FutureCallback (com.linkedin.common.callback.FutureCallback)2 ServiceUnavailableException (com.linkedin.d2.balancer.ServiceUnavailableException)2 URI (java.net.URI)2 BackupRequestsStrategy (com.linkedin.d2.backuprequests.BackupRequestsStrategy)1 BackupRequestsStrategyFromConfig (com.linkedin.d2.backuprequests.BackupRequestsStrategyFromConfig)1 TestTrackingBackupRequestsStrategy (com.linkedin.d2.backuprequests.TestTrackingBackupRequestsStrategy)1 LoadBalancer (com.linkedin.d2.balancer.LoadBalancer)1 StaticLoadBalancerState (com.linkedin.d2.balancer.StaticLoadBalancerState)1 PartitionData (com.linkedin.d2.balancer.properties.PartitionData)1 ServiceProperties (com.linkedin.d2.balancer.properties.ServiceProperties)1 SimpleLoadBalancer (com.linkedin.d2.balancer.simple.SimpleLoadBalancer)1 RequestContext (com.linkedin.r2.message.RequestContext)1 RestRequest (com.linkedin.r2.message.rest.RestRequest)1 RestResponseBuilder (com.linkedin.r2.message.rest.RestResponseBuilder)1 StreamRequest (com.linkedin.r2.message.stream.StreamRequest)1 StreamResponseBuilder (com.linkedin.r2.message.stream.StreamResponseBuilder)1 DrainReader (com.linkedin.r2.message.stream.entitystream.DrainReader)1