Hi Tim!
On Fri, Aug 24, 2012 at 06:44:02AM -0700, Tim Olsen wrote:
> 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
>
https://github.com/jruby/jruby-rack/issues/117
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]:
https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/streaming.rb#L219
--
Aaron Patterson
http://tenderlovemaking.com/