Search in sources :

Example 1 with AsyncFuture

use of fish.payara.microprofile.faulttolerance.FaultToleranceMethodContext.AsyncFuture in project Payara by payara.

the class FaultTolerancePolicy method processRetryAsync.

private AsyncFuture processRetryAsync(FaultToleranceInvocation invocation) throws Exception {
    AsyncFuture asyncAttempt = new AsyncFuture();
    invocation.context.runAsynchronous(asyncAttempt, () -> invocation.runStageWithWorker(() -> processCircuitBreakerStage(invocation, asyncAttempt)));
    try {
        // wait and only proceed on success
        asyncAttempt.get();
        invocation.timeoutIfConcludedConcurrently();
        return asyncAttempt;
    } catch (ExecutionException ex) {
        // this ExecutionException is from calling get() above in case completed exceptionally
        if (!asyncAttempt.isExceptionThrown() && asynchronous.isSuccessWhenCompletedExceptionally()) {
            invocation.timeoutIfConcludedConcurrently();
            return asyncAttempt;
        }
        rethrow(ex.getCause());
        // not reachable
        return null;
    }
}
Also used : AsyncFuture(fish.payara.microprofile.faulttolerance.FaultToleranceMethodContext.AsyncFuture) ExecutionException(java.util.concurrent.ExecutionException)

Example 2 with AsyncFuture

use of fish.payara.microprofile.faulttolerance.FaultToleranceMethodContext.AsyncFuture in project Payara by payara.

the class FaultTolerancePolicy method processAsynchronousStage.

/**
 * Stage that takes care of the {@link AsynchronousPolicy} handling.
 */
private Object processAsynchronousStage(FaultToleranceMethodContext context, FaultToleranceMetrics metrics) throws Exception {
    if (!isAsynchronous()) {
        return processFallbackStage(new FaultToleranceInvocation(context, metrics, null, null));
    }
    logger.log(Level.FINER, "Proceeding invocation with asynchronous semantics");
    Set<Thread> workers = ConcurrentHashMap.newKeySet();
    AsyncFuture asyncResult = new AsyncFuture() {

        @Override
        public boolean cancel(boolean mayInterruptIfRunning) {
            boolean res = super.cancel(mayInterruptIfRunning);
            if (mayInterruptIfRunning) {
                logger.log(Level.FINE, "Asynchronous computation was cancelled by caller.");
                if (mayInterruptIfRunning) {
                    workers.forEach(worker -> worker.interrupt());
                }
            }
            return res;
        }
    };
    FaultToleranceInvocation invocation = new FaultToleranceInvocation(context, metrics, asyncResult, workers);
    context.runAsynchronous(asyncResult, () -> invocation.runStageWithWorker(() -> processFallbackStage(invocation)));
    return asyncResult;
}
Also used : AsyncFuture(fish.payara.microprofile.faulttolerance.FaultToleranceMethodContext.AsyncFuture)

Example 3 with AsyncFuture

use of fish.payara.microprofile.faulttolerance.FaultToleranceMethodContext.AsyncFuture in project Payara by payara.

the class FaultTolerancePolicy method proceed.

/**
 * Wraps {@link InvocationContext#proceed()} with fault tolerance behaviour.
 *
 * Processing has 6 stages:
 * <pre>
 * 1) Asynchronous
 * 2) Fallback
 * 3) Retry
 * 4) Circuit Breaker
 * 5) Timeout
 * 6) Bulkhead
 * </pre>
 * The call chain goes from 1) down to 6) skipping stages that are not requested by this policy.
 *
 * Asynchronous execution branches to new threads in stage 1) and 3) each executed by the
 * {@link FaultToleranceService#runAsynchronous(CompletableFuture, Callable)}.
 *
 * @param context intercepted call context
 * @param ftmContextSupplier the environment used to execute the FT behaviour
 * @return the result of {@link InvocationContext#proceed()} after applying FT behaviour
 * @throws Exception as thrown by the wrapped invocation or a {@link FaultToleranceException}
 */
public Object proceed(InvocationContext context, Supplier<FaultToleranceMethodContext> ftmContextSupplier) throws Exception {
    if (!isPresent) {
        logger.log(Level.FINER, "Fault Tolerance not enabled, proceeding normally.");
        return context.proceed();
    }
    FaultToleranceMethodContext ftmContext = ftmContextSupplier.get();
    FaultToleranceMetrics metrics = ftmContext.getMetrics().boundTo(ftmContext, this);
    try {
        Object res = processAsynchronousStage(ftmContext, metrics);
        if (res instanceof AsyncFuture) {
            AsyncFuture async = (AsyncFuture) res;
            async.whenComplete((value, ex) -> {
                // first evaluate async when the results are in...
                if (isExceptionThrown(async)) {
                    metrics.incrementInvocationsExceptionThrown();
                } else {
                    metrics.incrementInvocationsValueReturned();
                }
            });
        } else {
            metrics.incrementInvocationsValueReturned();
        }
        return res;
    } catch (Exception | Error ex) {
        metrics.incrementInvocationsExceptionThrown();
        throw ex;
    }
}
Also used : FaultToleranceMetrics(fish.payara.microprofile.faulttolerance.FaultToleranceMetrics) AsyncFuture(fish.payara.microprofile.faulttolerance.FaultToleranceMethodContext.AsyncFuture) FaultToleranceMethodContext(fish.payara.microprofile.faulttolerance.FaultToleranceMethodContext) FaultToleranceException(org.eclipse.microprofile.faulttolerance.exceptions.FaultToleranceException) TimeoutException(org.eclipse.microprofile.faulttolerance.exceptions.TimeoutException) CircuitBreakerOpenException(org.eclipse.microprofile.faulttolerance.exceptions.CircuitBreakerOpenException) ExecutionException(java.util.concurrent.ExecutionException) BulkheadException(org.eclipse.microprofile.faulttolerance.exceptions.BulkheadException) FaultToleranceDefinitionException(org.eclipse.microprofile.faulttolerance.exceptions.FaultToleranceDefinitionException)

Aggregations

AsyncFuture (fish.payara.microprofile.faulttolerance.FaultToleranceMethodContext.AsyncFuture)3 ExecutionException (java.util.concurrent.ExecutionException)2 FaultToleranceMethodContext (fish.payara.microprofile.faulttolerance.FaultToleranceMethodContext)1 FaultToleranceMetrics (fish.payara.microprofile.faulttolerance.FaultToleranceMetrics)1 BulkheadException (org.eclipse.microprofile.faulttolerance.exceptions.BulkheadException)1 CircuitBreakerOpenException (org.eclipse.microprofile.faulttolerance.exceptions.CircuitBreakerOpenException)1 FaultToleranceDefinitionException (org.eclipse.microprofile.faulttolerance.exceptions.FaultToleranceDefinitionException)1 FaultToleranceException (org.eclipse.microprofile.faulttolerance.exceptions.FaultToleranceException)1 TimeoutException (org.eclipse.microprofile.faulttolerance.exceptions.TimeoutException)1