quarkus: Server Sent Events delaying 200 response
Describe the bug
I am on 2.6.1.Final. I have an endpoint that is an SSE endpoint. The status code is only returned after the first element is produced.
This was not the case in 1.x and can lead to timeouts on clients.
Expected behavior
I would expect a 200 to be returned immediately (provided everything worked as expected).
Actual behavior
The status code, headers, etc. is not returned until the moment the first item is produced.
How to Reproduce?
Output of uname -a or ver
Linux jose-buguroo 5.11.0-41-generic #45-Ubuntu SMP Fri Nov 5 11:37:01 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
Output of java -version
openjdk version “14.0.2” 2020-07-14 OpenJDK Runtime Environment (build 14.0.2+12-46) OpenJDK 64-Bit Server VM (build 14.0.2+12-46, mixed mode, sharing)
GraalVM version (if different from Java)
No response
Quarkus version or git rev
2.6.1.Final
Build tool (ie. output of mvnw --version or gradlew --version)
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f) Maven home: /home/jose/.m2/wrapper/dists/apache-maven-3.6.3-bin/1iopthnavndlasol9gbrbg6bf2/apache-maven-3.6.3 Java version: 14.0.2, vendor: Oracle Corporation, runtime: /home/jose/.sdkman/candidates/java/14.0.2-open Default locale: en_US, platform encoding: UTF-8 OS name: “linux”, version: “5.11.0-41-generic”, arch: “amd64”, family: “unix”
Additional information
From what I see SseUtil.send is producing the response the first time an element is produced. Therefore, until the first element is generated, no call to it happens and no response is flushed. I see this could have to do with PublisherResponseHandler suspending the context. I wonder if an option could be to have that class handle SSE slightly different and generate a status code.
I see that adding:
requestContext.serverResponse().setStatusCode(200)
requestContext.serverResponse().setChunked(true)
requestContext.serverResponse().write(new byte[]{})
to PublisherResponseHandler works as expected (i.e. we get the status code, headers, etc. and then the events get produced as they come). Any reason you can think of not to do that?
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 2
- Comments: 29 (28 by maintainers)
Commits related to this issue
- When using SSE send the headers (and flush them) as soon as we have the Publisher (so before subscription). Fix #22762 — committed to cescoffier/quarkus by cescoffier 2 years ago
- When using SSE send the headers (and flush them) as soon as we have the Publisher (so before subscription). Fix #22762 — committed to cescoffier/quarkus by cescoffier 2 years ago
- When using SSE send the headers (and flush them) as soon as we have the Publisher (so before subscription). Fix #22762 (cherry picked from commit 23ab5a000f0c5c23c0e3b9a149bc1786a991fe55) — committed to gsmet/quarkus by cescoffier 2 years ago
I’m no SSE expert, just a user, but as a user I would expect the 200 to come right away and then receive the events.
Maybe @cescoffier has an opinion too as he played quite a lot with this.
I’m only ever referring to RestEasy server here. By “client” in the above quote I meant an
EventSourceas defined by the WHATWG Spec.I agree that the status should be sent ASAP and we shouldn’t be waiting for a first message.
@cescoffier It seems we could easily find a middle ground here. I would think that any resource method that has returned a
MultiorFlowor equivalently setup JAX-RS’s asynchronous & SSE systems should be considered a200 OK. This allows the resource method to prepare things, and possibly throw an exception for400,401, etc. In all other cases a200should be assumed and sent.Basically by the time control returns back to RestEasy, the resource had their chance to set things up and possible report errors, if not it should be a successful “setup”.
WRT to the
204, what is the use? SSE is designed for long lived connections that are expecting streams of events. What would be the harm in sending a “200”, then not sending any events and finally closing the connection. IMHO, as an SSE client, this is what I would expect not a204; that seems like some kind of premature optimization that is wholly unnecessary.