Skip to content

SseEmitter (ResponseBodyEmitter) keeps collecting messages if not initialized #25442

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

Closed
kgcsabi opened this issue Jul 21, 2020 · 2 comments
Closed
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: bug A general bug
Milestone

Comments

@kgcsabi
Copy link

kgcsabi commented Jul 21, 2020

Details

Component: spring-webmvc
Affects: 5.2.7.RELEASE
Impact: Memory leak

Description

The ResponseBodyEmitter instance is normally initialized by the framework upon returned by the RestController method.
The messages that are passed in the meantime are collected in a LinkedHashSet.

When the connection is dropped by the client early enough then the initialization will never be invoked.

These instances keep collecting the messages with no limitation.
To make matters worse, these instances are not evicted when timeout is reached.

This may result in OutOfMemoryError on the long run.

Steps to reproduce:

  1. Start Server app in debug mode
  2. Add breakpoint to org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitterReturnValueHandler:129 //emitter.initialize(handler);
  3. Start Client app
  4. When breakpoint hit then stop Client app

Attachments

Ideas

In my opinion this may be addressed by

  • limiting the time waiting for initialization
  • limiting the number of messages kept before initialization
  • a combination of the above
  • a custom handler for early send attempts
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Jul 21, 2020
@archiezgg
Copy link

+1

@sbrannen sbrannen added the in: web Issues in web modules (web, webmvc, webflux, websocket) label Jul 21, 2020
@rstoyanchev rstoyanchev self-assigned this Oct 16, 2020
@rstoyanchev rstoyanchev added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Oct 16, 2020
@rstoyanchev rstoyanchev added this to the 5.2.10 milestone Oct 16, 2020
@rstoyanchev
Copy link
Contributor

I can't reproduce the exact scenario. The ISE "Async request already returned to container" from the logs is under WebAsyncRequest#startDeferredResultProcessing which is a couple of lines before emitter.initialize(handler). That means the connection must have been closed by then. I tried dropping the connection at that stage but I still can't get startDeferredResultProcessing to raise the same error.

In any case it's clear that we need to protect against very early connection issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

5 participants