From 40a074d729d026b76e10c209a28a487644949e4e Mon Sep 17 00:00:00 2001
From: Santiago Pericasgeertsen
Date: Wed, 20 May 2020 15:27:11 -0400
Subject: [PATCH 1/3] Wait for a thread to complete only if its interrupted
flag has been set and it is still running. Some new tests.
Signed-off-by: Santiago Pericasgeertsen
---
.../faulttolerance/FaultToleranceCommand.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/microprofile/fault-tolerance/src/main/java/io/helidon/microprofile/faulttolerance/FaultToleranceCommand.java b/microprofile/fault-tolerance/src/main/java/io/helidon/microprofile/faulttolerance/FaultToleranceCommand.java
index 56d716c3f16..05465b33d58 100644
--- a/microprofile/fault-tolerance/src/main/java/io/helidon/microprofile/faulttolerance/FaultToleranceCommand.java
+++ b/microprofile/fault-tolerance/src/main/java/io/helidon/microprofile/faulttolerance/FaultToleranceCommand.java
@@ -450,17 +450,17 @@ private void logCircuitBreakerState(String preamble) {
/**
* After a timeout expires, Hystrix can report an {@link ExecutionException}
- * while a thread is still running and cannot be interrupted (e.g. busy
- * loop). Hystrix makes this possible by using another thread to monitor
+ * when a thread has been interrupted but it is still running (e.g. while in a
+ * busy loop). Hystrix makes this possible by using another thread to monitor
* the command's thread.
*
* According to the FT spec, the thread may continue to run, so here
* we give it a chance to do that before completing the execution of the
* command. For more information see TCK test {@code
- * TimeoutUninterruptableTest::timeoutTest}.
+ * TimeoutUninterruptableTest::testTimeout}.
*/
private void waitForThreadToComplete() {
- if (!introspector.isAsynchronous() && runThread != null) {
+ if (!introspector.isAsynchronous() && runThread != null && runThread.isInterrupted()) {
try {
int waitTime = 250;
while (runThread.getState() == Thread.State.RUNNABLE && waitTime <= threadWaitingPeriod) {
From 0b2c7cd72ff38f80fab14359108e4bdfd981c3f9 Mon Sep 17 00:00:00 2001
From: Santiago Pericasgeertsen
Date: Wed, 20 May 2020 15:27:11 -0400
Subject: [PATCH 2/3] Wait for a thread to complete only if its interrupted
flag has been set and it is still running. Some new tests.
Signed-off-by: Santiago Pericasgeertsen
---
.../faulttolerance/TimeoutNoRetryBean.java | 47 +++++++++++++++++++
.../faulttolerance/TimeoutTest.java | 33 +++++++++++--
2 files changed, 75 insertions(+), 5 deletions(-)
create mode 100644 microprofile/fault-tolerance/src/test/java/io/helidon/microprofile/faulttolerance/TimeoutNoRetryBean.java
diff --git a/microprofile/fault-tolerance/src/test/java/io/helidon/microprofile/faulttolerance/TimeoutNoRetryBean.java b/microprofile/fault-tolerance/src/test/java/io/helidon/microprofile/faulttolerance/TimeoutNoRetryBean.java
new file mode 100644
index 00000000000..a671e7c4c36
--- /dev/null
+++ b/microprofile/fault-tolerance/src/test/java/io/helidon/microprofile/faulttolerance/TimeoutNoRetryBean.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.helidon.microprofile.faulttolerance;
+
+import java.time.temporal.ChronoUnit;
+import javax.enterprise.context.Dependent;
+
+import org.eclipse.microprofile.faulttolerance.Timeout;
+import org.eclipse.microprofile.faulttolerance.exceptions.TimeoutException;
+
+/**
+ * Class TimeoutNoRetryBean.
+ */
+@Dependent
+public class TimeoutNoRetryBean {
+
+ @Timeout(value=1000, unit=ChronoUnit.MILLIS)
+ public String forceTimeoutSleep() throws InterruptedException, TimeoutException {
+ FaultToleranceTest.printStatus("TimeoutNoRetryBean::forceTimeout()", "failure");
+ Thread.sleep(2000);
+ return "failure";
+ }
+
+ @Timeout(value=1000, unit=ChronoUnit.MILLIS)
+ public String forceTimeoutLoop() throws TimeoutException {
+ FaultToleranceTest.printStatus("TimeoutNoRetryBean::forceTimeoutLoop()", "failure");
+ long start = System.currentTimeMillis();
+ while (System.currentTimeMillis() - start < 2000) {
+ // busy loop
+ }
+ return "success";
+ }
+}
diff --git a/microprofile/fault-tolerance/src/test/java/io/helidon/microprofile/faulttolerance/TimeoutTest.java b/microprofile/fault-tolerance/src/test/java/io/helidon/microprofile/faulttolerance/TimeoutTest.java
index ab584d78a45..ea1cf2eab8e 100644
--- a/microprofile/fault-tolerance/src/test/java/io/helidon/microprofile/faulttolerance/TimeoutTest.java
+++ b/microprofile/fault-tolerance/src/test/java/io/helidon/microprofile/faulttolerance/TimeoutTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,10 +17,13 @@
package io.helidon.microprofile.faulttolerance;
import org.eclipse.microprofile.faulttolerance.exceptions.TimeoutException;
+
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.greaterThan;
+import static org.hamcrest.Matchers.lessThan;
import static org.junit.jupiter.api.Assertions.assertThrows;
/**
@@ -29,11 +32,9 @@
public class TimeoutTest extends FaultToleranceTest {
@Test
- public void testForceTimeout() throws Exception {
+ public void testForceTimeout() {
TimeoutBean bean = newBean(TimeoutBean.class);
- assertThrows(TimeoutException.class, () -> {
- bean.forceTimeout();
- });
+ assertThrows(TimeoutException.class, bean::forceTimeout);
}
@Test
@@ -59,4 +60,26 @@ public void testTimeoutWithRetriesAndFallback() throws Exception {
TimeoutBean bean = newBean(TimeoutBean.class);
assertThat(bean.timeoutWithRetriesAndFallback(), is("fallback"));
}
+
+ @Test
+ public void testForceTimeoutSleep() {
+ TimeoutNoRetryBean bean = newBean(TimeoutNoRetryBean.class);
+ long start = System.currentTimeMillis();
+ try {
+ bean.forceTimeoutSleep(); // can interrupt
+ } catch (InterruptedException | TimeoutException e) {
+ assertThat(System.currentTimeMillis() - start, is(lessThan(2000L)));
+ }
+ }
+
+ @Test
+ public void testForceTimeoutLoop() {
+ TimeoutNoRetryBean bean = newBean(TimeoutNoRetryBean.class);
+ long start = System.currentTimeMillis();
+ try {
+ bean.forceTimeoutLoop(); // cannot interrupt
+ } catch (TimeoutException e) {
+ assertThat(System.currentTimeMillis() - start, is(greaterThan(2000L)));
+ }
+ }
}
From 29ca7611e52c5b3ba1e841821758b0979c2ffac2 Mon Sep 17 00:00:00 2001
From: Santiago Pericasgeertsen
Date: Thu, 21 May 2020 08:53:52 -0400
Subject: [PATCH 3/3] Updated copyright header.
Signed-off-by: Santiago Pericasgeertsen
---
.../helidon/microprofile/faulttolerance/TimeoutNoRetryBean.java | 2 +-
.../io/helidon/microprofile/faulttolerance/TimeoutTest.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/microprofile/fault-tolerance/src/test/java/io/helidon/microprofile/faulttolerance/TimeoutNoRetryBean.java b/microprofile/fault-tolerance/src/test/java/io/helidon/microprofile/faulttolerance/TimeoutNoRetryBean.java
index a671e7c4c36..ffbc03c9e0a 100644
--- a/microprofile/fault-tolerance/src/test/java/io/helidon/microprofile/faulttolerance/TimeoutNoRetryBean.java
+++ b/microprofile/fault-tolerance/src/test/java/io/helidon/microprofile/faulttolerance/TimeoutNoRetryBean.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/microprofile/fault-tolerance/src/test/java/io/helidon/microprofile/faulttolerance/TimeoutTest.java b/microprofile/fault-tolerance/src/test/java/io/helidon/microprofile/faulttolerance/TimeoutTest.java
index ea1cf2eab8e..4d289c058eb 100644
--- a/microprofile/fault-tolerance/src/test/java/io/helidon/microprofile/faulttolerance/TimeoutTest.java
+++ b/microprofile/fault-tolerance/src/test/java/io/helidon/microprofile/faulttolerance/TimeoutTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.