eclipse-ee4j / grizzly

Grizzly
https://eclipse-ee4j.github.io/grizzly
Other
147 stars 69 forks source link

HTTP/2 server push race conditions #2111

Closed lprimak closed 1 year ago

lprimak commented 3 years ago

When HTTP/2 server push is enabled, there are race conditions preventing some of the resources to be pushed correctly. This is evident from PrimeFaces showcase running on Payara w/HTTP/2 push enabled.

This issue has been outstanding for 3+ years without a resolution

This issue prevents HTTP/2 server push from being used at all with Grizzly, thus hurting performance

Here are links to Payara issues: https://github.com/payara/Payara/issues/2625 https://github.com/payara/Payara/issues/2625#issuecomment-381304143

To reproduce via Primefaces Showcase:

git clone git@github.com:primefaces/showcase.git
cd showcase
git checkout 6_1
mvn clean package
asadmin deploy target/showcase-6.1.war
•   Make sure you are using HTTPS to access the showcase

•   Make sure to disable the cache and/or empty the browser cache

•   Click through Menu -> Menu -> Non-Ajax Delete

•   Keep clicking until you see a failure in your web browser


Exceptions:

[2018-06-14T15:52:03.969-0500] [Payara 5.183-SNAPSHOT] [WARNING] [] [org.glassfish.grizzly.filterchain.DefaultFilterChain] [tid: _ThreadID=39 _ThreadName=http-thread-pool::http-listener-2(2)] [timeMillis: 15
29009523969] [levelValue: 900] [[
 ‚GRIZZLY0013: Exception during FilterChain execution
java.lang.NullPointerException
  at org.glassfish.grizzly.http2.Http2SessionOutputSink$OutputQueueRecord.access$100(Http2SessionOutputSink.java:318)
  at org.glassfish.grizzly.http2.Http2SessionOutputSink.flushOutputQueue(Http2SessionOutputSink.java:242)
  at org.glassfish.grizzly.http2.Http2SessionOutputSink.writeDataDownStream(Http2SessionOutputSink.java:192)
  at org.glassfish.grizzly.http2.DefaultOutputSink.flushToConnectionOutputSink(DefaultOutputSink.java:521)
  at org.glassfish.grizzly.http2.DefaultOutputSink.writeDownStream(DefaultOutputSink.java:423)
  at org.glassfish.grizzly.http2.Http2ServerFilter.processOutgoingHttpHeader(Http2ServerFilter.java:970)
  at org.glassfish.grizzly.http2.Http2BaseFilter.handleWrite(Http2BaseFilter.java:729)
  at org.glassfish.grizzly.filterchain.ExecutorResolver$8.execute(ExecutorResolver.java:87)
  at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:260)
  at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:177)
  at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:109)
  at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:88)
  at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:53)
  at org.glassfish.grizzly.filterchain.FilterChainContext.write(FilterChainContext.java:866)
  at org.glassfish.grizzly.filterchain.FilterChainContext.write(FilterChainContext.java:834)
  at org.glassfish.grizzly.http.io.OutputBuffer.flushBuffer(OutputBuffer.java:1068)
  at org.glassfish.grizzly.http.io.OutputBuffer.write(OutputBuffer.java:695)
  at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:336)
  at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:323)
  at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:154)
  at java.nio.channels.Channels$WritableByteChannelImpl.write(Channels.java:458)
  at com.sun.faces.application.resource.ResourceHandlerImpl.handleResourceRequest(ResourceHandlerImpl.java:342)
  at javax.faces.application.ResourceHandlerWrapper.handleResourceRequest(ResourceHandlerWrapper.java:195)
  at org.primefaces.application.resource.PrimeResourceHandler.handleResourceRequest(PrimeResourceHandler.java:87)
  at javax.faces.webapp.FacesServlet.executeLifecyle(FacesServlet.java:728)
  at javax.faces.webapp.FacesServlet.service(FacesServlet.java:475)
  at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1622)
  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:258)
  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
  at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:654)
  at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:593)
  at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:159)
  at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:371)
  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:238)
  at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:516)
  at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:213)
  at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:182)
  at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:156)
  at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:218)
  at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:95)
  at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:260)
  at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:177)
  at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:109)
  at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:88)
  at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:53)
  at org.glassfish.grizzly.http2.Http2Session.sendMessageUpstream(Http2Session.java:1285)
  at org.glassfish.grizzly.http2.Http2Session.sendMessageUpstream(Http2Session.java:1261)
  at org.glassfish.grizzly.http2.Http2ServerFilter$2.run(Http2ServerFilter.java:1056)
  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
  at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:569)
  at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:549)
  at java.lang.Thread.run(Thread.java:748)
]]

