I want a CGI script to fire off another process and continue executing
(or even terminate) without waiting for the process to finish. I wrote
this:
#!/usr/bin/ruby
require ‘cgi’
c = CGI.new
fork do sleep 5 end
c.out {“hello!\n”}
When I execute that from the command line, it IMMEDIATELY prints
“Content-Type…hello!” and exits. When I run it on Apache and access it
from my browser, on the other hand, it PAUSES for five seconds, THEN
displays “hello!”.
What’s going on? Why does it behave differently with Apache?
I am using Apache/2.2.12 (Ubuntu) with ruby 1.8.7 (2009-06-12 patchlevel
174) [x86_64-linux].
When I execute that from the command line, it IMMEDIATELY prints
“Content-Type…hello!” and exits. When I run it on Apache and access it
from my browser, on the other hand, it PAUSES for five seconds, THEN
displays “hello!”.
What’s going on? Why does it behave differently with Apache?
All sorts of possible reasons: Apache might buffer your output and
maybe it even waits for the child to return.
What happens if you do this:
#!/usr/bin/ruby
require ‘cgi’
c = CGI.new
fork do
$stdin.close
$stdout.close
$stderr.close
sleep 5
end
Elanor: I’m using the default apache2 config as distributed by Ubuntu
9.10. Is there a particular Apache directive I could use to make it
behave the way I expect?
Robert: Closing STDIN and STDOUT seemed to do the trick! Thanks. Just so
I grok this: Apache, by default, will wait until all subprocesses close
their IO streams before it sends a CGI program’s output to the browser?
It seems so. You’ll probably have more luck with this question when
placed in an Apache forum. Reading the docs might also help.
Is that correct? Is there a better way to kick off such processes? Or is
manually closing STDIN and STDOUT every time I fork the ideal solution?
Since I have no idea what your process does or is supposed to do I
cannot really tell. You’ll probably want to look into the features
available to daemonize a process, e.g
Elanor: I’m using the default apache2 config as distributed by Ubuntu
9.10. Is there a particular Apache directive I could use to make it
behave the way I expect?
On reflection I suspect it wouldn’t make a lot of difference as…
Robert: Closing STDIN and STDOUT seemed to do the trick! Thanks.
Just so
I grok this: Apache, by default, will wait until all subprocesses
close
their IO streams before it sends a CGI program’s output to the
browser?
Is that correct? Is there a better way to kick off such processes?
Or is
manually closing STDIN and STDOUT every time I fork the ideal
solution?
…it appears that when Apache launches a CGI process it waits for
that process to close the std[in|out] file descriptors before sending
the page to the browser, so closing them is clearly the way to go if
using direct forking. However there are alternative options you could
explore such as using a message queue (BackgroundDRb, unix message
queues, etc.) or named pipe to communicate with a process (or
processes) created outside the context of Apache.
Elanor: I’m using the default apache2 config as distributed by Ubuntu
9.10. Is there a particular Apache directive I could use to make it
behave the way I expect?
Robert: Closing STDIN and STDOUT seemed to do the trick! Thanks. Just so
I grok this: Apache, by default, will wait until all subprocesses close
their IO streams before it sends a CGI program’s output to the browser?
Is that correct? Is there a better way to kick off such processes? Or is
manually closing STDIN and STDOUT every time I fork the ideal solution?
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.