Wednesday, May 13, 2009

Issues with RoR streaming from controller

Well, I am facing some issues with "on the go" streaming data from controller using Ruby on Rails. I've tried almost every instance to query about this problem and try to find an answer. Nothing works so far.

I've posted multiple questions on the Twitter. Previously, I was getting replies very quickly. But today is not my day.

I've tried IRC. I have to acknowledge it's dead now. Very dead, even that it keeps tens of people signing on and off every single minute, as well as keeping more then 500 of signed people on.

I've tried the discussion group on Google. I didn't receive any comments back to my issue, yet. But I still hope. :)

I don't know if my blog will be any better — actually, I doubt so as it's never been a RoR lair. But I'll give it a try and post my problem here. Hopefully, I'll get it nailed some day and share the solution with you.

So, I need to stream a lot of data from the controller and there is no need for a view. Data generates on the go, and can take pretty long time to complete (say, from 1 minute to 3-4 hours). I doubt that it worths generating a string (the output can be hundreds of megabytes) and pass it to the view (ouch).

The way to use render :text => ... is not going to work for me, as it can be called only once in controller, so not a real "on the go" streaming.

Neither store to file and then streaming it with render :file works. Several simultaneous uses of the controller can generate pretty huge files for every instance, which is no-go (tens and hundreds of gigabytes of free space for temporary files?). Anyway, it's not "on the go" as well. (Well, partially. It'll be streaming once the file is created. :)

The other way is to render :text = Proc.new { |r,o| ... }, however, somehow it doesn't seem to be working for my case. First of all, it complains about some random each ... do blocks (that work just fine when the blocks are not passed to Proc.new). When I'm commenting them out, I'm getting things like that:

Wed May 13 17:34:39 -0700 2009: Read error: #
/Library/Ruby/Gems/1.8/gems/activesupport-2.3.2/lib/active_support/dependencies.rb:414:in `load_missing_constant'
/Library/Ruby/Gems/1.8/gems/activesupport-2.3.2/lib/active_support/dependencies.rb:96:in `const_missing'
/Users/white/repo/vurvimport/app/controllers/do_controller.rb:380:in `preparesql'
/Users/white/repo/vurvimport/app/controllers/do_controller.rb:630:in `rendersql'
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.2/lib/action_controller/response.rb:153:in `call'
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.2/lib/action_controller/response.rb:153:in `each'
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.2/lib/action_controller/vendor/rack-1.0/rack/chunked.rb:37:in `each'
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.2/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb:74:in `process'
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:159:in `process_client'
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:158:in `each'
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:158:in `process_client'
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `run'
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `initialize'
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `new'
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `run'
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in `initialize'
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in `new'
/Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in `run'
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.2/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb:34:in `run'
/Library/Ruby/Gems/1.8/gems/rails-2.3.2/lib/commands/server.rb:111
/Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
/Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `require'
script/server:3

I think the similar situation is also mentioned in tickets. I'm not sure that this is really a bug though. I'll keep an eye on that.