forking behaves differently when using apache

N

Nick Brown

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].

Thanks in advance...
 
E

Eleanor McHugh

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].

Thanks in advance...

Do you have Apache configured to use preforked workers or to use
threads?


Ellie

Eleanor McHugh
Games With Brains
http://slides.games-with-brains.net
 
R

Robert Klemme

2009/11/12 Nick Brown said:
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?

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

c.out {"hello!\n"}

Cheers

robert
 
N

Nick Brown

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?
 
R

Robert Klemme

2009/11/12 Nick Brown said:
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

http://www.ruby-doc.org/core-1.9/classes/Process.html#M002265

Kind regards

robert
 
E

Eleanor McHugh

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.


Ellie

Eleanor McHugh
Games With Brains
http://slides.games-with-brains.net
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top