33import com .bugsnag .callbacks .Callback ;
44import com .bugsnag .delivery .Delivery ;
55import com .bugsnag .delivery .HttpDelivery ;
6+ import com .bugsnag .util .DaemonThreadFactory ;
67
78import org .slf4j .Logger ;
89import org .slf4j .LoggerFactory ;
1213import java .util .Collections ;
1314import java .util .Date ;
1415import java .util .Set ;
16+ import java .util .concurrent .ExecutorService ;
17+ import java .util .concurrent .Executors ;
18+ import java .util .concurrent .LinkedBlockingQueue ;
1519import java .util .concurrent .RejectedExecutionHandler ;
1620import java .util .concurrent .ScheduledThreadPoolExecutor ;
1721import java .util .concurrent .ThreadPoolExecutor ;
@@ -23,8 +27,17 @@ public class Bugsnag {
2327 private static final int SESSION_TRACKING_PERIOD_MS = 60000 ;
2428 private static final int CORE_POOL_SIZE = 1 ;
2529
30+ // Create an executor service which keeps idle threads alive for a maximum of SHUTDOWN_TIMEOUT.
31+ // This should avoid blocking an application that doesn't call shutdown from exiting.
32+ private ExecutorService sessionFlusherService =
33+ new ThreadPoolExecutor (0 , 1 ,
34+ SHUTDOWN_TIMEOUT_MS , TimeUnit .MILLISECONDS ,
35+ new LinkedBlockingQueue <Runnable >());
36+
2637 private ScheduledThreadPoolExecutor sessionExecutorService =
27- new ScheduledThreadPoolExecutor (CORE_POOL_SIZE , new RejectedExecutionHandler () {
38+ new ScheduledThreadPoolExecutor (CORE_POOL_SIZE ,
39+ new DaemonThreadFactory (),
40+ new RejectedExecutionHandler () {
2841 @ Override
2942 public void rejectedExecution (Runnable runnable , ThreadPoolExecutor executor ) {
3043 LOGGER .error ("Rejected execution for sessionExecutorService" );
@@ -81,7 +94,14 @@ private void scheduleSessionFlushes() {
8194 sessionExecutorService .scheduleAtFixedRate (new Runnable () {
8295 @ Override
8396 public void run () {
84- sessionTracker .flushSessions (new Date ());
97+ // Use a different thread which is not a daemon thread
98+ // to actually flush the sessions
99+ sessionFlusherService .submit (new Runnable () {
100+ @ Override
101+ public void run () {
102+ sessionTracker .flushSessions (new Date ());
103+ }
104+ });
85105 }
86106 }, SESSION_TRACKING_PERIOD_MS , SESSION_TRACKING_PERIOD_MS , TimeUnit .MILLISECONDS );
87107 }
0 commit comments