modperl_stop_button

This is part of The Pile, a partial archive of some open source mailing lists and newsgroups.



To: mod_perl list <modperl@apache.org>
From: Bill Moseley <moseley@hank.org>
Subject: Re: Stop button (was: Re: General Question)
Date: Sun, 11 Feb 2001 22:14:40 -0800

I don't know why I have to learn this fresh again each time -- it appears
I'm confusing mod_perl and mod_cgi.

Let's see if I have this right.  Under mod_perl and apache >= 1.3.5 if the
client drops the connection Apache will ignore it (well it might print an
info message to the log file about "broken pipe").  This means a running
mod_perl script will continue to run to completion, but the $r->prints go
nowhere.

The old Apache behavior of killing your running script can be restored
using Apache::SIG -- which is something you would not want to use if you
were doing anything besides displaying content, I'd think.

$r->connection->aborted can be used to detect the aborted connection (as
Stas shows in the Guide).  That sounds like a better way to deal with
broken connections.

Does all that sound right?

Are there still issues with doing this?

   local $SIG{PIPE} = sub { $aborted++ };



Then mod_cgi I'm still unclear on.

The cgi application does receive the SIGPIPE... well it did 1/2 hour ago
before I rebooted my machine.  Now I can't seem to catch it.
But, printing again after the SIGPIPE will kill the CGI script. 

===

To: Bill Moseley <moseley@hank.org>
From: Stas Bekman <stas@stason.org>
Subject: Re: Stop button (was: Re: General Question)
Date: Tue, 13 Feb 2001 17:47:47 +0800 (SGT)

On Sun, 11 Feb 2001, Bill Moseley wrote:

> I don't know why I have to learn this fresh again each time -- it appears
> I'm confusing mod_perl and mod_cgi.
>
> Let's see if I have this right.  Under mod_perl and apache >= 1.3.5 if the
> client drops the connection Apache will ignore it (well it might print an
> info message to the log file about "broken pipe").  This means a running
> mod_perl script will continue to run to completion, but the $r->prints go
> nowhere.
>
> The old Apache behavior of killing your running script can be restored
> using Apache::SIG -- which is something you would not want to use if you
> were doing anything besides displaying content, I'd think.
>
> $r->connection->aborted can be used to detect the aborted connection (as
> Stas shows in the Guide).  That sounds like a better way to deal with
> broken connections.
>
> Does all that sound right?

Yeah, it's a bit confusing.

Apache 1.3.6 and up -- STOP pressed:

the code keeps on running until it tries to read from or write to the
socket. the moment this happens, the script will stop the execution, and
run cleanup phase.

I think it's the same under mod_perl and mod_cgi. Am I right?

> Are there still issues with doing this?
>
>    local $SIG{PIPE} = sub { $aborted++ };

you do this because you want it to be mod_cgi back compatible? If not this
would be better:

END {
    $aborted++ if $r->connection->aborted;
}

And if you catch the signal you should do something about it other than
incrementing the count, right? like exit()

> Then mod_cgi I'm still unclear on.
>
> The cgi application does receive the SIGPIPE... well it did 1/2 hour ago
> before I rebooted my machine.  Now I can't seem to catch it.
> But, printing again after the SIGPIPE will kill the CGI script.

Well, it doesn't know that it was aborted before you try print something.

I guess the explanation in the guide is not clear enough and should be
revised, especially per Doug's reply... any volunteers?

===

To: modperl@apache.org
From: Steve Hay <Steve.Hay@uk.radan.com>
Subject: Re: Stop button (was: Re: General Question)
Date: Mon, 26 Feb 2001 14:02:26 +0000

Hi,

Stas Bekman wrote:

> Apache 1.3.6 and up -- STOP pressed:
>
> the code keeps on running until it tries to read from or write to the
> socket. the moment this happens, the script will stop the execution, and
> run cleanup phase.
>
> I think it's the same under mod_perl and mod_cgi. Am I right?

I have a script which I wish to run under either mod_perl or CGI which does
little more than display content and I would like it to stop when the user
presses Stop, but I can't get it working.

I've been trying to figure things out with the following test program:

 ---
use strict;
use warnings;
$SIG{PIPE} = \&handler;
$| = 1;
print "Content-Type: text/plain\n\n";
for (;;) {
    for (1 .. 1000000) { ; }
    print "x\n";
}
sub handler {
    # Unreliable signals on NT:-
    $SIG{PIPE} = \&handler;
    exit;
}
 ---

