summaryrefslogtreecommitdiff
path: root/FS/bin/freeside-queued
diff options
context:
space:
mode:
Diffstat (limited to 'FS/bin/freeside-queued')
-rw-r--r--FS/bin/freeside-queued176
1 files changed, 176 insertions, 0 deletions
diff --git a/FS/bin/freeside-queued b/FS/bin/freeside-queued
new file mode 100644
index 000000000..56475d059
--- /dev/null
+++ b/FS/bin/freeside-queued
@@ -0,0 +1,176 @@
+#!/usr/bin/perl -w
+
+use strict;
+use vars qw( $log_file $sigterm $sigint );
+use subs qw( _die _logmsg );
+use Fcntl qw(:flock);
+use POSIX qw(setsid);
+use Date::Format;
+use IO::File;
+use FS::UID qw(adminsuidsetup forksuidsetup driver_name);
+use FS::Record qw(qsearchs);
+use FS::queue;
+
+# no autoloading just yet
+use FS::cust_main;
+use FS::svc_acct;
+use Net::SSH 0.05;
+
+my $pid_file = '/var/run/freeside-queued.pid';
+
+my $user = shift or die &usage;
+
+&daemonize;
+
+sub REAPER { my $pid = wait; $SIG{CHLD} = \&REAPER; }
+$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++; };
+
+$> = $FS::UID::freeside_uid unless $>;
+$< = $>;
+$ENV{HOME} = (getpwuid($>))[7]; #for ssh
+adminsuidsetup $user;
+
+$log_file = "/usr/local/etc/freeside/queuelog.". $FS::UID::datasrc;
+
+$SIG{__DIE__} = \&_die;
+$SIG{__WARN__} = \&_logmsg;
+
+warn "freeside-queued starting\n";
+
+while (1) {
+
+ my $job = qsearchs(
+ 'queue',
+ { 'status' => 'new' },
+ '',
+ driver_name =~ /^mysql$/i
+ ? 'ORDER BY jobnum LIMIT 1 FOR UPDATE'
+ : 'ORDER BY jobnum FOR UPDATE LIMIT 1'
+ ) or do {
+ sleep 5;
+ next;
+ };
+
+ my %hash = $job->hash;
+ $hash{'status'} = 'locked';
+ my $ljob = new FS::queue ( \%hash );
+ my $error = $ljob->replace($job);
+ die $error if $error;
+
+ my @args = $ljob->args;
+
+ # number of children limit?
+ 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;
+ };
+
+ unless ( $pid ) { #kid time
+
+ #get new db handles
+ $FS::UID::dbh->{InactiveDestroy} = 1;
+ $FS::svc_acct::icradius_dbh->{InactiveDestroy} = 1
+ if $FS::svc_acct::icradius_dbh;
+ forksuidsetup($user);
+
+ my $eval = "&". $ljob->job. '(@args);';
+ warn "running $eval";
+ eval $eval;
+ 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 daemonize {
+
+ 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: $!";
+
+}
+
+=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
+