public T execute()

in src/main/java/software/amazon/qldb/QldbDriverImpl.java [132:195]


    public <T> T execute(Executor<T> executor, RetryPolicy retryPolicy) {
        Validate.paramNotNull(executor, "executor");
        Validate.notNull(retryPolicy, "retryPolicy");
        if (isClosed.get()) {
            logger.error(Errors.DRIVER_CLOSED.get());
            throw QldbDriverException.create(Errors.DRIVER_CLOSED.get());
        }

        boolean replaceDeadSession = false;
        int retryAttempt = 0;
        while (true) {
            QldbSession session = null;
            try {
                if (replaceDeadSession) {
                    session = this.createNewSession();
                } else {
                    session = this.getSession();
                }
                T returnedValue = session.execute(executor);
                this.releaseSession(session);
                return returnedValue;
            } catch (ExecuteException ee) {
                retryAttempt++;
                // If initial session is invalid, always retry once with a new session.
                if (ee.isRetryable() && ee.isInvalidSessionException() && retryAttempt == 1) {
                    logger.debug("Initial session received from pool invalid. Retrying...");
                    replaceDeadSession = true;
                    continue;
                }
                // Do not retry.
                if (!ee.isRetryable() || retryAttempt > retryPolicy.maxRetries()) {
                    if (ee.isSessionAlive() && session != null) {
                        this.releaseSession(session);
                    } else {
                        this.poolPermits.release();
                    }
                    throw ee.getCause();
                }
                // Retry.
                logger.info("A recoverable error has occurred. Attempting retry #{}.", retryAttempt);
                logger.debug("Errored Transaction ID: {}. Error cause: ", ee.getTransactionId(), ee.getCause());
                replaceDeadSession = !ee.isSessionAlive();
                if (replaceDeadSession) {
                    logger.debug("Replacing invalid session...");
                } else {
                    logger.debug("Retrying with a different session...");
                    this.releaseSession(session);
                }

                try {
                    // This can be safely casted since only SdkExceptions or child Exceptions are deemed retryable.
                    final SdkException se = (SdkException) ee.getCause();
                    final RetryPolicyContext context = new RetryPolicyContext(se, retryAttempt, ee.getTransactionId());
                    retrySleep(context, retryPolicy);
                } catch (Exception e) {
                    if (replaceDeadSession) {
                        // Safeguard against semaphore leak if parameter actions throw exceptions.
                        this.poolPermits.release();
                    }
                    throw e;
                }
            }
        }
    }