Skip to content

Inconsistency in SseEmitter.onCompletion() behavior between Spring 6.2.3 and 6.2.5 #34762

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
jrpedrianes opened this issue Apr 15, 2025 · 2 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: regression A bug that is also a regression
Milestone

Comments

@jrpedrianes
Copy link

jrpedrianes commented Apr 15, 2025

Summary

There is an inconsistency in the invocation behaviour of the SseEmitter.onCompletion() callback between Spring Framework versions 6.2.3 and 6.2.5. Previously, calling emitter.complete() would immediately trigger the callback registered via onCompletion(). However, starting with Spring Framework 6.2.5 (used in Spring Boot 3.4), this callback no longer appears to execute after complete() method is invoqued.

Current Behaviour

When using Spring Boot 3.4 (with Spring Framework 6.2.5), calling emitter.complete() does not cause an immediate invocation of the onCompletion() callback. This behaviour differs from that in Spring Boot 3.3 (with Spring Framework 6.2.3), where emitter.complete() immediately triggered the callback.

Expected behaviour

The expected behaviour is that calling emitter.complete() should trigger the onCompletion() callback immediately, just as it did in Spring Boot 3.3 (Spring Framework 6.2.3).

Steps to Reproduce

You can reproduce the issue with the following setup:

  1. Implement the controller below in your application:
    @RestController
    public class SseController {
    
        @GetMapping("/sse")
        public SseEmitter handleSse() {
            SseEmitter emitter = new SseEmitter();
    
            emitter.onCompletion(() -> {
                System.out.println("onCompletion callback executed");
            });
    
            ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
            scheduler.schedule(() -> {
                emitter.complete();
            }, 1, TimeUnit.SECONDS);
    
            return emitter;
        }
    }
  2. Run the application with Spring Boot 3.3 (which uses Spring Framework 6.2.3) and observe that the log shows "onCompletion callback executed" immediately after calling complete().
  3. Update the application to Spring Boot 3.4 (with Spring Framework 6.2.5) and notice that the callback is not executed immediately.

Additional Notes

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Apr 15, 2025
@bclozel bclozel added the in: web Issues in web modules (web, webmvc, webflux, websocket) label Apr 15, 2025
@rstoyanchev rstoyanchev self-assigned this Apr 16, 2025
@rstoyanchev rstoyanchev added type: regression A bug that is also a regression and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Apr 16, 2025
@rstoyanchev rstoyanchev added this to the 6.2.6 milestone Apr 16, 2025
@rstoyanchev
Copy link
Contributor

rstoyanchev commented Apr 16, 2025

The #34426 fix in 6.2.4 was to address a regression introduced by a performance improvement #33831 in 6.2.0. However, that in turn led to this issue.

Looking at it more deeply, the intent of synchronized methods in ResponseBodyEmitter was to prevent concurrent use of the response, which is not allowed by the Servlet API, but the AtomicBoolean checks that replaced them in #33831 also had the effect of skipping the calls to Handler#complete and Handler#completeWithError, and that caused the regression reported in #34426.

I will update ResponseBodyEmitter accordingly to fix this in 6.2.x by matching behavior before the performance improvement.

I have also realized that protection against concurrent use of the response should no longer be necessary at the level of ResponseBodyEmitter, so I have created #34767 to address in 7.0.

rstoyanchev added a commit that referenced this issue Apr 16, 2025
@rstoyanchev
Copy link
Contributor

I have reverted both #34426 and #33831, in effect undoing the performance optimization since for 7.0 we're going to address the same.

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: regression A bug that is also a regression
Projects
None yet
Development

No branches or pull requests

4 participants