diff options
author | ivan <ivan> | 2001-09-11 00:08:18 +0000 |
---|---|---|
committer | ivan <ivan> | 2001-09-11 00:08:18 +0000 |
commit | f5266a4d07d116efd732f433d0f4f3a47b143a7d (patch) | |
tree | 30b5bd95a9d3b3c588ab097f1877ae0d27e96741 /FS | |
parent | 85e59606c0b5eed9780534ffaf554aa32bcf9baf (diff) |
faster (cached) fuzzy searches
prelim. job queues!
fixed part_svc editing
Diffstat (limited to 'FS')
-rw-r--r-- | FS/FS.pm | 8 | ||||
-rw-r--r-- | FS/FS/Record.pm | 21 | ||||
-rw-r--r-- | FS/FS/cust_credit_bill.pm | 10 | ||||
-rw-r--r-- | FS/FS/cust_main.pm | 143 | ||||
-rw-r--r-- | FS/FS/part_svc.pm | 63 | ||||
-rw-r--r-- | FS/FS/queue.pm | 174 | ||||
-rw-r--r-- | FS/FS/queue_arg.pm | 121 | ||||
-rw-r--r-- | FS/MANIFEST | 5 | ||||
-rwxr-xr-x | FS/bin/freeside-bill | 4 | ||||
-rw-r--r-- | FS/bin/freeside-queued | 145 | ||||
-rw-r--r-- | FS/t/queue.t | 5 | ||||
-rw-r--r-- | FS/t/queue_arg.t | 5 |
12 files changed, 687 insertions, 17 deletions
@@ -93,7 +93,7 @@ L<FS::cust_refund> - Refund class L<FS::cust_credit_refund> - Refund application class -L<FS::cust_credit_bill> - Refund invoice application class +L<FS::cust_credit_bill> - Credit invoice application class L<FS::cust_pay_batch> - Credit card transaction queue class @@ -105,6 +105,10 @@ L<FS::port> - NAS port class L<FS::session> - User login session class +L<FS::queue> - Job queue + +L<FS::queue_arg> - Job arguments + =head2 User Interface classes (under development; not yet usable) L<FS::UI::Base> - User-interface base class @@ -135,7 +139,7 @@ The main documentation is in htdocs/docs. =head1 VERSION -$Id: FS.pm,v 1.7 2001-09-06 20:41:59 ivan Exp $ +$Id: FS.pm,v 1.8 2001-09-11 00:08:18 ivan Exp $ =head1 SUPPORT diff --git a/FS/FS/Record.pm b/FS/FS/Record.pm index 9a532e3..b476df2 100644 --- a/FS/FS/Record.pm +++ b/FS/FS/Record.pm @@ -855,13 +855,30 @@ Untaints arbitrary data. Be careful. =cut sub ut_anything { - my($self,$field)=@_; + my( $self, $field ) = @_; $self->getfield($field) =~ /^(.*)$/s or return "Illegal $field: ". $self->getfield($field); $self->setfield($field,$1); ''; } +=item ut_enum COLUMN CHOICES_ARRAYREF + +Check/untaint a column, supplying all possible choices, like the "enum" type. + +=cut + +sub ut_enum { + my( $self, $field, $choices ) = @_; + foreach my $choice ( @$choices ) { + if ( $self->getfield($field) eq $choice ) { + $self->setfield($choice); + return ''; + } + } + return "Illegal (enum) field $field: ". $self->getfield($field); +} + =item fields [ TABLE ] This can be used as both a subroutine and a method call. It returns a list @@ -976,7 +993,7 @@ sub DESTROY { return; } =head1 VERSION -$Id: Record.pm,v 1.26 2001-08-31 09:20:35 ivan Exp $ +$Id: Record.pm,v 1.27 2001-09-11 00:08:18 ivan Exp $ =head1 BUGS diff --git a/FS/FS/cust_credit_bill.pm b/FS/FS/cust_credit_bill.pm index 58cc789..9613408 100644 --- a/FS/FS/cust_credit_bill.pm +++ b/FS/FS/cust_credit_bill.pm @@ -33,12 +33,14 @@ FS::cust_credit_bill - Object methods for cust_credit_bill records =head1 DESCRIPTION An FS::cust_credit_bill object represents application of a credit (see -L<FS::cust_credit>) to a customer bill (see L<FS::cust_bill>). FS::cust_credit +L<FS::cust_credit>) to an invoice (see L<FS::cust_bill>). FS::cust_credit inherits from FS::Record. The following fields are currently supported: =over 4 -=item crednum - primary key; credit being applied +=item creditbillnum - primary key + +=item crednum - credit being applied =item invnum - invoice to which credit is applied (see L<FS::cust_bill>) @@ -119,7 +121,7 @@ sub check { $self->_date(time) unless $self->_date; - return "Cannot apply more than remaining value of credit memo" + return "Cannot apply more than remaining value of credit" unless $self->amount <= $cust_credit->credited; return "Cannot apply more than remaining value of invoice" @@ -143,7 +145,7 @@ sub cust_credit { =head1 VERSION -$Id: cust_credit_bill.pm,v 1.4 2001-09-02 07:49:52 ivan Exp $ +$Id: cust_credit_bill.pm,v 1.5 2001-09-11 00:08:18 ivan Exp $ =head1 BUGS diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index b29e385..e4f55cf 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -31,6 +31,7 @@ use FS::cust_main_invoice; use FS::cust_credit_bill; use FS::cust_bill_pay; use FS::prepay_credit; +use FS::queue; @ISA = qw( FS::Record ); @@ -343,6 +344,22 @@ sub insert { } } + my $queue = new FS::queue { 'job' => 'FS::cust_main::append_fuzzyfiles' }; + $error = $queue->insert($self->getfield('last'), $self->company); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "queueing job (transaction rolled back): $error"; + } + + if ( defined $self->dbdef_table->column('ship_last') && $self->ship_last ) { + $queue = new FS::queue { 'job' => 'FS::cust_main::append_fuzzyfiles' }; + $error = $queue->insert($self->getfield('last'), $self->company); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "queueing job (transaction rolled back): $error"; + } + } + $dbh->commit or die $dbh->errstr if $oldAutoCommit; ''; @@ -1533,24 +1550,140 @@ sub referral_cust_main { =over 4 -=item rebuild_fuzzyfile +=item check_and_rebuild_fuzzyfiles + +=cut + +sub check_and_rebuild_fuzzyfiles { + my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc; + -e "$dir/cust_main.last" && -e "$dir/cust_main.company" + or &rebuild_fuzzyfiles; +} + +=item rebuild_fuzzyfiles =cut sub rebuild_fuzzyfiles { + + use Fcntl qw(:flock); + + my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc; + + #last + + open(LASTLOCK,">>$dir/cust_main.last") + or die "can't open $dir/cust_main.last: $!"; + flock(LASTLOCK,LOCK_EX) + or die "can't lock $dir/cust_main.last: $!"; + my @all_last = map $_->getfield('last'), qsearch('cust_main', {}); push @all_last, grep $_, map $_->getfield('ship_last'), qsearch('cust_main',{}) - if defined dbdef->table('cust_main')->column('ship_last'); -# open( + if defined dbdef->table('cust_main')->column('ship_last'); + + open (LASTCACHE,">$dir/cust_main.last.tmp") + or die "can't open $dir/cust_main.last.tmp: $!"; + print LASTCACHE join("\n", @all_last), "\n"; + close LASTCACHE or die "can't close $dir/cust_main.last.tmp: $!"; + + rename "$dir/cust_main.last.tmp", "$dir/cust_main.last"; + close LASTLOCK; + + #company + + open(COMPANYLOCK,">>$dir/cust_main.company") + or die "can't open $dir/cust_main.company: $!"; + flock(COMPANYLOCK,LOCK_EX) + or die "can't lock $dir/cust_main.company: $!"; + + my @all_company = grep $_ ne '', map $_->company, qsearch('cust_main',{}); + push @all_company, + grep $_ ne '', map $_->ship_company, qsearch('cust_main', {}) + if defined dbdef->table('cust_main')->column('ship_last'); + + open (COMPANYCACHE,">$dir/cust_main.company.tmp") + or die "can't open $dir/cust_main.company.tmp: $!"; + print COMPANYCACHE join("\n", @all_company), "\n"; + close COMPANYCACHE or die "can't close $dir/cust_main.company.tmp: $!"; + + rename "$dir/cust_main.company.tmp", "$dir/cust_main.company"; + close COMPANYLOCK; } -=back +=item all_last + +=cut + +sub all_last { + my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc; + open(LASTCACHE,"<$dir/cust_main.last") + or die "can't open $dir/cust_main.last: $!"; + my @array = split(/\n/, <LASTCACHE> ); + close LASTCACHE; + \@array; +} + +=item all_company + +=cut + +sub all_company { + my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc; + open(COMPANYCACHE,"<$dir/cust_main.company") + or die "can't open $dir/cust_main.last: $!"; + my @array = split(/\n/, <COMPANYCACHE> ); + close COMPANYCACHE; + \@array; +} + +=item append_fuzzyfiles LASTNAME COMPANY + +=cut + +sub append_fuzzyfiles { + my( $last, $company ) = @_; + + use Fcntl qw(:flock); + + my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc; + + if ( $last ) { + + open(LAST,">>$dir/cust_main.last") + or die "can't open $dir/cust_main.last: $!"; + flock(LAST,LOCK_EX) + or die "can't lock $dir/cust_main.last: $!"; + + print LAST "$last\n"; + + flock(LAST,LOCK_UN) + or die "can't unlock $dir/cust_main.last: $!"; + close LAST; + } + + if ( $company ) { + + open(COMPANY,">>$dir/cust_main.company") + or die "can't open $dir/cust_main.company: $!"; + flock(COMPANY,LOCK_EX) + or die "can't lock $dir/cust_main.company: $!"; + + print COMPANY "$company\n"; + + flock(COMPANY,LOCK_UN) + or die "can't unlock $dir/cust_main.company: $!"; + + close COMPANY; + } + + 1; +} =head1 VERSION -$Id: cust_main.pm,v 1.29 2001-09-03 22:07:38 ivan Exp $ +$Id: cust_main.pm,v 1.30 2001-09-11 00:08:18 ivan Exp $ =head1 BUGS diff --git a/FS/FS/part_svc.pm b/FS/FS/part_svc.pm index e64f09a..f1e71ad 100644 --- a/FS/FS/part_svc.pm +++ b/FS/FS/part_svc.pm @@ -117,7 +117,7 @@ sub insert { $error = $part_svc_column->insert; } } else { - $error = $part_svc_column->delete; + $error = $previous ? $previous->delete : ''; } if ( $error ) { $dbh->rollback if $oldAutoCommit; @@ -155,7 +155,64 @@ sub replace { return "Can't change svcdb for an existing service definition!" unless $old->svcdb eq $new->svcdb; - $new->SUPER::replace( $old ); + local $SIG{HUP} = 'IGNORE'; + local $SIG{INT} = 'IGNORE'; + local $SIG{QUIT} = 'IGNORE'; + local $SIG{TERM} = 'IGNORE'; + local $SIG{TSTP} = 'IGNORE'; + local $SIG{PIPE} = 'IGNORE'; + + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + my $dbh = dbh; + + my $error = $new->SUPER::replace( $old ); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + if ( @_ && $_[0] eq '1.3-COMPAT' ) { + my $svcdb = $new->svcdb; + foreach my $field ( + grep { $_ ne 'svcnum' + && defined( $new->getfield($svcdb.'__'.$_.'_flag') ) + } fields($svcdb) + ) { + my $part_svc_column = $new->part_svc_column($field); + my $previous = qsearchs('part_svc_column', { + 'svcpart' => $new->svcpart, + 'columnname' => $field, + } ); + + my $flag = $new->getfield($svcdb.'__'.$field.'_flag'); + if ( uc($flag) =~ /^([DF])$/ ) { + $part_svc_column->setfield('columnflag', $1); + $part_svc_column->setfield('columnvalue', + $new->getfield($svcdb.'__'.$field) + ); + if ( $previous ) { + $error = $part_svc_column->replace($previous); + } else { + $error = $part_svc_column->insert; + } + } else { + $error = $previous ? $previous->delete : ''; + } + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } + } else { + $dbh->rollback if $oldAutoCommit; + return 'non-1.3-COMPAT interface not yet written'; + #not yet implemented + } + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + + ''; } =item check @@ -232,7 +289,7 @@ sub part_svc_column { =head1 VERSION -$Id: part_svc.pm,v 1.3 2001-09-06 20:41:59 ivan Exp $ +$Id: part_svc.pm,v 1.4 2001-09-11 00:08:18 ivan Exp $ =head1 BUGS diff --git a/FS/FS/queue.pm b/FS/FS/queue.pm new file mode 100644 index 0000000..51dd9af --- /dev/null +++ b/FS/FS/queue.pm @@ -0,0 +1,174 @@ +package FS::queue; + +use strict; +use vars qw( @ISA ); +use FS::Record qw( qsearch qsearchs dbh ); +use FS::queue_arg; + +@ISA = qw(FS::Record); + +=head1 NAME + +FS::queue - Object methods for queue records + +=head1 SYNOPSIS + + use FS::queue; + + $record = new FS::queue \%hash; + $record = new FS::queue { 'column' => 'value' }; + + $error = $record->insert; + + $error = $new_record->replace($old_record); + + $error = $record->delete; + + $error = $record->check; + +=head1 DESCRIPTION + +An FS::queue object represents an queued job. FS::queue inherits from +FS::Record. The following fields are currently supported: + +=over 4 + +=item jobnum - primary key + +=item job - fully-qualified subroutine name + +=item status - job status + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +Creates a new job. To add the example to the database, see L<"insert">. + +Note that this stores the hash reference, not a distinct copy of the hash it +points to. You can ask the object for a copy with the I<hash> method. + +=cut + +# the new method can be inherited from FS::Record, if a table method is defined + +sub table { 'queue'; } + +=item insert [ ARGUMENT, ARGUMENT... ] + +Adds this record to the database. If there is an error, returns the error, +otherwise returns false. + +If any arguments are supplied, a queue_arg record for each argument is also +created (see L<FS::queue_arg>). + +=cut + +sub insert { + my $self = shift; + + local $SIG{HUP} = 'IGNORE'; + local $SIG{INT} = 'IGNORE'; + local $SIG{QUIT} = 'IGNORE'; + local $SIG{TERM} = 'IGNORE'; + local $SIG{TSTP} = 'IGNORE'; + local $SIG{PIPE} = 'IGNORE'; + + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + my $dbh = dbh; + + my $error = $self->SUPER::insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + foreach my $arg ( @_ ) { + my $queue_arg = new FS::queue_arg ( { + 'jobnum' => $self->jobnum, + 'arg' => $arg, + } ); + $error = $queue_arg->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + + ''; + +} + +=item delete + +Delete this record from the database. + +=cut + +# the delete method can be inherited from FS::Record + +=item replace OLD_RECORD + +Replaces the OLD_RECORD with this one in the database. If there is an error, +returns the error, otherwise returns false. + +=cut + +# the replace method can be inherited from FS::Record + +=item check + +Checks all fields to make sure this is a valid job. If there is +an error, returns the error, otherwise returns false. Called by the insert +and replace methods. + +=cut + +sub check { + my $self = shift; + my $error = + $self->ut_numbern('jobnum') + || $self->ut_anything('job') + || $self->ut_numbern('_date') + || $self->ut_enum('status',['', qw( new locked failed )]) + ; + return $error if $error; + + $self->status('new') unless $self->status; + $self->_date(time) unless $self->_date; + + ''; #no error +} + +=item args + +=cut + +sub args { + my $self = shift; + map $_->arg, qsearch( 'queue_arg', { 'jobnum' => $self->jobnum } ); +} + +=back + +=head1 VERSION + +$Id: queue.pm,v 1.1 2001-09-11 00:08:18 ivan Exp $ + +=head1 BUGS + +=head1 SEE ALSO + +L<FS::Record>, schema.html from the base documentation. + +=cut + +1; + diff --git a/FS/FS/queue_arg.pm b/FS/FS/queue_arg.pm new file mode 100644 index 0000000..08fe473 --- /dev/null +++ b/FS/FS/queue_arg.pm @@ -0,0 +1,121 @@ +package FS::queue_arg; + +use strict; +use vars qw( @ISA ); +use FS::Record qw( qsearch qsearchs ); + +@ISA = qw(FS::Record); + +=head1 NAME + +FS::queue_arg - Object methods for queue_arg records + +=head1 SYNOPSIS + + use FS::queue_arg; + + $record = new FS::queue_arg \%hash; + $record = new FS::queue_arg { 'column' => 'value' }; + + $error = $record->insert; + + $error = $new_record->replace($old_record); + + $error = $record->delete; + + $error = $record->check; + +=head1 DESCRIPTION + +An FS::queue_arg object represents job argument. FS::queue_arg inherits from +FS::Record. The following fields are currently supported: + +=over 4 + +=item argnum - primary key + +=item jobnum - see L<FS::queue> + +=item arg - argument + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +Creates a new argument. To add the example to the database, see L<"insert">. + +Note that this stores the hash reference, not a distinct copy of the hash it +points to. You can ask the object for a copy with the I<hash> method. + +=cut + +# the new method can be inherited from FS::Record, if a table method is defined + +sub table { 'queue_arg'; } + +=item insert + +Adds this record to the database. If there is an error, returns the error, +otherwise returns false. + +=cut + +# the insert method can be inherited from FS::Record + +=item delete + +Delete this record from the database. + +=cut + +# the delete method can be inherited from FS::Record + +=item replace OLD_RECORD + +Replaces the OLD_RECORD with this one in the database. If there is an error, +returns the error, otherwise returns false. + +=cut + +# the replace method can be inherited from FS::Record + +=item check + +Checks all fields to make sure this is a valid argument. If there is +an error, returns the error, otherwise returns false. Called by the insert +and replace methods. + +=cut + +sub check { + my $self = shift; + my $error = + $self->ut_numbern('argnum') + || $self->ut_numbern('jobnum') + || $self->ut_anything('arg') + ; + return $error if $error; + + ''; #no error +} + +=back + +=head1 VERSION + +$Id: queue_arg.pm,v 1.1 2001-09-11 00:08:18 ivan Exp $ + +=head1 BUGS + +=head1 SEE ALSO + +L<FS::queue>, L<FS::Record>, schema.html from the base documentation. + +=cut + +1; + diff --git a/FS/MANIFEST b/FS/MANIFEST index ae3e0b0..69123db 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -6,6 +6,7 @@ README bin/freeside-bill bin/freeside-email bin/freeside-print-batch +bin/freeside-queued FS.pm FS/CGI.pm FS/Conf.pm @@ -51,6 +52,8 @@ FS/svc_www.pm FS/CGIwrapper.pm FS/svc_forward.pm FS/raddb.pm +FS/queue.pm +FS/queue_arg.pm t/agent.t t/agent_type.t t/CGI.t @@ -89,5 +92,7 @@ t/svc_domain.t t/svc_forward.t t/svc_www.t t/type_pkgs.t +t/queue.t +t/queue_arg.t t/UID.t t/raddb.t diff --git a/FS/bin/freeside-bill b/FS/bin/freeside-bill index 1dce9a1..82b3321 100755 --- a/FS/bin/freeside-bill +++ b/FS/bin/freeside-bill @@ -1,3 +1,5 @@ +#!/usr/bin/perl -w +# don't take any world-facing input #!/usr/bin/perl -Tw use strict; @@ -121,7 +123,7 @@ customers. Otherwise, bills all customers. =head1 VERSION -$Id: freeside-bill,v 1.8 2001-09-03 22:07:39 ivan Exp $ +$Id: freeside-bill,v 1.9 2001-09-11 00:08:18 ivan Exp $ =head1 BUGS diff --git a/FS/bin/freeside-queued b/FS/bin/freeside-queued new file mode 100644 index 0000000..5acffb5 --- /dev/null +++ b/FS/bin/freeside-queued @@ -0,0 +1,145 @@ +#!/usr/bin/perl -w + +use strict; +use Fcntl qw(:flock); +use POSIX qw(setsid); +use FS::UID qw(adminsuidsetup); +use FS::Record qw(qsearchs); +use FS::queue; + +# no autoloading just yet +use FS::cust_main; + +my $pid_file = '/var/run/freeside-queued.pid'; + +$SIG{CHLD} = sub { wait }; #zombie prevention + +my $sigterm = 0; +my $sigint = 0; +$SIG{INT} = sub { warn "SIGINT received; shutting down\n"; $sigint++; }; +$SIG{TERM} = sub { warn "SIGTERM received; shutting down\n"; $sigterm++; }; + +my $user = shift or die &usage; + +&daemonize; + +my $log_file = "/usr/local/etc/freeside/queuelog."; + +$> = $FS::UID::freeside_uid unless $>; +adminsuidsetup $user; + +$log_file = "/usr/local/etc/freeside/queuelog.". $FS::UID::datasrc; + +$SIG{__DIE__} = \&_die; +$SIG{__WARN__} = \&_logmsg; + + +while (1) { + + my $job = qsearchs( + 'queue', + { 'status' => 'new' }, + '', + '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; + + #fork a child for each job (up to some maximum perhaps?) + #single-threaded for now. + + my $eval = "&". $ljob->job. '(@args);'; + warn "running $eval"; + eval $eval; + if ( $@ ) { + warn "job $eval failed"; + my $hash = $ljob->hash; + $hash{'status'} = 'failed'; + my $fjob = new FS::queue( \%hash ); + my $error = $fjob->replace($ljob); + die $error if $error; + } else { + $ljob->delete; + } + +} continue { + if ( $sigterm ) { + warn "received TERM signal; exiting\n"; + exit; + } + if ( $sigint ) { + warn "received INT signal; exiting\n"; + exit; + } +} + + +sub datestamp { + time2str("%m%d%Y", time); +} + +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); +} + +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 + diff --git a/FS/t/queue.t b/FS/t/queue.t new file mode 100644 index 0000000..43e3373 --- /dev/null +++ b/FS/t/queue.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::queue; +$loaded=1; +print "ok 1\n"; diff --git a/FS/t/queue_arg.t b/FS/t/queue_arg.t new file mode 100644 index 0000000..cf3f91d --- /dev/null +++ b/FS/t/queue_arg.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::queue_arg; +$loaded=1; +print "ok 1\n"; |