You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by jo...@apache.org on 2017/10/08 16:00:01 UTC
geronimo-safeguard git commit: GERONIMO-6585 - Implement the
combination of timeout + retry + circuitbreaker.
Repository: geronimo-safeguard
Updated Branches:
refs/heads/master 0f811c373 -> b70e077a2
GERONIMO-6585 - Implement the combination of timeout + retry + circuitbreaker.
Project: http://git-wip-us.apache.org/repos/asf/geronimo-safeguard/repo
Commit: http://git-wip-us.apache.org/repos/asf/geronimo-safeguard/commit/b70e077a
Tree: http://git-wip-us.apache.org/repos/asf/geronimo-safeguard/tree/b70e077a
Diff: http://git-wip-us.apache.org/repos/asf/geronimo-safeguard/diff/b70e077a
Branch: refs/heads/master
Commit: b70e077a274be5c426e41bfdb94509dc9911ef55
Parents: 0f811c3
Author: John D. Ament <jo...@apache.org>
Authored: Sun Oct 8 11:59:56 2017 -0400
Committer: John D. Ament <jo...@apache.org>
Committed: Sun Oct 8 11:59:56 2017 -0400
----------------------------------------------------------------------
.../AsyncFailsafeExecutionPlan.java | 3 +-
.../MicroprofileAnnotationMapper.java | 4 +-
.../SyncFailsafeExecutionPlan.java | 5 +-
.../executionPlans/TimeoutWrappedCallable.java | 54 +++++++++++++++++---
safeguard-tck-tests/pom.xml | 1 -
5 files changed, 53 insertions(+), 14 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/geronimo-safeguard/blob/b70e077a/safeguard-impl/src/main/java/org/apache/safeguard/impl/executionPlans/AsyncFailsafeExecutionPlan.java
----------------------------------------------------------------------
diff --git a/safeguard-impl/src/main/java/org/apache/safeguard/impl/executionPlans/AsyncFailsafeExecutionPlan.java b/safeguard-impl/src/main/java/org/apache/safeguard/impl/executionPlans/AsyncFailsafeExecutionPlan.java
index 6ee1309..3265448 100644
--- a/safeguard-impl/src/main/java/org/apache/safeguard/impl/executionPlans/AsyncFailsafeExecutionPlan.java
+++ b/safeguard-impl/src/main/java/org/apache/safeguard/impl/executionPlans/AsyncFailsafeExecutionPlan.java
@@ -53,7 +53,8 @@ public class AsyncFailsafeExecutionPlan extends SyncFailsafeExecutionPlan {
return asyncFailsafe.get(callable).get();
} else {
return asyncFailsafe
- .get(new TimeoutWrappedCallable<>(callable, executorService, timeout))
+ .get(new TimeoutWrappedCallable<>(callable, executorService, timeout,
+ super.failsafeCircuitBreaker))
.get();
}
} catch (CircuitBreakerOpenException e) {
http://git-wip-us.apache.org/repos/asf/geronimo-safeguard/blob/b70e077a/safeguard-impl/src/main/java/org/apache/safeguard/impl/executionPlans/MicroprofileAnnotationMapper.java
----------------------------------------------------------------------
diff --git a/safeguard-impl/src/main/java/org/apache/safeguard/impl/executionPlans/MicroprofileAnnotationMapper.java b/safeguard-impl/src/main/java/org/apache/safeguard/impl/executionPlans/MicroprofileAnnotationMapper.java
index ee2b3e6..e898875 100644
--- a/safeguard-impl/src/main/java/org/apache/safeguard/impl/executionPlans/MicroprofileAnnotationMapper.java
+++ b/safeguard-impl/src/main/java/org/apache/safeguard/impl/executionPlans/MicroprofileAnnotationMapper.java
@@ -33,7 +33,7 @@ class MicroprofileAnnotationMapper {
static FailsafeRetryDefinition mapRetry(Retry retry, FailsafeRetryBuilder retryBuilder) {
retryBuilder.withMaxRetries(retry.maxRetries())
.withRetryOn(retry.retryOn())
- .withRetryOn(TimeoutException.class)
+ .withRetryOn(TimeoutException.class, org.eclipse.microprofile.faulttolerance.exceptions.TimeoutException.class)
.withAbortOn(retry.abortOn());
if (retry.delay() > 0L) {
retryBuilder.withDelay(Duration.of(retry.delay(), retry.delayUnit()));
@@ -52,7 +52,7 @@ class MicroprofileAnnotationMapper {
int failureCount = (int) (circuitBreaker.failureRatio() * circuitBreaker.requestVolumeThreshold());
FailsafeCircuitBreakerBuilder failsafeCircuitBreakerBuilder = builder
.withFailOn(circuitBreaker.failOn())
- .withFailOn(TimeoutException.class)
+ .withFailOn(TimeoutException.class, org.eclipse.microprofile.faulttolerance.exceptions.TimeoutException.class)
.withDelay(Duration.of(circuitBreaker.delay(), circuitBreaker.delayUnit()))
.withSuccessCount(circuitBreaker.successThreshold());
if (failureCount > 0) {
http://git-wip-us.apache.org/repos/asf/geronimo-safeguard/blob/b70e077a/safeguard-impl/src/main/java/org/apache/safeguard/impl/executionPlans/SyncFailsafeExecutionPlan.java
----------------------------------------------------------------------
diff --git a/safeguard-impl/src/main/java/org/apache/safeguard/impl/executionPlans/SyncFailsafeExecutionPlan.java b/safeguard-impl/src/main/java/org/apache/safeguard/impl/executionPlans/SyncFailsafeExecutionPlan.java
index f4fe8ee..0eec4ad 100644
--- a/safeguard-impl/src/main/java/org/apache/safeguard/impl/executionPlans/SyncFailsafeExecutionPlan.java
+++ b/safeguard-impl/src/main/java/org/apache/safeguard/impl/executionPlans/SyncFailsafeExecutionPlan.java
@@ -28,11 +28,10 @@ import org.apache.safeguard.impl.retry.FailsafeRetryDefinition;
import javax.interceptor.InvocationContext;
import java.util.concurrent.Callable;
-import java.util.function.Function;
public class SyncFailsafeExecutionPlan implements ExecutionPlan {
- private final FailsafeRetryDefinition retryDefinition;
- private final FailsafeCircuitBreaker failsafeCircuitBreaker;
+ protected final FailsafeRetryDefinition retryDefinition;
+ protected final FailsafeCircuitBreaker failsafeCircuitBreaker;
private final FallbackRunner fallback;
SyncFailsafeExecutionPlan(FailsafeRetryDefinition retryDefinition, FailsafeCircuitBreaker failsafeCircuitBreaker, FallbackRunner fallback) {
http://git-wip-us.apache.org/repos/asf/geronimo-safeguard/blob/b70e077a/safeguard-impl/src/main/java/org/apache/safeguard/impl/executionPlans/TimeoutWrappedCallable.java
----------------------------------------------------------------------
diff --git a/safeguard-impl/src/main/java/org/apache/safeguard/impl/executionPlans/TimeoutWrappedCallable.java b/safeguard-impl/src/main/java/org/apache/safeguard/impl/executionPlans/TimeoutWrappedCallable.java
index 8013a42..cf80558 100644
--- a/safeguard-impl/src/main/java/org/apache/safeguard/impl/executionPlans/TimeoutWrappedCallable.java
+++ b/safeguard-impl/src/main/java/org/apache/safeguard/impl/executionPlans/TimeoutWrappedCallable.java
@@ -19,30 +19,70 @@
package org.apache.safeguard.impl.executionPlans;
+import org.apache.safeguard.api.circuitbreaker.CircuitBreakerState;
+import org.apache.safeguard.impl.circuitbreaker.FailsafeCircuitBreaker;
+import org.eclipse.microprofile.faulttolerance.exceptions.CircuitBreakerOpenException;
+import org.eclipse.microprofile.faulttolerance.exceptions.TimeoutException;
+
import java.time.Duration;
import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
class TimeoutWrappedCallable<T> implements Callable<T> {
private final Callable<T> delegate;
- private final ExecutorService executorService;
+ private final ScheduledExecutorService executorService;
private final Duration timeout;
+ private final FailsafeCircuitBreaker failsafeCircuitBreaker;
+ private boolean timedout = false;
- TimeoutWrappedCallable(Callable<T> delegate, ExecutorService executorService, Duration timeout) {
+ TimeoutWrappedCallable(Callable<T> delegate, ScheduledExecutorService executorService, Duration timeout, FailsafeCircuitBreaker failsafeCircuitBreaker) {
this.delegate = delegate;
this.executorService = executorService;
this.timeout = timeout;
+ this.failsafeCircuitBreaker = failsafeCircuitBreaker;
}
@Override
public T call() throws Exception {
+ boolean circuitBreakerOpen = failsafeCircuitBreaker != null && failsafeCircuitBreaker.getState() == CircuitBreakerState.OPEN;
+ if(circuitBreakerOpen) {
+ throw new CircuitBreakerOpenException();
+ }
+ ScheduledFuture<?> scheduledFuture = executorService.schedule(new TimerRunnable(Thread.currentThread(), this),
+ timeout.toMillis(), TimeUnit.MILLISECONDS);
+
+ T result;
try {
- return executorService.submit(delegate).get(timeout.toMillis(), TimeUnit.MILLISECONDS);
+ result = delegate.call();
+ } catch (Exception e) {
+ throw e;
+ } finally {
+ scheduledFuture.cancel(true);
}
- catch (TimeoutException e) {
- throw new org.eclipse.microprofile.faulttolerance.exceptions.TimeoutException(e);
+ if(timedout) {
+ throw new TimeoutException("Execution timed out after " + timeout);
+ }
+ return result;
+ }
+
+ private class TimerRunnable implements Runnable {
+ private final Thread targetThread;
+ private final TimeoutWrappedCallable task;
+
+ private boolean doInterrupt = true;
+ private TimerRunnable(Thread targetThread, TimeoutWrappedCallable task) {
+ this.targetThread = targetThread;
+ this.task = task;
+ }
+
+ @Override
+ public void run() {
+ if(doInterrupt) {
+ task.timedout = true;
+ targetThread.interrupt();
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/geronimo-safeguard/blob/b70e077a/safeguard-tck-tests/pom.xml
----------------------------------------------------------------------
diff --git a/safeguard-tck-tests/pom.xml b/safeguard-tck-tests/pom.xml
index bdff948..5479be5 100644
--- a/safeguard-tck-tests/pom.xml
+++ b/safeguard-tck-tests/pom.xml
@@ -67,7 +67,6 @@
<dependency>org.eclipse.microprofile.fault-tolerance:microprofile-fault-tolerance-tck</dependency>
</dependenciesToScan>
<excludes>
- <exclude>org.eclipse.microprofile.fault.tolerance.tck.CircuitBreakerRetryTest</exclude>
<exclude>org.eclipse.microprofile.fault.tolerance.tck.ConfigTest</exclude>
<exclude>org.eclipse.microprofile.fault.tolerance.tck.bulkhead.BulkheadAsynchRetryTest</exclude>
<exclude>org.eclipse.microprofile.fault.tolerance.tck.bulkhead.BulkheadAsynchTest</exclude>