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

Flux<ServerSentEvent> looses messages when using a Processor from another Thread [SPR-14772] #19338

Closed
spring-projects-issues opened this issue Oct 1, 2016 · 9 comments
Assignees
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

@spring-projects-issues spring-projects-issues commented Oct 1, 2016

Guillaume DROUET opened SPR-14772 and commented

Hi,

I modified this example to expose a REST endpoint that creates a Flux. The messages are sent by a ReplayProcessor invoked from another REST endpoint that creates a ServerSentEvent from the parameter.

@RestController
public class HomeController {

    private FluxProcessor<ServerSentEvent<String>, ServerSentEvent<String>> replayProcessor =
            ReplayProcessor.<ServerSentEvent<String>>create().serialize();

    @GetMapping("/{val}")
    public void receive(@PathVariable("val") final String s) {
        replayProcessor.onNext(ServerSentEvent.builder(s).build());
    }

	@RequestMapping(value = "/")
	public Flux<ServerSentEvent<String>> starter() {
        return replayProcessor.log("starter");
	}
}

When I open the SSE endpoint in a browser tab and send messages with the correct URL opened in a second tab, I don't receive anything on SSE side when I run the application with Tomcat. With netty I can receive some messages but the onNext() method randomly blocks and some messages are lost.

Also note that if I switch to an EmitterProcessor, all messages are lost also with Netty while I'm expecting the same behavior between the two implementations here.


Affects: 5.0 M2

Issue Links:

  • #19369 Hot publishing to an event stream not working ("is duplicated by")

Referenced from: commits aea3a75, 25e7cd5, 5c9c5e0

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 4, 2016

Sébastien Deleuze commented

Thanks I will have a deeper look to see if I can reproduce the issue you described.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 5, 2016

Sébastien Deleuze commented

spring-reactive-playground now provides a HTML page that allows to reproduce this issue with Tomcat. Undertow, Jetty and RxNetty seems to be ok, while a bug prevents proper testing with Reactor Netty.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 6, 2016

Sébastien Deleuze commented

Stéphane Maldini has fixed the previously mentioned bug, and after testing with Reactor Netty 0.5.2, we can say this issue does not appear with Reactor Netty. So with the current repro use-case, this issue is only reproducible with Tomcat. That said, Guillaume DROUET mentioned some random issue with Netty and I have been able to make a similar unit test blocking with Jetty as well. So what we can say for now is that Tomcat allow to reproduce easily this issue but this is maybe not specific to Tomcat ...

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 14, 2016

Rossen Stoyanchev commented

I can no longer reproduce the issue with Tomcat in spring-reactive-playground and using the latest snapshots. What I am observing with the way the sample is written is that each 10 seconds if you don't send anything, Tomcat times out and then the browser reconnects the SSE connection. At that point the ReplayProcessor replays all events from the beginning, so the output on the browser keeps multiplying.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 15, 2016

Guillaume DROUET commented

Hum ok I start to suspect the OS because I'm testing on a windows 10 and even the spring-reactive-playground project does not works for me.
With tomcat I have also some kind of timeout after 30 seconds. It's like data are flushed and appear when the connection times out.
With Reactor Netty nothing works, events are never received.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 15, 2016

Guillaume DROUET commented

After re-testing it actually works fine with netty when I use the spring-reactive-playground.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 17, 2016

Sébastien Deleuze commented

I have tested again and I confirm that under MacOS, I can still reproduce the issue with Tomcat and not with Reactor Netty, so this is maybe a bug only reproducible with some specific OS in addition to being linked to the engine used. I am going to have a deeper look with Violeta Georgieva.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 19, 2016

Violeta Georgieva commented

Hi,

With the current implementation we handle the POST request in the original container thread.
ReplayProcessor tries to send data but at that moment Tomcat is still not able to accept writing (javax.servlet.ServletOutputStream.isReady() returns false).
As there is no POST request body the implementation will complete the async operation.
The next time when the browser reconnects the ReplayProcessor will be able to send the data.

My proposal is to move the request processing in another thread than the original container thread.
Using that approach when ReplayProcessor will be able to send the data.

Here is PR that I would like to propose.
#1213

What do you think?

Regards,
Violeta

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 21, 2016

Rossen Stoyanchev commented

This should now be fixed with commit 5c9c5e. We may yet revisit a more optimal solution if Tomcat provides an alternative option.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants