Hi Tim!
Hello,
I have been using the HTTP streaming feature for my company's website for a few months now. It has significantly decreased the page load times for our asset-heavy pages.
I have encountered a few problems with HTTP streaming which can be traced to Rails always doing the chunked encoding itself:
- Incompatible middleware such as newrelic (granted it's easy to solve by putting the newrelic header and footer in manually but there are probably other incompatible middleware).
I'm not familiar with this, but it seems like something newrelic should provide?
- Problems with running assertions against a response body in integration tests. The response has chunk markers in it making it difficult to parse the body.
Are these *rails* integration tests? If so, we should consider this a bug. I would expect chunks to be assembled in to normal bodies in the integration tests.
- Incompatible servers that chunk encode again resulting in a double chunked encoding. I had to monkey patch Rails to not chunk encode in order to get streaming working properly with JRuby / Tomcat. See rails streamed pages are doubly chunked encoded after going through tomcat · Issue #117 · jruby/jruby-rack · GitHub
Not fun.
I understand the chunked encoding is required in the end in order to stream. But I wonder if instead of having Rails doing it at the core, it can instead be moved to a Rack middleware that is placed at the end of the middleware stack when needed and can be left out when the server is capable of doing the chunked encoding. This could be controlled by a configuration option.
As an intermediate step towards moving it to a Rack middleware, chunked encoding could first be made optional. This would at least solve the JRuby / Tomcat issue.
It seems entirely possible to do this. Rack has a chunking middleware that can be inserted in the stack. I think the main problem is that by the time the framework learns that you want a streaming response (the point when you call render with stream), the middleware stack is already assembled. In order to make the streaming Just Work, you'd have to add a chunked body right at that point.
We could eliminate the chunked body [from here][1], but it means two things:
1. You'd have to manually add the chunking middleware for *that* controller.
2. It would break backwards compatibility
We could add the chunking middleware by default, but I'm not sure everyone would want that.
I have another idea to fix this, but it's a bit more effort. AC::Live
doesn't chunk responses. I think it's possible to get the ERB to write
to a buffer that AC::Live uses. I've been looking in to this, but it
hasn't been my highest priority lately.
[1]: <%= yield :title %>