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();
}
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);
}
};
}
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);
}
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;
}
}
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);
}
Aggregations