Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SSE Defects #23997

Closed
jimbogithub opened this issue Feb 27, 2022 · 24 comments
Closed

SSE Defects #23997

jimbogithub opened this issue Feb 27, 2022 · 24 comments
Labels
area/resteasy-reactive kind/bug Something isn't working triage/needs-feedback We are waiting for feedback.

Comments

@jimbogithub
Copy link

Describe the bug

Multiple issues related to Server Sent Events demonstrated in https://github.com/jimbogithub/sse. It contains reactive and non-reactive versions of a simple TimeBroadcaster broadcasting a timestamp event once per second to each subscribed TimeConsumer.

SSE Server

See sse-server TimeBroadcaster.

  1. Unable to obtain a centralised (e.g. @ApplicationScoped or @Singleton) Sse instance from which to derive the SseBroadcaster and Builder. Hence it appears impossible to properly implement the one-sender-many-receivers pattern.
  2. SseBroadcaster.onError is called twice for a client that has been cleanly closed. This is undesirable.

SSE Client

See sse-client TimeConsumer.

  1. Requires the Dummy interface in order for the client to bootstrap. See comments on that class as to what happens if you don't have this.

SSE Server Reactive

See sse-server-reactive TimeBroadcaster. Unlike the non-reactive server, it is possible to obtain a singular Sse instance from which to derive the SseBroadcaster and Builder.

  1. SseBroadcaster.broadcast tries to send messages to clients that have already closed.
  2. SseBroadcaster.onClose is never called.

SSE Client Reactive

See sse-client-reactive TimeConsumer.

  1. ClientBuilder.newBuilder()...build() does not work unless you add .withConfig(new org.jboss.resteasy.reactive.common.jaxrs.ConfigurationImpl(RuntimeType.CLIENT)). This wasn't necessary for the non-reactive client or when doing ClientBuilder.newClient() and I suspect is not intended.
  2. ClientRequestContext.getHeaders().toString() is not useful and does not match the non-reactive. See further discussion in code.
  3. ClientResponseContext.getStatusInfo().toString() is not useful and does not match the non-reactive. See further discussion in code.
  4. Client does not send the expected Accept: text/event-stream header.

Expected behavior

No response

Actual behavior

No response

How to Reproduce?

https://github.com/jimbogithub/sse

Output of uname -a or ver

No response

Output of java -version

No response

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.7.2

Build tool (ie. output of mvnw --version or gradlew --version)

No response

Additional information

Initial discussion: https://groups.google.com/g/quarkus-dev/c/qbH9RYnrIPg/m/GUlEiwLABAAJ

@jimbogithub jimbogithub added the kind/bug Something isn't working label Feb 27, 2022
@michalszynkiewicz
Copy link
Member

for building the client in the reactive version, is there any reason for not using ClientBuilder.newClient().register(new ClientRequestLogger()).register(new ClientResponseLogger()); to create the client?

@michalszynkiewicz
Copy link
Member

CC @FroMage @geoand

@jimbogithub
Copy link
Author

for building the client in the reactive version, is there any reason for not using ClientBuilder.newClient().register(new ClientRequestLogger()).register(new ClientResponseLogger()); to create the client?

In my case no. I simply point out the issue that occurs for anyone who does need to access the methods that are only available on the builder.

@jimbogithub
Copy link
Author

for building the client in the reactive version, is there any reason for not using ClientBuilder.newClient().register(new ClientRequestLogger()).register(new ClientResponseLogger()); to create the client?

In my case no. I simply point out the issue that occurs for anyone who does need to access the methods that are only available on the builder.

Looks like this one has been addressed by #23949 / #23996.

@jimbogithub
Copy link
Author

Another issue with the SSE Client Reactive is that it does not propagate the entity in the WebApplicationException. I think this is a known issue as there are comments in the code to that effect.

This is a more serious issue as I was hoping to switch to the reactive client as it properly implements connection-ttl as documented in https://quarkus.io/guides/all-config#quarkus-rest-client-config_quarkus.rest-client.-config-key-.connection-ttl (idle TTL) whereas the non-reactive version does a hard TTL.

@quarkus-bot
Copy link

quarkus-bot bot commented Apr 4, 2022

/cc @FroMage, @geoand, @stuartwdouglas

@herasimau
Copy link

