Skip to content

Commit 511d08f

Browse files
authored
Allow idle Pipe worker threads to time out (#18000)
1 parent 5f96833 commit 511d08f

3 files changed

Lines changed: 41 additions & 1 deletion

File tree

iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/concurrent/IoTDBThreadPoolFactory.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,23 @@ public static ExecutorService newFixedThreadPool(
127127
poolName);
128128
}
129129

130+
public static ExecutorService newFixedThreadPoolWithIdleThreadTimeout(
131+
int nThreads, long keepAliveTime, TimeUnit unit, String poolName) {
132+
logger.info(NEW_FIXED_THREAD_POOL_LOGGER_FORMAT, poolName, nThreads);
133+
134+
WrappedThreadPoolExecutor executor =
135+
new WrappedThreadPoolExecutor(
136+
nThreads,
137+
nThreads,
138+
keepAliveTime,
139+
unit,
140+
new LinkedBlockingQueue<>(),
141+
new IoTThreadFactory(poolName),
142+
poolName);
143+
executor.allowCoreThreadTimeOut(true);
144+
return executor;
145+
}
146+
130147
/**
131148
* see {@link Executors#newSingleThreadExecutor(java.util.concurrent.ThreadFactory)}.
132149
*

iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/agent/task/execution/PipeSubtaskExecutor.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,14 @@
3838
import java.util.concurrent.ConcurrentHashMap;
3939
import java.util.concurrent.ExecutorService;
4040
import java.util.concurrent.ThreadPoolExecutor;
41+
import java.util.concurrent.TimeUnit;
4142

4243
public abstract class PipeSubtaskExecutor {
4344

4445
private static final Logger LOGGER = LoggerFactory.getLogger(PipeSubtaskExecutor.class);
4546

47+
private static final long WORKER_THREAD_KEEP_ALIVE_TIME_IN_SECONDS = 60L;
48+
4649
private static final ExecutorService globalSubtaskCallbackListeningExecutor =
4750
IoTDBThreadPoolFactory.newSingleThreadExecutor(
4851
ThreadName.PIPE_SUBTASK_CALLBACK_EXECUTOR_POOL.getName());
@@ -78,7 +81,11 @@ protected PipeSubtaskExecutor(
7881
: ThreadName.PIPE_SUBTASK_CALLBACK_EXECUTOR_POOL.getName();
7982
underlyingThreadPool =
8083
(WrappedThreadPoolExecutor)
81-
IoTDBThreadPoolFactory.newFixedThreadPool(corePoolSize, workingThreadName);
84+
IoTDBThreadPoolFactory.newFixedThreadPoolWithIdleThreadTimeout(
85+
corePoolSize,
86+
WORKER_THREAD_KEEP_ALIVE_TIME_IN_SECONDS,
87+
TimeUnit.SECONDS,
88+
workingThreadName);
8289
if (disableLogInThreadPool) {
8390
underlyingThreadPool.disableErrorLog();
8491
}

iotdb-core/node-commons/src/test/java/org/apache/iotdb/commons/IoTDBThreadPoolFactoryTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import org.apache.iotdb.commons.concurrent.IoTDBThreadPoolFactory;
2222
import org.apache.iotdb.commons.concurrent.WrappedRunnable;
23+
import org.apache.iotdb.commons.concurrent.threadpool.WrappedThreadPoolExecutor;
2324

2425
import org.apache.thrift.server.TThreadPoolServer;
2526
import org.apache.thrift.server.TThreadPoolServer.Args;
@@ -110,6 +111,21 @@ public void testNewCachedThreadPool() {
110111
}
111112
}
112113

114+
@Test
115+
public void testNewFixedThreadPoolWithIdleThreadTimeout() throws Exception {
116+
ExecutorService exec =
117+
IoTDBThreadPoolFactory.newFixedThreadPoolWithIdleThreadTimeout(
118+
1, 1, TimeUnit.MILLISECONDS, POOL_NAME);
119+
120+
exec.submit(() -> {}).get();
121+
assertEquals(1, ((WrappedThreadPoolExecutor) exec).getLargestPoolSize());
122+
123+
Thread.sleep(100);
124+
assertEquals(0, ((WrappedThreadPoolExecutor) exec).getPoolSize());
125+
126+
exec.shutdown();
127+
}
128+
113129
@Test
114130
public void testNewSingleThreadScheduledExecutor() throws InterruptedException {
115131
String reason = "(can be ignored in Tests) NewSingleThreadScheduledExecutor";

0 commit comments

Comments
 (0)