SLING-8997 - Make sure shutdown of ExponentialBackOff happens quickly
diff --git a/src/main/java/org/apache/sling/distribution/journal/impl/shared/ExponentialBackOff.java b/src/main/java/org/apache/sling/distribution/journal/impl/shared/ExponentialBackOff.java
index ea7cc28..1338ef4 100644
--- a/src/main/java/org/apache/sling/distribution/journal/impl/shared/ExponentialBackOff.java
+++ b/src/main/java/org/apache/sling/distribution/journal/impl/shared/ExponentialBackOff.java
@@ -25,6 +25,7 @@
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.slf4j.Logger;
@@ -63,7 +64,15 @@
 
     @Override
     public void close() {
+        log.info("Shutting down exponential backoff executor");
         this.executor.shutdown();
+        this.executor.shutdownNow();
+        try {
+            this.executor.awaitTermination(100, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+        }
+        log.info("Shutdown completed");
     }
     
     public void startChecks() {
diff --git a/src/test/java/org/apache/sling/distribution/journal/impl/shared/ExponentialBackoffTest.java b/src/test/java/org/apache/sling/distribution/journal/impl/shared/ExponentialBackoffTest.java
index a69aed6..55e4c01 100644
--- a/src/test/java/org/apache/sling/distribution/journal/impl/shared/ExponentialBackoffTest.java
+++ b/src/test/java/org/apache/sling/distribution/journal/impl/shared/ExponentialBackoffTest.java
@@ -23,6 +23,7 @@
 import static org.junit.Assert.assertThat;
 
 import java.time.Duration;
+import java.time.temporal.ChronoUnit;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
@@ -37,6 +38,7 @@
     private static final int RETRIES = 5;
     private static final Duration INITIAL_DELAY = Duration.of(64, MILLIS);
     private static final Duration MAX_DELAY = Duration.of(256, MILLIS);
+    private static final Duration LONG_DELAY = Duration.of(5, ChronoUnit.SECONDS);
     
     private Logger log = LoggerFactory.getLogger(this.getClass());
     
@@ -68,7 +70,17 @@
         assertThat("Should finish quickly as we called startChecks after enough delay", finished3, equalTo(true));
 
         backOff.close();
-        
+    }
+    
+    /**
+     * Even with a scheduled check the shutdown is expected to be 
+     * fast and to clean up its thread
+     */
+    @Test(timeout = 500)
+    public void testShutdown() throws Exception {
+        ExponentialBackOff backoff = new ExponentialBackOff(LONG_DELAY, LONG_DELAY, false, this::checkCallback);
+        backoff.startChecks();
+        backoff.close(); // We expect this to finish in less than the test timeout
     }
     
     private void checkCallback() {