Skip to content

Commit d48db6c

Browse files
Merge branch 'master' into SNOW-2161718-JDBC-fix-permission-check-for-toml-config
2 parents 674c6f5 + 6a05bb4 commit d48db6c

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

src/main/java/net/snowflake/client/jdbc/telemetryOOB/TelemetryThreadPool.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
import java.util.concurrent.Callable;
44
import java.util.concurrent.ExecutorService;
5+
import java.util.concurrent.Executors;
56
import java.util.concurrent.Future;
67
import java.util.concurrent.LinkedBlockingQueue;
8+
import java.util.concurrent.ThreadFactory;
79
import java.util.concurrent.ThreadPoolExecutor;
810
import java.util.concurrent.TimeUnit;
911

@@ -39,13 +41,23 @@ public static TelemetryThreadPool getInstance() {
3941
* allowing the pool to shrink back to zero during periods of inactivity.
4042
*/
4143
private TelemetryThreadPool() {
44+
// Create a thread factory that creates daemon threads to prevent blocking JVM termination
45+
ThreadFactory daemonThreadFactory =
46+
r -> {
47+
Thread thread = Executors.defaultThreadFactory().newThread(r);
48+
thread.setName("telemetry-uploader-" + thread.getId());
49+
thread.setDaemon(true);
50+
return thread;
51+
};
52+
4253
uploader =
4354
new ThreadPoolExecutor(
4455
CORE_POOL_SIZE, // core size
4556
CORE_POOL_SIZE, // max size
4657
30L, // keep alive time
4758
TimeUnit.SECONDS,
48-
new LinkedBlockingQueue<>() // work queue
59+
new LinkedBlockingQueue<>(), // work queue
60+
daemonThreadFactory // thread factory
4961
);
5062
// Allow core threads to time out and be terminated when idle.
5163
((ThreadPoolExecutor) uploader).allowCoreThreadTimeOut(true);

src/test/java/net/snowflake/client/jdbc/telemetryOOB/TelemetryThreadPoolTest.java

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

33
import static org.awaitility.Awaitility.await;
44
import static org.junit.jupiter.api.Assertions.assertEquals;
5+
import static org.junit.jupiter.api.Assertions.assertTrue;
56

67
import java.lang.reflect.Field;
78
import java.util.Collections;
@@ -10,6 +11,7 @@
1011
import java.util.concurrent.CountDownLatch;
1112
import java.util.concurrent.ThreadPoolExecutor;
1213
import java.util.concurrent.TimeUnit;
14+
import java.util.concurrent.atomic.AtomicBoolean;
1315
import net.snowflake.client.category.TestTags;
1416
import org.junit.jupiter.api.Tag;
1517
import org.junit.jupiter.api.Test;
@@ -77,6 +79,24 @@ void testThreadPoolScaling() throws InterruptedException {
7779
});
7880
}
7981

82+
@Test
83+
void testTelemetryThreadsAreDaemonThreads() throws InterruptedException {
84+
TelemetryThreadPool telemetryPool = TelemetryThreadPool.getInstance();
85+
final AtomicBoolean isDaemonThread = new AtomicBoolean(false);
86+
final CountDownLatch latch = new CountDownLatch(1);
87+
88+
telemetryPool.execute(
89+
() -> {
90+
isDaemonThread.set(Thread.currentThread().isDaemon());
91+
latch.countDown();
92+
});
93+
94+
// Wait for the task to complete
95+
latch.await(1, TimeUnit.SECONDS);
96+
97+
assertTrue(isDaemonThread.get(), "TelemetryThreadPool threads should be daemon threads");
98+
}
99+
80100
private ThreadPoolExecutor getThreadPoolExecutor(TelemetryThreadPool telemetryThreadPool) {
81101
try {
82102
Field uploaderField = TelemetryThreadPool.class.getDeclaredField("uploader");

0 commit comments

Comments
 (0)