eclipse-ee4j / eclipse-ee4j/jersey

RequestEventListener does not contain request properties during FINISHED event during async request handling

Open
#5,214 0 comments 0 reactions 0 assignees View on GitHub
async Monitor
Dominant language
Java
Stars
730
Forks
382
PR merge metrics
No merged PRs in 30d

Description

I am using the following:
2.0.34
2.33
9.4.49.v20220914

The problem is that when in async mode using Suspend annotation, the RequestEventListener event RequestEvent.Type.FINISHED does not contain the request properties (attributes) anymore since it gets recycled during the AsyncResponse.resume() call, whereas the regular sync calls (thread per request model) have all the properties set for the request during the handling of the same FINISHED event.

Both modes async and sync have the request properties set during the previous event, the RequestEvent.Type.RESP_FILTERS_FINISHED event.

I have a RequestEventListener listener that does not work properly during async because it is expecting the FINISHED event to contain all the request properties, but it doesnt since the request gets recycled between RESP_FILTERS_FINISHED and FINISHED, not after FINISHED like the regular sync mode.

```
@Override
public void onEvent(RequestEvent event) {
if (event.getType() == RequestEvent.Type.FINISHED) {
// containerRequest.getProperty("my-property-name") will be cleared during async, but will contain the properties during sync
}
}
```

Is by design, a bug? If it is by design, and I want to say do some processing once the response is fully completed (i.e. closed) and I need to use some of those properties set during an earlier filter, what is the right way to utilize the request properties for async mode ensuring the response is already closed?

For sync mode, during the FINISHED event, the container response is closed (true), the request properties are present, and the http channel gets recycled afterwards.

For the async mode, during the FINISHED event, the http channel was already recycled beforehand, the container response is closed (true), and the request properties are **not present**, which is what I need.

Here is a stack trace when the request gets recycled during async resume before the FINISHED event is fired:
```
"pool-2-thread-1@7052" prio=5 tid=0x1c nid=NA runnable
java.lang.Thread.State: RUNNABLE
at org.eclipse.jetty.server.HttpChannelOverHttp.recycle(HttpChannelOverHttp.java:81)
at org.eclipse.jetty.server.HttpConnection.onCompleted(HttpConnection.java:447)
at org.eclipse.jetty.server.HttpChannel.onCompleted(HttpChannel.java:919)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:467)
at org.eclipse.jetty.server.HttpChannel.run(HttpChannel.java:439)
at org.eclipse.jetty.server.handler.ContextHandler.handle(ContextHandler.java:1525)
at org.eclipse.jetty.server.HttpChannelState.runInContext(HttpChannelState.java:1225)
at org.eclipse.jetty.server.HttpChannelState.complete(HttpChannelState.java:733)
at org.eclipse.jetty.server.AsyncContextState.complete(AsyncContextState.java:72)
at org.glassfish.jersey.servlet.async.AsyncContextDelegateProviderImpl$ExtensionImpl.complete(AsyncContextDelegateProviderImpl.java:102)
at org.glassfish.jersey.servlet.internal.ResponseWriter.commit(ResponseWriter.java:173)
at org.glassfish.jersey.server.ContainerResponse.close(ContainerResponse.java:390)
at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:707)
at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:373)
at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:363)
at org.glassfish.jersey.server.ServerRuntime$AsyncResponder$3.run(ServerRuntime.java:857)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
at org.glassfish.jersey.internal.Errors.process(Errors.java:244)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265)
at org.glassfish.jersey.server.ServerRuntime$AsyncResponder.resume(ServerRuntime.java:889)
at org.glassfish.jersey.server.ServerRuntime$AsyncResponder.resume(ServerRuntime.java:845)
at com.playground.resources.JerseyResource.lambda$asyncEventListener$2(JerseyResource.java:127)
at com.playground.resources.JerseyResource$$Lambda$561.137000849.run(Unknown Source:-1)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
at java.util.concurrent.FutureTask.run(FutureTask.java:-1)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
```

Here is the sync call, which happens after the FINISHED event:
```
"dw-28@5189" prio=5 tid=0x1c nid=NA runnable
java.lang.Thread.State: RUNNABLE
at org.eclipse.jetty.server.HttpChannelOverHttp.recycle(HttpChannelOverHttp.java:81)
at org.eclipse.jetty.server.HttpConnection.onCompleted(HttpConnection.java:447)
at org.eclipse.jetty.server.HttpChannel.onCompleted(HttpChannel.java:919)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:467)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)
at java.lang.Thread.run(Thread.java:748)
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.