Hi, any update on this issue ? SSE Server Reactive
SseBroadcaster.onClose is never called.

@gsmet
Copy link
Member

gsmet commented Aug 5, 2022

@geoand do you have this one on your radar?

@geoand
Copy link
Contributor

geoand commented Aug 5, 2022

Nope, it had dropped off, but I guess it's back on

@jimbogithub
Copy link
Author

FYI, I switched to Mutiny SSE as SSE Client Reactive started rapidly leaking memory (from 2.9.x?) - appears Buffers not being closed.

@geoand
Copy link
Contributor

geoand commented Aug 25, 2022

Do you have a memory dump or a sample project that exhibits this behavior?

@jimbogithub
Copy link
Author

Do you have a memory dump or a sample project that exhibits this behavior?

See this branch of the reproducer: https://github.com/jimbogithub/sse/tree/mem-leak

Start the sse-server-reactive then the sse-client-reactive.

2.7.x was OK. Noticed it from 2.9.2. Still present in 2.11.3.
Appears to be related to the Jackson integration as it doesn't occur if the messages are plain and the consumer does either event.readData() or event.readData(String.class).

Not so much leaking byte arrays but they grow in size (increasing #bytes):

jcmd 87720 GC.class_histogram
87720:
 num     #instances         #bytes  class name (module)
-------------------------------------------------------
   1:        119875       57961616  [B (java.base@17.0.4)

Eventually become "humungous" and GC fails.

@geoand
Copy link
Contributor

geoand commented Aug 26, 2022

Thanks

@geoand
Copy link
Contributor

geoand commented Aug 30, 2022

@jimbogithub I was not able to reproduce the issue with your project.

@jimbogithub
Copy link
Author

@geoand Did you use the branch I indicated?

@geoand
Copy link
Contributor

geoand commented Aug 30, 2022

I did yes.

This is what memory looked like:

mem

As you see, the Old Generation size is constant and all allocations are in Eden (which also results in all GCs being Young Generation GCs).
This is what one would expect to see from a well behaving GCed system.

@jimbogithub
Copy link
Author

What process are you monitoring? That loaded class count does not look plausible to me.

image

image

@geoand
Copy link
Contributor

geoand commented Aug 30, 2022

Oh, it's the client that has the leak? I was monitoring the server. Let me check the client as well

@geoand
Copy link
Contributor

geoand commented Aug 30, 2022

I can confirm the client issue.

geoand added a commit to geoand/quarkus that referenced this issue Aug 30, 2022
@geoand
Copy link
Contributor

geoand commented Aug 30, 2022

#27594 seems to fix the issue but I am not yet 100% it's the proper fix

@jimbogithub
Copy link
Author

@geoand I've re-tested my assertion that it was related to the Jackson/JSON integration - it isn't. Reproducer works with server sending PLAIN_TEXT and client doing simple event.readData(). So no need to worry about that aspect.

@geoand
Copy link
Contributor

geoand commented Aug 31, 2022

Right, I saw that too when testing my fix

FroMage added a commit that referenced this issue Oct 5, 2022
Avoid leaking memory in SseParser
gsmet pushed a commit to gsmet/quarkus that referenced this issue Oct 10, 2022
Relates to: quarkusio#23997

(cherry picked from commit 5d485f0)
igorregis pushed a commit to igorregis/quarkus that referenced this issue Oct 16, 2022
igorregis pushed a commit to igorregis/quarkus that referenced this issue Oct 16, 2022
igorregis pushed a commit to igorregis/quarkus that referenced this issue Oct 16, 2022
igorregis pushed a commit to igorregis/quarkus that referenced this issue Oct 17, 2022
tmihalac pushed a commit to tmihalac/quarkus that referenced this issue Oct 27, 2022
@geoand
Copy link
Contributor

geoand commented Jan 27, 2023

Is this still a problem?

@geoand
Copy link
Contributor

geoand commented Mar 1, 2024

Closing as we did not receive feedback

@geoand geoand closed this as not planned Won't fix, can't repro, duplicate, stale Mar 1, 2024
@geoand geoand added the triage/needs-feedback We are waiting for feedback. label Mar 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/resteasy-reactive kind/bug Something isn't working triage/needs-feedback We are waiting for feedback.
Projects
Status: Done
Development

No branches or pull requests

6 participants