Fast CSV Report Generation with Postgres in Rails
Silas J. Matson
1573

You really nicely listed all the advantages of streaming responses. I just want to mention an alternative to ActionController::Live, which works for any Rack application (not just Rails), and any sane web server. And you’ll be surprised how simple it is ;)

I don’t know how much you know about Rack, but Rails and most other web frameworks are built on top of it. When you return response with Rails, it gets translated into a Rack response. What is a “Rack response”? It’s a 3-element array: 1st element is the response status, 2nd element is a hash of headers, and the 3rd element is an object that responds to #each (representing the response body). One example of a Rack response:

[200, {“Content-Length” => “7”}, [“content”]]

Now, why is the 3rd argument an object that responds to #each? Why is it not just a string? Well, for streaming responses! Most web servers when they call #each will immediately write the yielded strings into the TCP socket (the only exception I saw so far was Reel, but a simple PR would fix that).

With that in mind, let’s rewrite your example to use streaming that’s already built into Rack itself:

If you didn’t yet play with Ruby Enumerators, they will lazily fetch elements as they are requested (in your case CSV row strings). This should achieve the same end result, but without the complexity of ActionController::Live.