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

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


The following commit(s) were added to refs/heads/trunk by this push:
     new 2c9dc7a84b OAK-11916 : added exiting executor service in oak-commons 
(#2622)
2c9dc7a84b is described below

commit 2c9dc7a84ba6564b636bd81888d3a6bf44ccdeb9
Author: Rishabh Kumar <[email protected]>
AuthorDate: Mon Nov 24 20:57:59 2025 +0530

    OAK-11916 : added exiting executor service in oak-commons (#2622)
    
    * OAK-11916 : added exiting executor service in oak-commons
    
    * OAK-11916 : updated package version
    
    * OAK-11916 : fixed failing issues due to wrong guava import
---
 .../commons/internal/concurrent/ExecutorUtils.java | 30 ++++++++++++++++++++++
 .../commons/internal/concurrent/package-info.java  |  2 +-
 .../internal/concurrent/ExecutorUtilsTest.java     | 28 ++++++++++++++++++++
 3 files changed, 59 insertions(+), 1 deletion(-)

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 4ef9de91e1..9abfde3393 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
@@ -21,6 +21,13 @@ package 
org.apache.jackrabbit.oak.commons.internal.concurrent;
 import java.util.concurrent.Executor;
 import java.util.concurrent.ExecutorService;
 
+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.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
 /**
  * Util methods for {@link java.util.concurrent.Executor}
  */
@@ -36,4 +43,27 @@ public class ExecutorUtils {
     public static ExecutorService newDirectExecutorService() {
         return new DirectExecutorService();
     }
+
+    public static ExecutorService getExitingExecutorService(ThreadPoolExecutor 
executor) {
+        setDeamonThreadFactory(executor);
+        final ExecutorService service = 
Executors.unconfigurableExecutorService(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(),
+                "RuntimeShutdownHook-for-" + executor));
+    }
+
+    private static void setDeamonThreadFactory(final ThreadPoolExecutor 
executor) {
+        executor.setThreadFactory(
+                new ThreadFactoryBuilder()
+                        .setDaemon(true)
+                        .setThreadFactory(executor.getThreadFactory())
+                        .build());
+    }
 }
diff --git 
a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/internal/concurrent/package-info.java
 
b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/internal/concurrent/package-info.java
index 1d60571596..26de19423a 100644
--- 
a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/internal/concurrent/package-info.java
+++ 
b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/internal/concurrent/package-info.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("1.1.0")
+@Version("1.2.0")
 @Internal(since = "1.0.0")
 package org.apache.jackrabbit.oak.commons.internal.concurrent;
 
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 20b9c81b83..d7d55465a9 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
@@ -23,7 +23,10 @@ import org.junit.Test;
 
 import java.util.concurrent.Executor;
 import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Unit cases for ExecutorUtils
@@ -72,4 +75,29 @@ public class ExecutorUtilsTest {
         Assert.assertEquals("test", future.get());
     }
 
+    @Test
+    public void testGetExitingExecutorServiceReturnsUnconfigurableExecutor() {
+        ThreadPoolExecutor executor = (ThreadPoolExecutor) 
Executors.newFixedThreadPool(1);
+        ExecutorService service = 
ExecutorUtils.getExitingExecutorService(executor);
+        Assert.assertNotNull(service);
+        
Assert.assertFalse(service.getClass().getName().contains("ThreadPoolExecutor"));
+    }
+
+    @Test
+    public void testDaemonThreadFactoryIsSet() {
+        ThreadPoolExecutor executor = (ThreadPoolExecutor) 
Executors.newFixedThreadPool(1);
+        ExecutorUtils.getExitingExecutorService(executor);
+        Assert.assertTrue(executor.getThreadFactory().newThread(() -> 
{}).isDaemon());
+    }
+
+    @Test
+    public void testShutdownHookIsRegisteredAndShutsDownExecutor() throws 
Exception {
+        ThreadPoolExecutor executor = (ThreadPoolExecutor) 
Executors.newFixedThreadPool(1);
+        ExecutorUtils.getExitingExecutorService(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