X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2Fbin%2Ffreeside-queued;h=3a0a9b4e50d76a34b867ebe429f5d612a47bda4a;hb=ee27da6c4fdef689b9c32e9e84a7aa94648e2298;hp=a3fb7e562a577ff35d942813fa7a132c0567618f;hpb=6cf964d0dc008621fb30fd2da28e2c44f29c6364;p=freeside.git diff --git a/FS/bin/freeside-queued b/FS/bin/freeside-queued deleted file mode 100644 index a3fb7e562..000000000 --- a/FS/bin/freeside-queued +++ /dev/null @@ -1,315 +0,0 @@ -#!/usr/bin/perl -w - -use strict; -use vars qw( $log_file $sigterm $sigint $kids $max_kids %kids ); -use subs qw( _die _logmsg ); -use Fcntl qw(:flock); -use POSIX qw(:sys_wait_h setsid); -use Date::Format; -use IO::File; -use FS::UID qw(adminsuidsetup forksuidsetup driver_name dbh myconnect); -use FS::Record qw(qsearch qsearchs); -use FS::queue; -use FS::queue_depend; - -# no autoloading just yet -use FS::cust_main; -use FS::svc_acct; -use Net::SSH 0.07; -use FS::part_export; - -$max_kids = '10'; #guess it should be a config file... -$kids = 0; - -my $user = shift or die &usage; - -#my $pid_file = "/var/run/freeside-queued.$user.pid"; -my $pid_file = "/var/run/freeside-queued.pid"; - -&daemonize1; - -#sub REAPER { my $pid = wait; $SIG{CHLD} = \&REAPER; $kids--; } -#$SIG{CHLD} = \&REAPER; - -$sigterm = 0; -$sigint = 0; -$SIG{INT} = sub { warn "SIGINT received; shutting down\n"; $sigint++; }; -$SIG{TERM} = sub { warn "SIGTERM received; shutting down\n"; $sigterm++; }; - -my $freeside_gid = scalar(getgrnam('freeside')) - or die "can't setgid to freeside group\n"; -$) = $freeside_gid; -$( = $freeside_gid; -#if freebsd can't setuid(), presumably it can't setgid() either. grr fleabsd -($(,$)) = ($),$(); -$) = $freeside_gid; - -$> = $FS::UID::freeside_uid; -$< = $FS::UID::freeside_uid; -#freebsd is sofa king broken, won't setuid() -($<,$>) = ($>,$<); -$> = $FS::UID::freeside_uid; - -$ENV{HOME} = (getpwuid($>))[7]; #for ssh - -$@ = 'not connected'; -while ( $@ ) { - eval { adminsuidsetup $user; }; - if ( $@ ) { - warn $@; - warn "sleeping for reconnect...\n"; - sleep 5; - } -} - -$log_file = "/usr/local/etc/freeside/queuelog.". $FS::UID::datasrc; - -&daemonize2; - -$SIG{__DIE__} = \&_die; -$SIG{__WARN__} = \&_logmsg; - -warn "freeside-queued starting\n"; - -my $warnkids=0; -while (1) { - - &reap_kids; - #prevent runaway forking - if ( $kids >= $max_kids ) { - warn "WARNING: maximum $kids children reached\n" unless $warnkids++; - &reap_kids; - sleep 1; #waiting for signals is cheap - next; - } - $warnkids=0; - - unless ( dbh && dbh->ping ) { - warn "WARNING: connection to database lost, reconnecting...\n"; - - eval { $FS::UID::dbh = myconnect; }; - - unless ( !$@ && dbh && dbh->ping ) { - warn "WARNING: still no connection to database, sleeping for retry...\n"; - sleep 10; - next; - } else { - warn "WARNING: reconnected to database\n"; - } - } - - #my($job, $ljob); - #{ - # my $oldAutoCommit = $FS::UID::AutoCommit; - # local $FS::UID::AutoCommit = 0; - $FS::UID::AutoCommit = 0; - - #assuming mysql 4.1 w/subqueries now - #my $nodepend = driver_name eq 'mysql' - # ? '' - # : 'AND 0 = ( SELECT COUNT(*) FROM queue_depend'. - # ' WHERE queue_depend.jobnum = queue.jobnum ) '; - my $nodepend = 'AND 0 = ( SELECT COUNT(*) FROM queue_depend'. - ' WHERE queue_depend.jobnum = queue.jobnum ) '; - - my $job = qsearchs( - 'queue', - { 'status' => 'new' }, - '', - driver_name eq 'mysql' - ? "$nodepend ORDER BY jobnum LIMIT 1 FOR UPDATE" - : "$nodepend ORDER BY jobnum FOR UPDATE LIMIT 1" - ) or do { - # if $oldAutoCommit { - dbh->commit or do { - warn "WARNING: database error, closing connection: ". dbh->errstr; - undef $FS::UID::dbh; - next; - }; - # } - sleep 5; #connecting to db is expensive - next; - }; - - #assuming mysql 4.1 w/subqueries now - #if ( driver_name eq 'mysql' - # && qsearch('queue_depend', { 'jobnum' => $job->jobnum } ) ) { - # dbh->commit or die dbh->errstr; #if $oldAutoCommit; - # sleep 5; #would be better if mysql could do everything in query above - # next; - #} - - my %hash = $job->hash; - $hash{'status'} = 'locked'; - my $ljob = new FS::queue ( \%hash ); - my $error = $ljob->replace($job); - if ( $error ) { - warn "WARNING: database error locking job, closing connection: ". - dbh->errstr; - undef $FS::UID::dbh; - next; - } - - # if $oldAutoCommit { - dbh->commit or do { - warn "WARNING: database error, closing connection: ". dbh->errstr; - undef $FS::UID::dbh; - next; - }; - # } - - $FS::UID::AutoCommit = 1; - #} - - my @args = $ljob->args; - splice @args, 0, 1, $ljob if $args[0] eq '_JOB'; - - defined( my $pid = fork ) or do { - warn "WARNING: can't fork: $!\n"; - my %hash = $job->hash; - $hash{'status'} = 'failed'; - $hash{'statustext'} = "[freeside-queued] can't fork: $!"; - my $ljob = new FS::queue ( \%hash ); - my $error = $ljob->replace($job); - die $error if $error; - next; #don't increment the kid counter - }; - - if ( $pid ) { - $kids++; - $kids{$pid} = 1; - } else { #kid time - - #get new db handle - $FS::UID::dbh->{InactiveDestroy} = 1; - - forksuidsetup($user); - - #auto-use classes... - #if ( $ljob->job =~ /(FS::part_export::\w+)::/ ) { - if ( $ljob->job =~ /(FS::part_export::\w+)::/ - || $ljob->job =~ /(FS::\w+)::/ - ) - { - my $class = $1; - eval "use $class;"; - if ( $@ ) { - warn "job use $class failed"; - my %hash = $ljob->hash; - $hash{'status'} = 'failed'; - $hash{'statustext'} = $@; - my $fjob = new FS::queue( \%hash ); - my $error = $fjob->replace($ljob); - die $error if $error; - exit; #end-of-kid - }; - } - - my $eval = "&". $ljob->job. '(@args);'; - warn "running $eval"; - eval $eval; #throw away return value? suppose so - if ( $@ ) { - warn "job $eval failed"; - my %hash = $ljob->hash; - $hash{'status'} = 'failed'; - $hash{'statustext'} = $@; - my $fjob = new FS::queue( \%hash ); - my $error = $fjob->replace($ljob); - die $error if $error; - } else { - $ljob->delete; - } - - exit; - #end-of-kid - } - -} continue { - if ( $sigterm ) { - warn "received TERM signal; exiting\n"; - exit; - } - if ( $sigint ) { - warn "received INT signal; exiting\n"; - exit; - } -} - -sub usage { - die "Usage:\n\n freeside-queued user\n"; -} - -sub _die { - my $msg = shift; - unlink $pid_file if -e $pid_file; - _logmsg($msg); -} - -sub _logmsg { - chomp( my $msg = shift ); - my $log = new IO::File ">>$log_file"; - flock($log, LOCK_EX); - seek($log, 0, 2); - print $log "[". time2str("%a %b %e %T %Y",time). "] [$$] $msg\n"; - flock($log, LOCK_UN); - close $log; -} - -sub daemonize1 { - - chdir "/" or die "Can't chdir to /: $!"; - open STDIN, '/dev/null' or die "Can't read /dev/null: $!"; - defined(my $pid = fork) or die "Can't fork: $!"; - if ( $pid ) { - print "freeside-queued started with pid $pid\n"; #logging to $log_file\n"; - exit unless $pid_file; - my $pidfh = new IO::File ">$pid_file" or exit; - print $pidfh "$pid\n"; - exit; - } - #open STDOUT, '>/dev/null' - # or die "Can't write to /dev/null: $!"; - #setsid or die "Can't start a new session: $!"; - #open STDERR, '>&STDOUT' or die "Can't dup stdout: $!"; - -} - -sub daemonize2 { - open STDOUT, '>/dev/null' - or die "Can't write to /dev/null: $!"; - setsid or die "Can't start a new session: $!"; - open STDERR, '>&STDOUT' or die "Can't dup stdout: $!"; -} - -sub reap_kids { - foreach my $pid ( keys %kids ) { - my $kid = waitpid($pid, WNOHANG); - if ( $kid > 0 ) { - $kids--; - delete $kids{$kid}; - } - } -} - -=head1 NAME - -freeside-queued - Job queue daemon - -=head1 SYNOPSIS - - freeside-queued user - -=head1 DESCRIPTION - -Job queue daemon. Should be running at all times. - -user: from the mapsecrets file - see config.html from the base documentation - -=head1 VERSION - -=head1 BUGS - -=head1 SEE ALSO - -=cut -