R
Rob Young
Hi;
I spent about 4 hours searching through newsgroups, faqs, and O'reilly
books with various odd-smelling desert animals on the cover. I found
that this question has been asked A LOT, but none of the answers worked
for me. I'm posting this in hopes it will help someone else, and to
solicit comments on why the other methods did not work and whether this
is the best way.
The problem: You are batching e-mails to a large number of subscribers,
and you don't want the CGI script to wait until the mail process
finishes before completing the page.
Many people wrote to just put
$|=1;
at the top of your script. I am using the Mail::Bulkmail module, so
I tried this down near the end of the routine after the $bulk object had
been defined.
$|=1;
print "";
print qq(Thank you.... );
$bulk->bulkmail() or die $bulk->error;
and the script hesitated for 17 seconds before printing the thankyou
statement, just as it did without the buffer change. Mail was delivered OK.
Then I tried forking it like this:
if (my $pid = fork) {
print qq(Thank you.... );
} else {
die "cannot fork: $!" unless defined $pid;
$bulk->bulkmail() or die $bulk->error;
}
No difference.
Then I tried closing STDOUT
$|=1;
print "";
if (my $pid = fork) {
print qq(Thank you.... );
close(STDOUT);close(STDERR);
} else {
die "cannot fork: $!" unless defined $pid;
$bulk->bulkmail() or die $bulk->error;
}
That got instant results, but no mail was sent. I'm guessing
that Apache terminated the process when STDOUT closed?
Some people wrote to write the entire script to a new file and
then use system() to call it, but this script needs to be portable,
and some CGI wrappers don't allow system() calls or backticks.
This is what finally worked:
$|=1;
print "";
if (my $pid = fork) {
print qq(Thank you.... );
kill("KILLBUFFER"=>$$);
} else {
die "cannot fork: $!" unless defined $pid;
$bulk->bulkmail() or die $bulk->error;
}
Comments or suggestions welcome.
Rob
I spent about 4 hours searching through newsgroups, faqs, and O'reilly
books with various odd-smelling desert animals on the cover. I found
that this question has been asked A LOT, but none of the answers worked
for me. I'm posting this in hopes it will help someone else, and to
solicit comments on why the other methods did not work and whether this
is the best way.
The problem: You are batching e-mails to a large number of subscribers,
and you don't want the CGI script to wait until the mail process
finishes before completing the page.
Many people wrote to just put
$|=1;
at the top of your script. I am using the Mail::Bulkmail module, so
I tried this down near the end of the routine after the $bulk object had
been defined.
$|=1;
print "";
print qq(Thank you.... );
$bulk->bulkmail() or die $bulk->error;
and the script hesitated for 17 seconds before printing the thankyou
statement, just as it did without the buffer change. Mail was delivered OK.
Then I tried forking it like this:
if (my $pid = fork) {
print qq(Thank you.... );
} else {
die "cannot fork: $!" unless defined $pid;
$bulk->bulkmail() or die $bulk->error;
}
No difference.
Then I tried closing STDOUT
$|=1;
print "";
if (my $pid = fork) {
print qq(Thank you.... );
close(STDOUT);close(STDERR);
} else {
die "cannot fork: $!" unless defined $pid;
$bulk->bulkmail() or die $bulk->error;
}
That got instant results, but no mail was sent. I'm guessing
that Apache terminated the process when STDOUT closed?
Some people wrote to write the entire script to a new file and
then use system() to call it, but this script needs to be portable,
and some CGI wrappers don't allow system() calls or backticks.
This is what finally worked:
$|=1;
print "";
if (my $pid = fork) {
print qq(Thank you.... );
kill("KILLBUFFER"=>$$);
} else {
die "cannot fork: $!" unless defined $pid;
$bulk->bulkmail() or die $bulk->error;
}
Comments or suggestions welcome.
Rob