62
62
import javax .servlet .http .HttpServletRequest ;
63
63
import javax .servlet .http .HttpServletResponse ;
64
64
import org .eclipse .jetty .ee8 .nested .ContextHandler ;
65
- import org .eclipse .jetty .ee8 .nested .HandlerWrapper ;
66
- import org .eclipse .jetty .ee8 .nested .HttpChannel ;
67
65
import org .eclipse .jetty .ee8 .nested .Request ;
66
+ import org .eclipse .jetty .ee8 .nested .ScopedHandler ;
68
67
import org .eclipse .jetty .ee8 .servlet .ServletHolder ;
69
68
import org .eclipse .jetty .ee8 .webapp .Configuration ;
70
69
import org .eclipse .jetty .ee8 .webapp .JettyWebXmlConfiguration ;
@@ -354,7 +353,6 @@ protected void connectContainer() throws Exception {
354
353
0 ,
355
354
Runtime .getRuntime ().availableProcessors (),
356
355
new HttpConnectionFactory (configuration ));
357
- connector .addBean (new CompletionListener ());
358
356
connector .setHost (address );
359
357
connector .setPort (port );
360
358
// Linux keeps the port blocked after shutdown if we don't disable this.
@@ -597,7 +595,7 @@ private File determineAppRoot() throws IOException {
597
595
* com.google.apphosting.api.ApiProxy.Environment} which is stored as a request Attribute and then
598
596
* set/cleared on a ThreadLocal by the ContextScopeListener {@link ThreadLocal}.
599
597
*/
600
- private class ApiProxyHandler extends HandlerWrapper {
598
+ private class ApiProxyHandler extends ScopedHandler {
601
599
@ SuppressWarnings ("hiding" ) // Hides AbstractContainerService.appEngineWebXml
602
600
private final AppEngineWebXml appEngineWebXml ;
603
601
@@ -606,7 +604,103 @@ public ApiProxyHandler(AppEngineWebXml appEngineWebXml) {
606
604
}
607
605
608
606
@ Override
609
- public void handle (String target , Request baseRequest , HttpServletRequest request , HttpServletResponse response ) throws IOException , ServletException {
607
+ public void doHandle (
608
+ String target ,
609
+ Request baseRequest ,
610
+ HttpServletRequest request ,
611
+ HttpServletResponse response )
612
+ throws IOException , ServletException {
613
+ nextHandle (target , baseRequest , request , response );
614
+ }
615
+
616
+ @ Override
617
+ public void doScope (
618
+ String target ,
619
+ Request baseRequest ,
620
+ HttpServletRequest request ,
621
+ HttpServletResponse response )
622
+ throws IOException , ServletException {
623
+
624
+ org .eclipse .jetty .server .Request .addCompletionListener (
625
+ baseRequest .getCoreRequest (),
626
+ t -> {
627
+ try {
628
+ // a special hook with direct access to the container instance
629
+ // we invoke this only after the normal request processing,
630
+ // in order to generate a valid response
631
+ if (request .getRequestURI ().startsWith (AH_URL_RELOAD )) {
632
+ try {
633
+ reloadWebApp ();
634
+ log .info ("Reloaded the webapp context: " + request .getParameter ("info" ));
635
+ } catch (Exception ex ) {
636
+ log .log (Level .WARNING , "Failed to reload the current webapp context." , ex );
637
+ }
638
+ }
639
+ } finally {
640
+
641
+ LocalEnvironment env =
642
+ (LocalEnvironment ) request .getAttribute (LocalEnvironment .class .getName ());
643
+ if (env != null ) {
644
+ environments .remove (env );
645
+
646
+ // Acquire all of the semaphores back, which will block if any are outstanding.
647
+ Semaphore semaphore =
648
+ (Semaphore ) env .getAttributes ().get (LocalEnvironment .API_CALL_SEMAPHORE );
649
+ try {
650
+ System .err .println ("=========== acquire semaphore ===========" );
651
+ semaphore .acquire (MAX_SIMULTANEOUS_API_CALLS );
652
+ } catch (InterruptedException ex ) {
653
+ Thread .currentThread ().interrupt ();
654
+ log .log (
655
+ Level .WARNING , "Interrupted while waiting for API calls to complete:" , ex );
656
+ }
657
+
658
+ try {
659
+ ApiProxy .setEnvironmentForCurrentThread (env );
660
+
661
+ // Invoke all of the registered RequestEndListeners.
662
+ env .callRequestEndListeners ();
663
+
664
+ if (apiProxyDelegate instanceof ApiProxyLocal ) {
665
+ // If apiProxyDelegate is not instanceof ApiProxyLocal, we are presumably
666
+ // running in
667
+ // the devappserver2 environment, where the master web server in Python will
668
+ // take care
669
+ // of logging requests.
670
+ ApiProxyLocal apiProxyLocal = (ApiProxyLocal ) apiProxyDelegate ;
671
+ String appId = env .getAppId ();
672
+ String versionId = env .getVersionId ();
673
+ String requestId = DevLogHandler .getRequestId ();
674
+
675
+ LocalLogService logService =
676
+ (LocalLogService ) apiProxyLocal .getService (LocalLogService .PACKAGE );
677
+
678
+ @ SuppressWarnings ("NowMillis" )
679
+ long nowMillis = System .currentTimeMillis ();
680
+ logService .addRequestInfo (
681
+ appId ,
682
+ versionId ,
683
+ requestId ,
684
+ request .getRemoteAddr (),
685
+ request .getRemoteUser (),
686
+ baseRequest .getTimeStamp () * 1000 ,
687
+ nowMillis * 1000 ,
688
+ request .getMethod (),
689
+ request .getRequestURI (),
690
+ request .getProtocol (),
691
+ request .getHeader ("User-Agent" ),
692
+ true ,
693
+ response .getStatus (),
694
+ request .getHeader ("Referrer" ));
695
+ logService .clearResponseSize ();
696
+ }
697
+ } finally {
698
+ ApiProxy .clearEnvironmentForCurrentThread ();
699
+ }
700
+ }
701
+ }
702
+ });
703
+
610
704
if (baseRequest .getDispatcherType () == DispatcherType .REQUEST ) {
611
705
Semaphore semaphore = new Semaphore (MAX_SIMULTANEOUS_API_CALLS );
612
706
@@ -631,87 +725,9 @@ public void handle(String target, Request baseRequest, HttpServletRequest reques
631
725
// this and so the Environment has not yet been created.
632
726
ApiProxy .Environment oldEnv = enterScope (request );
633
727
try {
634
- super .handle (target , baseRequest , request , response );
635
- }
636
- finally {
637
- exitScope (oldEnv );
638
- }
639
- }
640
- }
641
-
642
- private class CompletionListener implements HttpChannel .Listener {
643
- @ Override
644
- public void onComplete (Request request ) {
645
- try {
646
- // a special hook with direct access to the container instance
647
- // we invoke this only after the normal request processing,
648
- // in order to generate a valid response
649
- if (request .getRequestURI ().startsWith (AH_URL_RELOAD )) {
650
- try {
651
- reloadWebApp ();
652
- log .info ("Reloaded the webapp context: " + request .getParameter ("info" ));
653
- } catch (Exception ex ) {
654
- log .log (Level .WARNING , "Failed to reload the current webapp context." , ex );
655
- }
656
- }
728
+ super .doScope (target , baseRequest , request , response );
657
729
} finally {
658
-
659
- LocalEnvironment env =
660
- (LocalEnvironment ) request .getAttribute (LocalEnvironment .class .getName ());
661
- if (env != null ) {
662
- environments .remove (env );
663
-
664
- // Acquire all of the semaphores back, which will block if any are outstanding.
665
- Semaphore semaphore =
666
- (Semaphore ) env .getAttributes ().get (LocalEnvironment .API_CALL_SEMAPHORE );
667
- try {
668
- semaphore .acquire (MAX_SIMULTANEOUS_API_CALLS );
669
- } catch (InterruptedException ex ) {
670
- Thread .currentThread ().interrupt ();
671
- log .log (Level .WARNING , "Interrupted while waiting for API calls to complete:" , ex );
672
- }
673
-
674
- try {
675
- ApiProxy .setEnvironmentForCurrentThread (env );
676
-
677
- // Invoke all of the registered RequestEndListeners.
678
- env .callRequestEndListeners ();
679
-
680
- if (apiProxyDelegate instanceof ApiProxyLocal ) {
681
- // If apiProxyDelegate is not instanceof ApiProxyLocal, we are presumably running in
682
- // the devappserver2 environment, where the master web server in Python will take care
683
- // of logging requests.
684
- ApiProxyLocal apiProxyLocal = (ApiProxyLocal ) apiProxyDelegate ;
685
- String appId = env .getAppId ();
686
- String versionId = env .getVersionId ();
687
- String requestId = DevLogHandler .getRequestId ();
688
-
689
- LocalLogService logService =
690
- (LocalLogService ) apiProxyLocal .getService (LocalLogService .PACKAGE );
691
-
692
- @ SuppressWarnings ("NowMillis" )
693
- long nowMillis = System .currentTimeMillis ();
694
- logService .addRequestInfo (
695
- appId ,
696
- versionId ,
697
- requestId ,
698
- request .getRemoteAddr (),
699
- request .getRemoteUser (),
700
- request .getTimeStamp () * 1000 ,
701
- nowMillis * 1000 ,
702
- request .getMethod (),
703
- request .getRequestURI (),
704
- request .getProtocol (),
705
- request .getHeader ("User-Agent" ),
706
- true ,
707
- request .getResponse ().getStatus (),
708
- request .getHeader ("Referrer" ));
709
- logService .clearResponseSize ();
710
- }
711
- } finally {
712
- ApiProxy .clearEnvironmentForCurrentThread ();
713
- }
714
- }
730
+ exitScope (oldEnv );
715
731
}
716
732
}
717
733
}
0 commit comments