use of org.eclipse.microprofile.faulttolerance.exceptions.TimeoutException in project Payara by payara.
the class TimeoutInterceptor method timeout.
/**
* Proceeds the given invocation context with Timeout semantics.
* @param invocationContext The invocation context to proceed.
* @return The result of the invocation context.
* @throws Exception If the invocation context execution throws an exception
*/
private Object timeout(InvocationContext invocationContext) throws Exception {
Object proceededInvocationContext = null;
Timeout timeout = FaultToleranceCdiUtils.getAnnotation(beanManager, Timeout.class, invocationContext);
Config config = null;
try {
config = ConfigProvider.getConfig();
} catch (IllegalArgumentException ex) {
logger.log(Level.INFO, "No config could be found", ex);
}
long value = (Long) FaultToleranceCdiUtils.getOverrideValue(config, Timeout.class, "value", invocationContext, Long.class).orElse(timeout.value());
ChronoUnit unit = (ChronoUnit) FaultToleranceCdiUtils.getOverrideValue(config, Timeout.class, "unit", invocationContext, ChronoUnit.class).orElse(timeout.unit());
Future timeoutFuture = null;
ThreadLocal<Boolean> timedOut = new ThreadLocal<>();
timedOut.set(false);
long timeoutMillis = Duration.of(value, unit).toMillis();
long timeoutTime = System.currentTimeMillis() + timeoutMillis;
try {
timeoutFuture = startTimeout(timeoutMillis, timedOut);
proceededInvocationContext = invocationContext.proceed();
stopTimeout(timeoutFuture);
if (System.currentTimeMillis() > timeoutTime || timedOut.get()) {
logger.log(Level.FINE, "Execution timed out");
throw new TimeoutException();
}
} catch (Exception ex) {
stopTimeout(timeoutFuture);
throw ex;
}
return proceededInvocationContext;
}
use of org.eclipse.microprofile.faulttolerance.exceptions.TimeoutException in project Payara by payara.
the class FaultTolerancePolicy method processTimeoutStage.
/**
* Stage that takes care of the {@link TimeoutPolicy} handling.
*/
private Object processTimeoutStage(FaultToleranceInvocation invocation, AsyncFuture asyncAttempt) throws Exception {
if (!isTimeoutPresent()) {
return processBulkheadStage(invocation);
}
logger.log(Level.FINER, "Proceeding invocation with timeout semantics");
long timeoutDuration = Duration.of(timeout.value, timeout.unit).toMillis();
long timeoutTime = System.currentTimeMillis() + timeoutDuration;
Thread current = Thread.currentThread();
AtomicBoolean timedOut = new AtomicBoolean(false);
Future<?> timeout = invocation.context.runDelayed(timeoutDuration, () -> {
logger.log(Level.FINE, "Interrupting attempt due to timeout.");
timedOut.set(true);
current.interrupt();
invocation.metrics.incrementTimeoutCallsTimedOutTotal();
if (asyncAttempt != null) {
// we do this since interrupting not necessarily returns directly or ever but the attempt should timeout now
asyncAttempt.setExceptionThrown(true);
asyncAttempt.completeExceptionally(new TimeoutException());
}
});
long executionStartTime = System.nanoTime();
try {
Object resultValue = processBulkheadStage(invocation);
if (current.isInterrupted()) {
// clear the flag
Thread.interrupted();
}
if (timedOut.get() || System.currentTimeMillis() > timeoutTime) {
throw new TimeoutException();
}
invocation.metrics.incrementTimeoutCallsNotTimedOutTotal();
return resultValue;
} catch (TimeoutException ex) {
logger.log(Level.FINE, "Execution timed out.");
throw ex;
} catch (Exception | Error ex) {
if (timedOut.get() || System.currentTimeMillis() > timeoutTime) {
logger.log(Level.FINE, "Execution timed out.");
throw new TimeoutException(ex);
}
throw ex;
} finally {
invocation.metrics.addTimeoutExecutionDuration(System.nanoTime() - executionStartTime);
timeout.cancel(true);
}
}
use of org.eclipse.microprofile.faulttolerance.exceptions.TimeoutException in project wildfly-swarm by wildfly-swarm.
the class HystrixCommandInterceptor method interceptCommand.
@AroundInvoke
public Object interceptCommand(InvocationContext ic) throws Exception {
Method method = ic.getMethod();
ExecutionContextWithInvocationContext ctx = new ExecutionContextWithInvocationContext(ic);
boolean shouldRunCommand = true;
Object res = null;
LOGGER.tracef("FT operation intercepted: %s", method);
CommandMetadata metadata = commandMetadataMap.computeIfAbsent(method, CommandMetadata::new);
RetryContext retryContext = nonFallBackEnable && metadata.operation.hasRetry() ? new RetryContext(metadata.operation.getRetry()) : null;
SynchronousCircuitBreaker syncCircuitBreaker = null;
while (shouldRunCommand) {
shouldRunCommand = false;
if (nonFallBackEnable && syncCircuitBreakerEnabled && metadata.hasCircuitBreaker()) {
syncCircuitBreaker = getSynchronousCircuitBreaker(metadata.commandKey, metadata.operation.getCircuitBreaker());
}
Supplier<Object> fallback = null;
if (retryContext == null || retryContext.isLastAttempt()) {
fallback = metadata.getFallback(ctx);
}
DefaultCommand command = new DefaultCommand(metadata.setter, ctx, fallback);
try {
if (metadata.operation.isAsync()) {
LOGGER.debugf("Queue up command for async execution: %s", metadata.operation);
res = new AsyncFuture(command.queue());
} else {
LOGGER.debugf("Sync execution: %s]", metadata.operation);
res = command.execute();
}
if (syncCircuitBreaker != null) {
syncCircuitBreaker.executionSucceeded();
}
} catch (HystrixRuntimeException e) {
if (syncCircuitBreaker != null) {
syncCircuitBreaker.executionFailed();
}
HystrixRuntimeException.FailureType failureType = e.getFailureType();
LOGGER.tracef("Hystrix runtime failure [%s] when invoking %s", failureType, method);
switch(failureType) {
case TIMEOUT:
TimeoutException timeoutException = new TimeoutException(e);
if (retryContext != null && retryContext.shouldRetry()) {
shouldRunCommand = shouldRetry(retryContext, timeoutException);
if (shouldRunCommand) {
continue;
}
}
throw timeoutException;
case SHORTCIRCUIT:
throw new CircuitBreakerOpenException(method.getName());
case REJECTED_THREAD_EXECUTION:
case REJECTED_SEMAPHORE_EXECUTION:
case REJECTED_SEMAPHORE_FALLBACK:
BulkheadException bulkheadException = new BulkheadException(e);
if (retryContext != null && retryContext.shouldRetry()) {
shouldRunCommand = shouldRetry(retryContext, bulkheadException);
if (shouldRunCommand) {
continue;
}
}
throw bulkheadException;
case COMMAND_EXCEPTION:
if (retryContext != null && retryContext.shouldRetry()) {
shouldRunCommand = shouldRetry(retryContext, getCause(e));
continue;
}
default:
throw getCause(e);
}
}
}
return res;
}
Aggregations