Flushing output stream(ob_flush() equivalent)

I’m trying to find a way to flush the output buffer. I have done this
before
in java and php but cannot find a method in ruby/rails? Is this
possible?

-m

On 8/27/06, Miguel El Feo [email protected] wrote:

I’m trying to find a way to flush the output buffer. I have done this before
in java and php but cannot find a method in ruby/rails? Is this possible?

Rails doesn’t do streaming for regular requests, but it does provide
an API for streaming responses.


Kent

Looking through the changelog I found this:

  • render_text now accepts a block for deferred rendering. Useful for
    streaming large files, displaying
    a “please wait” message during a complex search, etc. Streaming
    example:

    render_text do |response|
    File.open(path, ‘rb’) do |file|
    while buf = file.read(1024)
    print buf
    end
    end
    end

    [Jeremy K.]

Yet when I try this it does not work. I wonder if this has been removed
in
later releases?

-m

Thanks for the input. I’ve tried send_data previously and it does not
provide the function I need. I’ve also tried using $stdout.flush and it
doesn’t seem to affect anything. Any other suggestions welcomed.

-m

Thanks Kent, but I’ve tried that and it doesn’t provide what I want. If
I do
:

render :text => lambda { |response, out|
  out << "Sleeping"
  sleep(10)
  out << "Waking Up"
}

What I’m expecting here is to see “Sleeping” then after the sleep
duration,
“Waking Up”. However it does not stream the response, it will process
the
whole block and then send the response. No different then how it
normally
renders.

render :text => lambda { |response, out|
File.open(path, ‘rb’) do |file|
while buf = file.read(1024)
out.print buf
end
end
}

On 8/28/06, Miguel El Feo [email protected] wrote:

       print buf

Rails doesn’t do streaming for regular requests, but it does provide


Kent

You should use out.flush method

class TestController < ApplicationController
def index
render :text => lambda { |resp, out|
out.puts ‘start’
out.flush
10.times do
out.puts ‘.’
out.flush
sleep 1
end
out.puts ‘done’
}
end
end

Note it works only with fastcgi setup. It doesn’t work with webrick.

On 8/28/06, Miguel El Feo [email protected] wrote:

What I’m expecting here is to see “Sleeping” then after the sleep duration,

   while buf = file.read(1024)

a “please wait” message during a complex search, etc. Streaming
[Jeremy K.]

Thanks for the input. I’ve tried send_data previously and it does not

On 8/27/06, Miguel El Feo [email protected] wrote:


Kent

If you are using a browser to test it, you won’t see the difference. Use
curl for that. In my example,

$ curl http://localhost:3000/test

You will see the output printed after each flush method is being called.

On 8/29/06, Miguel El Feo [email protected] wrote:

regards,

  out.puts 'start'
  out << "Sleeping"

renders.

 end

Yet when I try this it does not work. I wonder if this has been
does not

Rails doesn’t do streaming for regular requests, but it does
DATANOISE.COM

Kent

http://www.datanoise.com


Kent

I’ve been using mozilla and lynx to test and now I’ve just used curl and
the
same thing happens. It’s not streaming the output. I am wondering if its
something within my setup thats preventing me from getting this to work.
My
co-worker has tried the same code on his development system and it
doesn’t
work for him either. I am wondering if I can replicate your rails/server
setup if I could get it to work.

-m

The saga continues - I refuse to give up. I’ve determined that its not a
server issue at this point, I’ve used lighttpd, apache with fcgid,
mongrel
and no luck still. Me and a coworker are working on a workaround for
this
since output streaming seems like a pipe dream at this point. In the
meantime it would be nice to get the specs of a system setup that is
known
to work with streaming so I can implement it and see if I have better
results. In the meanwhile I have a $20 prize over at Guruza
HugeDomains.com to anyone who can help
answer
this question.

I’ve tried of all this and I’m using lighttpd and still it does not
flush
the output buffer. I’ve tested this in production and development mode,
I
even tried mongrel just for kicks. Tested it on more then one machine
with
the help of a coworker here at work. I am not sure if maybe at work our
configuration is somehow preventing this to function, but we are running
a
standard setup and I really don’t see how that can be. In the meantime I
will have some of my other friends try this on their setups and see if
they
can get it to work. Any other suggestions would be truly appreciated.

regards,
m

On Thu, 2006-08-31 at 11:31 -0400, Miguel El Feo wrote:

The saga continues - I refuse to give up. I’ve determined that its not
a server issue at this point, I’ve used lighttpd, apache with fcgid,
mongrel and no luck still. Me and a coworker are working on a
workaround for this since output streaming seems like a pipe dream at
this point. In the meantime it would be nice to get the specs of a
system setup that is known to work with streaming so I can implement
it and see if I have better results. In the meanwhile I have a $20
prize over at Guruza HugeDomains.com to
anyone who can help answer this question.

Oh, I missed this, sorry but you can’t stream from rails in Mongrel at
the least, probably in none of them. Mostly because Rails does some
buffering and Mongrel does some buffering and Rails likes to change its
mind mid-stream.

If there’s a particular action that needs streaming and you can break it
out of rails then it is possible to write Mongrel handler that streams
fairly quickly. In fact Mongrel does this when sending a file.

Another option, is if you can pack up what Rails is supposed to send in
a streaming fashion, then you can write a simple Mongrel handler that
does the heavy lifting of streaming it out to the user.

Otherwise, having Rails do the actual streaming will stop the other
clients since while Rails is streaming you’ll be locked.

Go ahead and give the $20 to a charity. :slight_smile:


Zed A. Shaw

http://mongrel.rubyforge.org/
http://www.lingr.com/room/3yXhqKbfPy8 – Come get help.

On 8/31/06, Miguel El Feo [email protected] wrote:

The saga continues - I refuse to give up. I’ve determined that its not a
server issue at this point, I’ve used lighttpd, apache with fcgid, mongrel
and no luck still. Me and a coworker are working on a workaround for this
since output streaming seems like a pipe dream at this point. In the
meantime it would be nice to get the specs of a system setup that is known
to work with streaming so I can implement it and see if I have better
results. In the meanwhile I have a $20 prize over at Guruza
HugeDomains.com
to anyone who can help answer this question.

Miguel,

I’m using lighttpd with fastcgi and it streams just fine. With my
example if I use curl to query my action URL, I can see the output
after each our.flush invocation.


Kent

On 8/31/06, Zed S. [email protected] wrote:

anyone who can help answer this question.

Oh, I missed this, sorry but you can’t stream from rails in Mongrel at
the least, probably in none of them. Mostly because Rails does some
buffering and Mongrel does some buffering and Rails likes to change its
mind mid-stream.

Rails calls output.write on the IO the dispatcher hands it; Mongrel
hands
Rails a StringIO. The only exception I recall is that send_file used to
call
output.syswrite, if available, to bypass Ruby buffered IO.

jeremy

On 8/31/06, Jeremy K. [email protected] wrote:

Rails calls output.write on the IO the dispatcher hands it; Mongrel hands
Rails a StringIO. The only exception I recall is that send_file used to call
output.syswrite, if available, to bypass Ruby buffered IO.

jeremy

No, send_file uses output.write method. If Rails is deployed in the
fastcgi environment, your output object is FCGI::Stream which doesn’t
provide sysread/syswrite methods. All buffering in this case is
provided by fastcgi library and ‘flush’ method is supported.


Kent