(The pointless time-wasting loop just before each print() is so that I can
easily see whether the program actually has exited or not -- I'm running on NT
(groan!) and I can see in my "Task Manager" display that the Apache child
process is flat out 100% CPU while its running.)

I would expect that when the user presses Stop and the script next tries a
print() it'll get a SIGPIPE, call the handler(), and exit().

But it doesn't -- the Apache child process just carries on at 100% CPU.

It makes no difference whether I run it under mod_perl or mod_cgi (except that,
of course, I get a Perl process at 100% CPU instead of the Apache child), and it
also makes no difference if I take out the first "$SIG{PIPE} = \&handler;" line
(and rely on mod_perl to handle the SIGPIPE for me as Stas described above)
and/or put the "PerlFixupHandler Apache::SIG" directive in my httpd.conf.

Can anybody help/explain?

I'm running Apache/1.3.17 and mod_perl/1.25 on Windows NT 4.

===

To: Steve Hay <Steve.Hay@uk.radan.com>, modperl@apache.org
From: Bill Moseley <moseley@hank.org>
Subject: Re: Stop button (was: Re: General Question)
Date: Mon, 26 Feb 2001 09:04:54 -0800

At 02:02 PM 02/26/01 +0000, Steve Hay wrote:
>I have a script which I wish to run under either mod_perl or CGI which does
>little more than display content and I would like it to stop when the user
>presses Stop, but I can't get it working.

You need to do different things under mod_perl and mod_cgi.  Refer to the
Guide for running under mod_perl -- you probably should check explicitly
for an aborted connection as the guide shows.

[This is all from my memory, so I hope I have the details correct]

Under mod_cgi Apache will receive the SIGPIPE when it tries to print to the
socket.  Since your CGI script is running as a subprocess (that has been
marked "kill_after_timeout", I believe), apache will first close the pipe
from your CGI program, send it a SIGTERM, wait three seconds, then send a
SIGKILL, and then reap.  This all happens in alloc.c, IIRC.

This is basically the same thing that happens when you have a timeout.

So, you can catch SIGTERM and then have three seconds to clean up.  You
won't see a SIGPIPE unless you try to print in that three second gap.  

Does it do the same thing under NT?



===

To: Bill Moseley <moseley@hank.org>, modperl@apache.org
From: Steve Hay <Steve.Hay@uk.radan.com>
Subject: Re: Stop button (was: Re: General Question)
Date: Tue, 27 Feb 2001 11:34:57 +0000

Bill Moseley wrote:

> At 02:02 PM 02/26/01 +0000, Steve Hay wrote:
> >I have a script which I wish to run under either mod_perl or CGI which does
> >little more than display content and I would like it to stop when the user
> >presses Stop, but I can't get it working.
>
> You need to do different things under mod_perl and mod_cgi.  Refer to the
> Guide for running under mod_perl -- you probably should check explicitly
> for an aborted connection as the guide shows.

Oh dear.  The program has to run on various different machines around the place,
some of which run Apache/mod_perl and some of which run Microsoft IIS/CGI, so I
really want one solution which works in both environments if at all possible.

> [This is all from my memory, so I hope I have the details correct]
>
> Under mod_cgi Apache will receive the SIGPIPE when it tries to print to the
> socket.  Since your CGI script is running as a subprocess (that has been
> marked "kill_after_timeout", I believe), apache will first close the pipe
> from your CGI program, send it a SIGTERM, wait three seconds, then send a
> SIGKILL, and then reap.  This all happens in alloc.c, IIRC.
>
> This is basically the same thing that happens when you have a timeout.
>
> So, you can catch SIGTERM and then have three seconds to clean up.  You
> won't see a SIGPIPE unless you try to print in that three second gap.

I'm fairly sure the program does print in any given three second gap -- I see
the "x"s appearing in my browser window (since output is "unbuffered") at the
rate of two or three per second, so I really should get the SIGPIPE.

I've also tried adding in a similar handler to try and catch a SIGTERM and
exit(), but that doesn't seem to work either.

Has anybody else had any luck responding to "Stop" on NT?

===

the rest of The Pile (a partial mailing list archive)

doom@kzsu.stanford.edu