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>