46
46
import org .eclipse .jetty .security .AuthenticationState ;
47
47
import org .eclipse .jetty .server .Handler ;
48
48
import org .eclipse .jetty .util .Callback ;
49
+ import org .eclipse .jetty .util .thread .Scheduler ;
49
50
import org .glassfish .jersey .internal .MapPropertiesDelegate ;
50
51
import org .glassfish .jersey .internal .inject .AbstractBinder ;
51
52
import org .glassfish .jersey .internal .inject .ReferencingFactory ;
@@ -91,8 +92,6 @@ public final class JettyHttpContainer extends Handler.Abstract implements Contai
91
92
*/
92
93
private boolean configSetStatusOverSendError ;
93
94
94
- private final ScheduledThreadPoolExecutor timeoutScheduler ;
95
-
96
95
/**
97
96
* Referencing factory for Jetty request.
98
97
*/
@@ -141,7 +140,7 @@ protected void configure() {
141
140
@ Override
142
141
public boolean handle (Request request , Response response , Callback callback ) throws Exception {
143
142
144
- final ResponseWriter responseWriter = new ResponseWriter (timeoutScheduler , request , response , callback , configSetStatusOverSendError );
143
+ final ResponseWriter responseWriter = new ResponseWriter (request , response , callback , configSetStatusOverSendError );
145
144
try {
146
145
LOGGER .debugLog (LocalizationMessages .CONTAINER_STARTED ());
147
146
final URI baseUri = getBaseUri (request );
@@ -253,37 +252,38 @@ private String getBasePath(final Request request) {
253
252
}
254
253
}
255
254
256
- private static final class ResponseWriter implements ContainerResponseWriter {
255
+ private static class ResponseWriter implements ContainerResponseWriter {
257
256
258
257
private final Request request ;
259
258
private final Response response ;
260
259
private final Callback callback ;
261
260
private final boolean configSetStatusOverSendError ;
262
261
private final long asyncStartTimeNanos ;
263
- private final ScheduledExecutorService timeoutScheduler ;
262
+ private final Scheduler scheduler ;
264
263
private final ConcurrentLinkedQueue <TimeoutHandler > timeoutHandlerQueue = new ConcurrentLinkedQueue <>();
265
- private ScheduledFuture <?> currentTimerTask ;
264
+ private Scheduler . Task currentTimerTask ;
266
265
267
- ResponseWriter (final ScheduledExecutorService timeoutScheduler , final Request request , final Response response ,
266
+ ResponseWriter (final Request request , final Response response ,
268
267
final Callback callback , final boolean configSetStatusOverSendError ) {
269
- this .timeoutScheduler = timeoutScheduler ;
270
268
this .request = request ;
271
269
this .response = response ;
272
270
this .callback = callback ;
273
271
this .asyncStartTimeNanos = System .nanoTime ();
274
272
this .configSetStatusOverSendError = configSetStatusOverSendError ;
273
+
274
+ this .scheduler = request .getComponents ().getScheduler ();
275
275
}
276
276
277
277
private synchronized void setNewTimeout (long timeOut , TimeUnit timeUnit ) {
278
278
long timeOutNanos = timeUnit .toNanos (timeOut );
279
279
if (currentTimerTask != null ) {
280
280
// Do not interrupt, see callTimeoutHandlers()
281
- currentTimerTask .cancel (false );
281
+ currentTimerTask .cancel ();
282
282
}
283
283
// Use System.nanoTime() as the clock source here, because the returned value is not prone to wall-clock
284
284
// drift - unlike System.currentTimeMillis().
285
285
long delayNanos = Math .max (asyncStartTimeNanos - System .nanoTime () + timeOutNanos , 0L );
286
- currentTimerTask = timeoutScheduler .schedule (this ::callTimeoutHandlers , delayNanos , TimeUnit .NANOSECONDS );
286
+ currentTimerTask = scheduler .schedule (this ::callTimeoutHandlers , delayNanos , TimeUnit .NANOSECONDS );
287
287
}
288
288
289
289
private void callTimeoutHandlers () {
@@ -437,50 +437,21 @@ public void doStop() throws Exception {
437
437
appHandler .onShutdown (this );
438
438
appHandler = null ;
439
439
440
- timeoutScheduler .shutdown ();
441
440
boolean needInterrupt = false ;
442
- while (true ) {
443
- try {
444
- if (timeoutScheduler .awaitTermination (1L , TimeUnit .MINUTES )) {
445
- break ;
446
- }
447
- } catch (InterruptedException e ) {
448
- if (!needInterrupt ) {
449
- needInterrupt = true ;
450
- timeoutScheduler .shutdownNow ();
451
- }
452
- }
453
- }
454
441
if (needInterrupt ) {
455
442
Thread .currentThread ().interrupt ();
456
443
}
457
444
}
458
445
459
446
private static final AtomicInteger TIMEOUT_HANDLER_ID_GEN = new AtomicInteger ();
460
447
461
- private static ScheduledThreadPoolExecutor createTimeoutScheduler () {
462
- // Note: creating the thread-pool does not start the core-pool threads.
463
- ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor (1 , r -> {
464
- Thread t = new Thread (r , "JettyHttpContainer-Timeout-Handler #" + TIMEOUT_HANDLER_ID_GEN .incrementAndGet ());
465
- t .setDaemon (true );
466
- return t ;
467
- });
468
- // Limit the number of timeout handling threads to a quarter of the number of CPUs, at least 2.
469
- executor .setMaximumPoolSize (Math .max (2 , Runtime .getRuntime ().availableProcessors () / 4 ));
470
- executor .allowCoreThreadTimeOut (true );
471
- // Don't Keep timeout handling threads around "forever".
472
- executor .setKeepAliveTime (100 , TimeUnit .MILLISECONDS );
473
- return executor ;
474
- }
475
-
476
448
/**
477
449
* Create a new Jetty HTTP container.
478
450
*
479
451
* @param application JAX-RS / Jersey application to be deployed on Jetty HTTP container.
480
452
* @param parentContext DI provider specific context with application's registered bindings.
481
453
*/
482
454
JettyHttpContainer (final Application application , final Object parentContext ) {
483
- this .timeoutScheduler = createTimeoutScheduler ();
484
455
this .appHandler = new ApplicationHandler (application , new JettyBinder (), parentContext );
485
456
}
486
457
@@ -490,7 +461,6 @@ private static ScheduledThreadPoolExecutor createTimeoutScheduler() {
490
461
* @param application JAX-RS / Jersey application to be deployed on Jetty HTTP container.
491
462
*/
492
463
JettyHttpContainer (final Application application ) {
493
- this .timeoutScheduler = createTimeoutScheduler ();
494
464
this .appHandler = new ApplicationHandler (application , new JettyBinder ());
495
465
496
466
cacheConfigSetStatusOverSendError ();
@@ -502,7 +472,6 @@ private static ScheduledThreadPoolExecutor createTimeoutScheduler() {
502
472
* @param applicationClass JAX-RS / Jersey class of application to be deployed on Jetty HTTP container.
503
473
*/
504
474
JettyHttpContainer (final Class <? extends Application > applicationClass ) {
505
- this .timeoutScheduler = createTimeoutScheduler ();
506
475
this .appHandler = new ApplicationHandler (applicationClass , new JettyBinder ());
507
476
508
477
cacheConfigSetStatusOverSendError ();
0 commit comments