This is an automated email from the ASF dual-hosted git repository.

daim pushed a commit to branch OAK-11917
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git

commit cb0568dee335412cee9f10cfcdf490b43990ceb8
Author: rishabhdaim <[email protected]>
AuthorDate: Tue Nov 25 08:10:19 2025 +0530

    OAK-11917 : added exiting scheduled executor service in oak-commons
---
 .../commons/internal/concurrent/ExecutorUtils.java | 11 +++++++++
 .../internal/concurrent/ExecutorUtilsTest.java     | 26 ++++++++++++++++++++++
 2 files changed, 37 insertions(+)

diff --git 
a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/internal/concurrent/ExecutorUtils.java
 
b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/internal/concurrent/ExecutorUtils.java
index 9abfde3393..1962c494a0 100644
--- 
a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/internal/concurrent/ExecutorUtils.java
+++ 
b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/internal/concurrent/ExecutorUtils.java
@@ -25,6 +25,8 @@ import 
org.apache.jackrabbit.guava.common.util.concurrent.ThreadFactoryBuilder;
 import org.apache.jackrabbit.oak.commons.concurrent.ExecutorCloser;
 
 import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 
@@ -53,6 +55,15 @@ public class ExecutorUtils {
 
     }
 
+    public static ScheduledExecutorService 
getExitingScheduledExecutorService(ScheduledThreadPoolExecutor executor) {
+        setDeamonThreadFactory(executor);
+        ScheduledExecutorService service = 
Executors.unconfigurableScheduledExecutorService(executor);
+        // JVM shutdown hook for graceful executor shutdown
+        addRuntimeShutdownHook(executor);
+        return service;
+
+    }
+
     private static void addRuntimeShutdownHook(final ExecutorService executor) 
{
         Runtime.getRuntime().addShutdownHook(
                 new Thread(() -> new ExecutorCloser(executor, 120, 
TimeUnit.SECONDS).close(),
diff --git 
a/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/internal/concurrent/ExecutorUtilsTest.java
 
b/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/internal/concurrent/ExecutorUtilsTest.java
index d7d55465a9..6ac440975f 100644
--- 
a/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/internal/concurrent/ExecutorUtilsTest.java
+++ 
b/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/internal/concurrent/ExecutorUtilsTest.java
@@ -25,6 +25,7 @@ import java.util.concurrent.Executor;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 
@@ -100,4 +101,29 @@ public class ExecutorUtilsTest {
         Assert.assertTrue(terminated || executor.isShutdown());
     }
 
+    @Test
+    public void 
testGetScheduledExitingExecutorServiceReturnsUnconfigurableExecutor() {
+        ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) 
Executors.newScheduledThreadPool(1);
+        ExecutorService service = 
ExecutorUtils.getExitingScheduledExecutorService(executor);
+        Assert.assertNotNull(service);
+        
Assert.assertFalse(service.getClass().getName().contains("ThreadPoolExecutor"));
+    }
+
+    @Test
+    public void testScheduledExecutorDaemonThreadFactoryIsSet() {
+        ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) 
Executors.newScheduledThreadPool(1);
+        ExecutorUtils.getExitingScheduledExecutorService(executor);
+        Assert.assertTrue(executor.getThreadFactory().newThread(() -> 
{}).isDaemon());
+    }
+
+    @Test
+    public void 
testScheduledExecutorShutdownHookIsRegisteredAndShutsDownExecutor() throws 
Exception {
+        ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) 
Executors.newScheduledThreadPool(1);
+        ExecutorUtils.getExitingScheduledExecutorService(executor);
+        // Simulate JVM shutdown hook
+        executor.shutdown();
+        boolean terminated = executor.awaitTermination(1, TimeUnit.SECONDS);
+        Assert.assertTrue(terminated || executor.isShutdown());
+    }
+
 }
\ No newline at end of file

Reply via email to