use of com.github.ambry.commons.RetryExecutor in project ambry by linkedin.
the class MySqlNamedBlobDb method executeTransactionAsync.
/**
* Run a transaction on a thread pool and handle common logic surrounding looking up account metadata and error
* handling. Eventually this will handle retries.
* @param <T> the return type of the {@link Transaction}.
* @param accountName the account name for the transaction.
* @param containerName the container name for the transaction.
* @param autoCommit true if each statement execution should be its own transaction. If set to false, this helper will
* handle calling commit/rollback.
* @param transaction the {@link Transaction} to run. This can either be a read only query or include DML.
* @param transactionStateTracker the {@link TransactionStateTracker} to describe the retry strategy.
* @return a {@link CompletableFuture} that will eventually contain the result of the transaction or an exception.
*/
private <T> CompletableFuture<T> executeTransactionAsync(String accountName, String containerName, boolean autoCommit, Transaction<T> transaction, TransactionStateTracker transactionStateTracker) {
CompletableFuture<T> future = new CompletableFuture<>();
// Look up account and container IDs. This is common logic needed for all types of transactions.
Account account = accountService.getAccountByName(accountName);
if (account == null) {
future.completeExceptionally(new RestServiceException("Account not found: " + accountName, RestServiceErrorCode.NotFound));
return future;
}
Container container = account.getContainerByName(containerName);
if (container == null) {
future.completeExceptionally(new RestServiceException("Container not found: " + containerName, RestServiceErrorCode.NotFound));
return future;
}
Callback<T> finalCallback = (result, exception) -> {
if (exception != null) {
future.completeExceptionally(exception);
} else {
future.complete(result);
}
};
// TODO consider introducing CompletableFuture support in RetryExecutor so that we can use only futures, no callback
if (transactionStateTracker != null) {
retryExecutor.runWithRetries(RetryPolicies.fixedBackoffPolicy(transactionExecutors.size(), 0), callback -> {
String datacenter = transactionStateTracker.getNextDatacenter();
transactionExecutors.get(datacenter).executeTransaction(container, autoCommit, transaction, callback);
}, transactionStateTracker::processFailure, finalCallback);
} else {
transactionExecutors.get(localDatacenter).executeTransaction(container, autoCommit, transaction, finalCallback);
}
return future;
}
Aggregations