Another one:

[2018-06-30T19:56:08.098-0500] [Payara 5.183-SNAPSHOT] [SEVERE] [] [org.glassfish.grizzly.http2.Http2ServerFilter] [tid: _ThreadID=45 _ThreadName=http-thread-pool::http-listener-2(1)] [timeMillis: 1530406568098] [levelValue: 1000] [[
  Unable to push resource identified by path [/showcase-6.1/javax.faces.resource/main/images/mono/overlayBlue.svg.xhtml]]]

[2018-06-30T19:56:08.099-0500] [Payara 5.183-SNAPSHOT] [SEVERE] [] [org.glassfish.grizzly.http2.Http2ServerFilter] [tid: _ThreadID=45 _ThreadName=http-thread-pool::http-listener-2(1)] [timeMillis: 1530406568099] [levelValue: 1000] [[
  Session is closed
org.glassfish.grizzly.http2.Http2StreamException streamId=204 errorCode=REFUSED_STREAM: Session is closed
        at org.glassfish.grizzly.http2.Http2Session.openStream(Http2Session.java:1090)
        at org.glassfish.grizzly.http2.Http2ServerFilter.doPush(Http2ServerFilter.java:1017)
        at org.glassfish.grizzly.http2.Http2ServerFilter.handleEvent(Http2ServerFilter.java:603)
        at org.glassfish.grizzly.filterchain.ExecutorResolver$6.execute(ExecutorResolver.java:70)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:260)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:177)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:109)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:88)
        at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:53)
        at org.glassfish.grizzly.filterchain.FilterChainContext.notifyDownstream(FilterChainContext.java:928)
        at org.glassfish.grizzly.filterchain.FilterChainContext.notifyDownstream(FilterChainContext.java:910)
        at org.apache.catalina.core.ApplicationPushBuilder.push(ApplicationPushBuilder.java:365)
        at com.sun.faces.context.ExternalContextImpl.pushIfPossibleAndNecessary(ExternalContextImpl.java:1211)
        at com.sun.faces.context.ExternalContextImpl.encodeResourceURL(ExternalContextImpl.java:668)
        at javax.faces.context.ExternalContextWrapper.encodeResourceURL(ExternalContextWrapper.java:164)
        at com.sun.faces.renderkit.RenderKitUtils.getImageSource(RenderKitUtils.java:1440)
        at com.sun.faces.renderkit.html_basic.ImageRenderer.encodeEnd(ImageRenderer.java:96)
        at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:619)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1677)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1673)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1673)
        at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:492)
        at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:194)
        at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:156)
        at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:156)
        at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:126)
        at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
        at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:223)
        at javax.faces.webapp.FacesServlet.executeLifecyle(FacesServlet.java:732)
        at javax.faces.webapp.FacesServlet.service(FacesServlet.java:475)
        at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1622)
        at org.apache.catalina.core.ApplicationDispatcher.doInvoke(ApplicationDispatcher.java:824)
        at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:688)
        at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:527)
        at org.apache.catalina.core.ApplicationDispatcher.doDispatch(ApplicationDispatcher.java:496)
        at org.apache.catalina.core.ApplicationDispatcher.dispatch(ApplicationDispatcher.java:378)
        at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:507)
        at org.apache.catalina.core.StandardHostValve.dispatchToErrorPage(StandardHostValve.java:701)
        at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:385)
        at org.apache.catalina.core.StandardHostValve.postInvoke(StandardHostValve.java:219)
        at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:373)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:238)
        at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:516)
        at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:213)
        at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:182)
        at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:156)
        at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:218)
        at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:95)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:260)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:177)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:109)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:88)
        at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:53)
        at org.glassfish.grizzly.http2.Http2Session.sendMessageUpstream(Http2Session.java:1288)
        at org.glassfish.grizzly.http2.Http2Session.sendMessageUpstream(Http2Session.java:1264)
        at org.glassfish.grizzly.http2.Http2ServerFilter$2.run(Http2ServerFilter.java:1056)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:569)
        at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:549)
        at java.lang.Thread.run(Thread.java:748)
]]