JRuby/Rails Streaming in development environment (and beyond)

Rails streaming is a great feature that allows you to optimize on server resources when dealing with large generated content. However – it might be a bit tricky to validate and test in local development.

First off – a local server that supports streaming is required. The only one I could find was trinidad which is moving to the likely defacto for JRuby/Rails projects. Trinidad uses tomcat-core as it’s servlet container and server.

Then make sure you grab the latest jruby-rack resolving most recent issues (1.1.10 at the time of writing).

This StackOverflow answer, along with this guide offer a comprehensive support as to what options work with Rails version as well as some gotchas (newrelic, caching, haml, …).

For Rails 3.2.x – It boils down to assigning an object that responds to an each method call to the response_body of a controller’s action. However – this doesn’t allow you to set a :stream =>true where it explicitly tells Rails to stream the respons. To resolve that I opted to use a render call, with a passed option hash as follows:

{% highlight ruby %}


def streaming_action @objs = MyObj.where(:foo => ‘bar’) render :nothing => true, :stream => true #setting the response to stream while rendering nothing self.response_body = Streamer.new(@objs) # the object responding to ‘each’ call end

#models/streamer.rb class Streamer attr_accssor :objs

def initialize(objs) @objs = objs end

# all the magic def each yield “Some initial output for header” @objs.each do |obj| yield “#{obj.attr}\n” end end end {% endhighlight %}

This works with the following releases: JRuby 1.6.8 Rails 3.2.8 jruby-rack 1.1.10 trinidad 1.4.4