[interchange-cvs] interchange - jon modified 2 files
interchange-cvs at icdevgroup.org
interchange-cvs at icdevgroup.org
Fri Dec 19 04:47:43 UTC 2008
User: jon
Date: 2008-12-19 04:47:42 GMT
Modified: code/UserTag child-process.tag
Modified: lib/Vend Server.pm
Log:
Fix design flaw in the new child-process tag:
* Need to double-fork and close sockets and filehandles to disconnect from
the parent process so that the parent doesn't wait for the child to finish.
* Add a new routine &Vend::Server::cleanup_for_exec to handle clearing the
private socket variables, usable from other child code as well.
* Can no longer return a useful PID because of the double-fork, so return
nothing from the tag.
Some other tweaks as well:
* Change process description and allow it to be customized, especially
useful for long-running processes.
* Don't bother retrying if fork attempts fail, as that gets prohibitively
complicated on double-forks and probably indicates a suffocating system
we shouldn't add load to anyway.
* For now, at least, don't bother with optional single-fork implementation
which is mostly useful for a tiny bit of improved performance that's not
worth the hassle for a background process.
* Ignore not just an empty body, but also one with only whitespace.
* Remove documentation for unimplemented umask option.
Revision Changes Path
1.2 interchange/code/UserTag/child-process.tag
rev 1.2, prev_rev 1.1
Index: child-process.tag
===================================================================
RCS file: /var/cvs/interchange/code/UserTag/child-process.tag,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -u -r1.1 -r1.2
--- child-process.tag 14 Dec 2008 10:06:04 -0000 1.1
+++ child-process.tag 19 Dec 2008 04:47:42 -0000 1.2
@@ -1,15 +1,17 @@
-# Copyright 2002-2007 Interchange Development Group and others
+# Copyright 2008 Interchange Development Group and others
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version. See the LICENSE file for details.
#
-# $Id: child-process.tag,v 1.1 2008-12-14 10:06:04 ton Exp $
+# $Id: child-process.tag,v 1.2 2008-12-19 04:47:42 jon Exp $
UserTag child-process addAttr
UserTag child-process HasEndTag
-UserTag child-process Version $Revision: 1.1 $
+UserTag child-process NoReparse 0
+UserTag child-process Interpolate 0
+UserTag child-process Version $Revision: 1.2 $
UserTag child-process Documentation <<EOD
=head1 NAME
@@ -25,6 +27,8 @@
Runs Interchange markup code in a forked child process.
Useful for off-loading processes that take a relatively long time to complete.
+Has no effect if the body is empty or contains only whitespace.
+
Options are:
=over 4
@@ -34,6 +38,11 @@
File name relative to catalog directory to file where output from forked
process should be stored.
+=item label
+
+Optional descriptive label for this process that will be put in the operating
+system process list. Default is "child-process tag".
+
=item notifyname
File name relative to catalog directory where a file of zero length will
@@ -44,18 +53,14 @@
in web docroot space one could poll for the existence of this file and
when it exists bounce to a page that will display the results.
-=item umask
-
-Octal umask for notification file.
-
=back
=head1 EXAMPLES
This is the parent process.
- Child process starts here:<br>
- Child PID: [child-process filename="tmp/report_[time]%Y%m%d%H%M%S[/time].txt"]
+ Child process starts here.
+ [child-process filename="tmp/report_[time]%Y%m%d%H%M%S[/time].txt"]
[query
list=1
sql="
@@ -79,55 +84,47 @@
EOD
UserTag child-process Routine <<EOR
+
+use POSIX ();
+
sub {
- my ($opt, $body) = @_;
- use vars qw/ $Tag /;
+ my ($opt, $body) = @_;
+ use vars qw/ $Tag /;
- return unless defined($body) and length($body);
+ return unless defined($body) and $body =~ /\S/;
- my $pid;
+ defined(my $kid = fork) or die "Cannot fork: $!\n";
+ if ($kid) {
+ waitpid($kid, 0);
+ return;
+ }
+ else {
+ defined (my $grandkid = fork) or die "Kid cannot fork: $!\n";
+ exit if $grandkid;
+
+ Vend::Server::cleanup_for_exec();
+
+ # Disconnect from parent's terminal
+ POSIX::setsid() or die "Can't start a new session: $!\n";
+
+ defined $opt->{label} or $opt->{label} = 'child-process tag';
+ Vend::Server::set_process_name($opt->{label});
+
+ my $output = interpolate_html($body, 1);
+
+ my $filename = $opt->{filename};
+ if (defined($filename) and length($filename)) {
+ $filename = $Tag->filter('filesafe', $filename);
+ my $status = $Tag->write_relative_file($filename, $$output);
+
+ my $notifyname = $opt->{notifyname};
+ if ($status and defined($notifyname) and length($notifyname)) {
+ $notifyname = $Tag->filter('filesafe', $notifyname);
+ $Tag->write_relative_file($notifyname, $opt, '');
+ }
+ }
- FORK: {
- if ($pid = fork) {
- # Parent
- # As parent we have no tasks to perform at this place
- # we only want to off-load 'heavy' processes to a child process
- # The main reason for this Usertag
-
- return $pid;
- }
- elsif (defined $pid) {
- # Child
-
- Vend::Server::reset_per_fork();
-
- my $output = interpolate_html($body, 1);
- if (defined($$output) and length($$output)) {
- my $filename = $opt->{filename};
- if (defined($filename) and length($filename)) {
- $filename = $Tag->filter('filesafe', $filename);
- my $status = $Tag->write_relative_file($filename, $$output);
-
- my $notifyname = $opt->{notifyname};
- if ($status and defined($notifyname) and length($notifyname)) {
- $notifyname = $Tag->filter('filesafe', $notifyname);
- $Tag->write_relative_file($notifyname, $opt, '');
- }
-
- }
- }
-
- exit;
- }
- elsif ($! =~ /No more process/) {
- # Supposedly recoverable fork error
- select(undef, undef, undef, 2.00);
- redo FORK;
- }
- else {
- # Weird fork error
- die "Can't fork: $!\n";
- }
- }
+ exit;
+ }
}
EOR
2.95 interchange/lib/Vend/Server.pm
rev 2.95, prev_rev 2.94
Index: Server.pm
===================================================================
RCS file: /var/cvs/interchange/lib/Vend/Server.pm,v
retrieving revision 2.94
retrieving revision 2.95
diff -u -u -r2.94 -r2.95
--- Server.pm 19 Dec 2008 04:37:44 -0000 2.94
+++ Server.pm 19 Dec 2008 04:47:42 -0000 2.95
@@ -1,6 +1,6 @@
# Vend::Server - Listen for Interchange CGI requests as a background server
#
-# $Id: Server.pm,v 2.94 2008-12-19 04:37:44 jon Exp $
+# $Id: Server.pm,v 2.95 2008-12-19 04:47:42 jon Exp $
#
# Copyright (C) 2002-2008 Interchange Development Group
# Copyright (C) 1996-2002 Red Hat, Inc.
@@ -26,7 +26,7 @@
package Vend::Server;
use vars qw($VERSION);
-$VERSION = substr(q$Revision: 2.94 $, 10);
+$VERSION = substr(q$Revision: 2.95 $, 10);
use Cwd;
use POSIX qw(setsid strftime);
@@ -3074,6 +3074,25 @@
return;
}
+# Disconnect child process from any dangling attachments to parent process.
+# Named after similar mod_perl routine.
+sub cleanup_for_exec {
+ # Release any open sockets
+ %fh_map = %vec_map = %s_vec_map = %s_fh_map = %ipc_socket = %unix_socket
+ = ();
+
+ # Close filehandles except for STDERR, used for debug log
+ close MESSAGE;
+ close SOCK;
+ open STDIN, '<', '/dev/null';
+ open STDOUT, '>>', '/dev/null';
+
+ # Clear any cached DBI handles
+ reset_per_fork();
+
+ return;
+}
+
1;
__END__
More information about the interchange-cvs
mailing list