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

Buffering of output in Spring Web Reactive with Netty too aggressive [SPR-14943] #19510

Closed
spring-projects-issues opened this issue Nov 24, 2016 · 5 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Nov 24, 2016

Daniel Fernández opened SPR-14943 and commented

Scenario

This is the scenario:

  • Web application outputting a very large sequence of items produced by a Flux<Item>, serialized as JSON
  • Clients expecting to receive first results quickly, then keep on receiving more results until the Flux finishes producing items.
  • SSE not being used.

Observed Results

When using Spring Web Reactive in a Spring Boot 2.0.0 (snapshot) application:

  • If Netty is used as a server, no results come until the end (Netty seems to buffer all output until it's finished, then send it altogether).
  • If RxNetty is used as a server, no results ever come (or at least during a very large period of time).

Compare Tomcat (intro being hit during curl execution to see the data transfer flow):

$ curl http://localhost:8084/items/10000 > out.tomcat
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 1959k    0 1959k    0     0   334k      0 --:--:--  0:00:05 --:--:--  340k
100 2421k    0 2421k    0     0   336k      0 --:--:--  0:00:07 --:--:--  340k

With Netty:

$ curl http://localhost:8082/items/10000 > out.netty
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:00:05 --:--:--     0
  0     0    0     0    0     0      0      0 --:--:--  0:00:10 --:--:--     0
  0     0    0     0    0     0      0      0 --:--:--  0:00:15 --:--:--     0
  0     0    0     0    0     0      0      0 --:--:--  0:00:20 --:--:--     0
  0     0    0     0    0     0      0      0 --:--:--  0:00:25 --:--:--     0
  0     0    0     0    0     0      0      0 --:--:--  0:00:30 --:--:--     0
100 2421k    0 2421k    0     0  74041      0 --:--:--  0:00:33 --:--:--  579k

And RxNetty:

$ curl http://localhost:8083/items/10000 > out.rxnetty
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:00:15 --:--:--     0
  0     0    0     0    0     0      0      0 --:--:--  0:00:30 --:--:--     0
  0     0    0     0    0     0      0      0 --:--:--  0:00:45 --:--:--     0
  0     0    0     0    0     0      0      0 --:--:--  0:01:00 --:--:--     0
  0     0    0     0    0     0      0      0 --:--:--  0:01:15 --:--:--     0
  0     0    0     0    0     0      0      0 --:--:--  0:01:30 --:--:--     0
  0     0    0     0    0     0      0      0 --:--:--  0:01:45 --:--:--     0
  0     0    0     0    0     0      0      0 --:--:--  0:02:00 --:--:--     0
  0     0    0     0    0     0      0      0 --:--:--  0:02:15 --:--:--     0
  0     0    0     0    0     0      0      0 --:--:--  0:02:30 --:--:--     0
  0     0    0     0    0     0      0      0 --:--:--  0:02:45 --:--:--     0
... (cancelled after 7 minutes)

Example applications

Example applications: https://github.com/danielfernandez/test-spring-boot-reactive-netty-output

The above applications replicate the scenario using Spring Boot 2.0.0 apps with Jetty, Netty, RxNetty, Tomcat and Undertow. Note this application also tests other issues (to be specified in separate tickets).

Please have a look at the detailed test explanation at the linked repository's README


Affects: 5.0 M3

Reference URL: https://github.com/danielfernandez/test-spring-boot-reactive-netty-output

Sub-tasks:

Issue Links:

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Nov 28, 2016

Rossen Stoyanchev commented

Note that Flux<Item> currently produces a JSON array which is what browser clients can consume. In that sense it's not designed for a streaming scenario as opposed to SSE which enforces a flush after each event. That said we should consider improvements:

Why does it work better in Tomcat/Undertow out of the box and can we ensure similar reasonable defaults across all runtimes?

How do we support outputting a very large sequence of items other than SSE? Ideally returning Flux<Item> should support streaming and non-streaming scenarios just as well so let's start from there and see if that is possible.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Dec 2, 2016

Sébastien Deleuze commented

For Reactor Netty, it should maybe flush the buffer when a specific amount of data has been sent, I am going to discuss that with Reactor team.
With RxNetty, 184 iterations works while 185 does not! I am going to try to reproduce it with a pure RxNetty application.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Dec 2, 2016

Sébastien Deleuze commented

Reactor Netty will introduce a threshold to trigger a flush after buffering a certain amount of data, see this issue.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Dec 6, 2016

Sébastien Deleuze commented

I have been able to reproduce this issue with a pure RxNetty sample application and have raised an issue on RxNetty bugtracker.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Dec 15, 2016

Sébastien Deleuze commented

The 2 subtasks have been resolved, I am just waiting a fix from Stéphane Maldini that will allow to restore Reactor Netty based integration tests (currently disabled via this commit).

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: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants