Search in sources :

Example 1 with RetryExecutor

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;
}
Also used : RestServiceException(com.github.ambry.rest.RestServiceException) Connection(java.sql.Connection) MySqlNamedBlobDbConfig(com.github.ambry.config.MySqlNamedBlobDbConfig) LoggerFactory(org.slf4j.LoggerFactory) AccountService(com.github.ambry.account.AccountService) CompletableFuture(java.util.concurrent.CompletableFuture) SQLIntegrityConstraintViolationException(java.sql.SQLIntegrityConstraintViolationException) Base64(org.apache.commons.codec.binary.Base64) ArrayList(java.util.ArrayList) RetryExecutor(com.github.ambry.commons.RetryExecutor) ResultSet(java.sql.ResultSet) Map(java.util.Map) DataSource(javax.sql.DataSource) ExecutorService(java.util.concurrent.ExecutorService) Container(com.github.ambry.account.Container) Logger(org.slf4j.Logger) Timestamp(java.sql.Timestamp) RestServiceErrorCode(com.github.ambry.rest.RestServiceErrorCode) DbEndpoint(com.github.ambry.mysql.MySqlUtils.DbEndpoint) Utils(com.github.ambry.utils.Utils) RetryPolicies(com.github.ambry.commons.RetryPolicies) Page(com.github.ambry.frontend.Page) PreparedStatement(java.sql.PreparedStatement) Collectors(java.util.stream.Collectors) MySqlUtils(com.github.ambry.mysql.MySqlUtils) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) RestServiceException(com.github.ambry.rest.RestServiceException) Closeable(java.io.Closeable) Account(com.github.ambry.account.Account) Callback(com.github.ambry.commons.Callback) Account(com.github.ambry.account.Account) CompletableFuture(java.util.concurrent.CompletableFuture) Container(com.github.ambry.account.Container)

Aggregations

Account (com.github.ambry.account.Account)1 AccountService (com.github.ambry.account.AccountService)1 Container (com.github.ambry.account.Container)1 Callback (com.github.ambry.commons.Callback)1 RetryExecutor (com.github.ambry.commons.RetryExecutor)1 RetryPolicies (com.github.ambry.commons.RetryPolicies)1 MySqlNamedBlobDbConfig (com.github.ambry.config.MySqlNamedBlobDbConfig)1 Page (com.github.ambry.frontend.Page)1 MySqlUtils (com.github.ambry.mysql.MySqlUtils)1 DbEndpoint (com.github.ambry.mysql.MySqlUtils.DbEndpoint)1 RestServiceErrorCode (com.github.ambry.rest.RestServiceErrorCode)1 RestServiceException (com.github.ambry.rest.RestServiceException)1 Utils (com.github.ambry.utils.Utils)1 Closeable (java.io.Closeable)1 Connection (java.sql.Connection)1 PreparedStatement (java.sql.PreparedStatement)1 ResultSet (java.sql.ResultSet)1 SQLIntegrityConstraintViolationException (java.sql.SQLIntegrityConstraintViolationException)1 Timestamp (java.sql.Timestamp)1 ArrayList (java.util.ArrayList)1