@@ -469,6 +469,10 @@ private void validateSetting(Settings tpSettings) {
469469 }
470470 Settings tpGroup = entry .getValue ();
471471 ExecutorHolder holder = executors .get (tpName );
472+ // Skip validation for ForkJoinPool type since it does not support these settings
473+ if (holder .info .type == ThreadPoolType .FORK_JOIN ) {
474+ continue ;
475+ }
472476 assert holder .executor instanceof OpenSearchThreadPoolExecutor ;
473477 OpenSearchThreadPoolExecutor threadPoolExecutor = (OpenSearchThreadPoolExecutor ) holder .executor ;
474478 if (holder .info .type == ThreadPoolType .SCALING ) {
@@ -504,6 +508,9 @@ public void setThreadPool(Settings tpSettings) {
504508 String tpName = entry .getKey ();
505509 Settings tpGroup = entry .getValue ();
506510 ExecutorHolder holder = executors .get (tpName );
511+ if (holder .info .type == ThreadPoolType .FORK_JOIN ) {
512+ continue ;
513+ }
507514 assert holder .executor instanceof OpenSearchThreadPoolExecutor ;
508515 OpenSearchThreadPoolExecutor executor = (OpenSearchThreadPoolExecutor ) holder .executor ;
509516 if (holder .info .type == ThreadPoolType .SCALING ) {
@@ -543,6 +550,11 @@ public ThreadPoolStats stats() {
543550 if ("same" .equals (name )) {
544551 continue ;
545552 }
553+ if (holder .info .type == ThreadPoolType .FORK_JOIN ) {
554+ // Add ForkJoinPool with sentinel values
555+ stats .add (new ThreadPoolStats .Stats (name , 0 , 0 , 0 , 0 , 0 , 0 , -1 ));
556+ continue ;
557+ }
546558 int threads = -1 ;
547559 int queue = -1 ;
548560 int active = -1 ;
@@ -664,8 +676,11 @@ public void shutdown() {
664676 stopCachedTimeThread ();
665677 scheduler .shutdown ();
666678 for (ExecutorHolder executor : executors .values ()) {
667- if (executor .executor () instanceof ThreadPoolExecutor || executor .executor () instanceof ForkJoinPool ) {
668- executor .executor ().shutdown ();
679+ ExecutorService es = executor .executor ();
680+ if (es instanceof ThreadPoolExecutor ) {
681+ es .shutdown ();
682+ } else if (es instanceof ForkJoinPool ) {
683+ es .shutdown ();
669684 }
670685 }
671686 }
@@ -674,23 +689,50 @@ public void shutdownNow() {
674689 stopCachedTimeThread ();
675690 scheduler .shutdownNow ();
676691 for (ExecutorHolder executor : executors .values ()) {
677- if (executor .executor () instanceof ThreadPoolExecutor || executor .executor () instanceof ForkJoinPool ) {
678- executor .executor ().shutdownNow ();
692+ ExecutorService es = executor .executor ();
693+ if (es instanceof ThreadPoolExecutor ) {
694+ es .shutdownNow ();
695+ } else if (es instanceof ForkJoinPool ) {
696+ es .shutdownNow (); // same as shutdown(), but explicit to the reader
679697 }
680698 }
681699 }
682700
683701 public boolean awaitTermination (long timeout , TimeUnit unit ) throws InterruptedException {
684- boolean result = scheduler .awaitTermination (timeout , unit );
702+ long nanos = unit .toNanos (timeout );
703+ long deadline = System .nanoTime () + nanos ;
704+ boolean result = scheduler .awaitTermination (Math .max (0 , nanos ), TimeUnit .NANOSECONDS );
705+ long now = System .nanoTime ();
706+ nanos = deadline - now ;
707+
685708 for (ExecutorHolder executor : executors .values ()) {
686709 if (executor .executor () instanceof ThreadPoolExecutor || executor .executor () instanceof ForkJoinPool ) {
687- result &= executor .executor ().awaitTermination (timeout , unit );
710+ if (nanos <= 0 ) {
711+ result = false ;
712+ break ;
713+ }
714+ result &= executor .executor ().awaitTermination (Math .max (0 , nanos ), TimeUnit .NANOSECONDS );
715+ now = System .nanoTime ();
716+ nanos = deadline - now ;
688717 }
689718 }
690- cachedTimeThread .join (unit .toMillis (timeout ));
719+ if (nanos > 0 ) {
720+ cachedTimeThread .join (TimeUnit .NANOSECONDS .toMillis (nanos ));
721+ }
691722 return result ;
692723 }
693724
725+ // public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
726+ // boolean result = scheduler.awaitTermination(timeout, unit);
727+ // for (ExecutorHolder executor : executors.values()) {
728+ // if (executor.executor() instanceof ThreadPoolExecutor || executor.executor() instanceof ForkJoinPool) {
729+ // result &= executor.executor().awaitTermination(timeout, unit);
730+ // }
731+ // }
732+ // cachedTimeThread.join(unit.toMillis(timeout));
733+ // return result;
734+ // }
735+
694736 public ScheduledExecutorService scheduler () {
695737 return this .scheduler ;
696738 }
@@ -948,6 +990,10 @@ public void writeTo(StreamOutput out) throws IOException {
948990 // Opensearch on older version doesn't know about "resizable" thread pool. Convert RESIZABLE to FIXED
949991 // to avoid serialization/de-serization issue between nodes with different OpenSearch version
950992 out .writeString (ThreadPoolType .FIXED .getType ());
993+ } else if (type == ThreadPoolType .FORK_JOIN && out .getVersion ().before (Version .V_3_2_0 )) {
994+ // Opensearch on older version doesn't know about "fork_join" thread pool. Convert FORK_JOIN to FIXED (or SCALING, or
995+ // another safe fallback)
996+ out .writeString (ThreadPoolType .FIXED .getType ());
951997 } else {
952998 out .writeString (type .getType ());
953999 }
@@ -993,6 +1039,12 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
9931039 builder .field ("core" , min );
9941040 assert max != -1 ;
9951041 builder .field ("max" , max );
1042+ } else if (type == ThreadPoolType .FORK_JOIN ) {
1043+ builder .field ("size" , -1 );
1044+ builder .field ("min" , -1 );
1045+ builder .field ("max" , -1 );
1046+ builder .field ("keep_alive" , (Object ) null );
1047+ builder .field ("queue_size" , -1 );
9961048 } else {
9971049 assert max != -1 ;
9981050 builder .field ("size" , max );
0 commit comments