From af9bb255aac1218f029fb164c8a3499208e1d6b2 Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 22 Apr 2009 00:54:03 +0000 Subject: [PATCH] have the big query find customers in batches. this should be way more efficient in multi-process mode, can start billing before the big query completes. RT#4412 --- FS/FS/Cron/bill.pm | 105 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 59 insertions(+), 46 deletions(-) diff --git a/FS/FS/Cron/bill.pm b/FS/FS/Cron/bill.pm index 312f337a7..653701822 100644 --- a/FS/FS/Cron/bill.pm +++ b/FS/FS/Cron/bill.pm @@ -95,52 +95,65 @@ END push @search, "( $where_pkg OR $where_event )"; - ### - # get a list of custnums - ### - - warn "searching for customers:\n". join("\n", @search). "\n" - if $opt{'v'} || $opt{'l'}; - - my $sth = dbh->prepare( - "SELECT custnum FROM cust_main". - " WHERE ". join(' AND ', @search) - ) or die dbh->errstr; - - $sth->execute or die $sth->errstr; - - my @custnums = map { $_->[0] } @{ $sth->fetchall_arrayref }; - - ### - # for each custnum, queue or make one customer object and bill - # (one at a time, to reduce memory footprint with large #s of customers) - ### - - foreach my $custnum ( @custnums ) { - - my %args = ( - 'time' => $time, - 'invoice_time' => $invoice_time, - 'actual_time' => $^T, #when freeside-bill was started - #(not, when using -m, freeside-queued) - 'check_freq' => $check_freq, - 'resetup' => ( $opt{'s'} ? $opt{'s'} : 0 ), - ); - - if ( $opt{'m'} ) { - - #add job to queue that calls bill_and_collect with options - my $queue = new FS::queue { - 'job' => 'FS::cust_main::queued_bill', - 'secure' => 'Y', - 'priority' => 99, #don't get in the way of provisioning jobs - }; - my $error = $queue->insert( 'custnum'=>$custnum, %args ); - - } else { - - my $cust_main = qsearchs( 'cust_main', { 'custnum' => $custnum } ); - $cust_main->bill_and_collect( %args, 'debug' => $debug ); + my $prev_custnum = 0; + while ( 1 ) { + + ### + # get a list of custnums + ### + + warn "searching for customers:\n". + join("\n", @search). + "custnum > $prev_custnum\n" + if $opt{'v'} || $opt{'l'}; + + my $sth = dbh->prepare( + "SELECT custnum FROM cust_main". + " WHERE ". join(' AND ', @search). + " AND custnum > $prev_custnum ". + " ORDER BY custnum LIMIT 100 " + ) or die dbh->errstr; + + $sth->execute or die $sth->errstr; + + my @custnums = map { $_->[0] } @{ $sth->fetchall_arrayref }; + + last unless scalar(@custnums); + + $prev_custnum = $custnums[-1]; + + ### + # for each custnum, queue or make one customer object and bill + # (one at a time, to reduce memory footprint with large #s of customers) + ### + + foreach my $custnum ( @custnums ) { + + my %args = ( + 'time' => $time, + 'invoice_time' => $invoice_time, + 'actual_time' => $^T, #when freeside-bill was started + #(not, when using -m, freeside-queued) + 'check_freq' => $check_freq, + 'resetup' => ( $opt{'s'} ? $opt{'s'} : 0 ), + ); + + if ( $opt{'m'} ) { + + #add job to queue that calls bill_and_collect with options + my $queue = new FS::queue { + 'job' => 'FS::cust_main::queued_bill', + 'secure' => 'Y', + 'priority' => 99, #don't get in the way of provisioning jobs + }; + my $error = $queue->insert( 'custnum'=>$custnum, %args ); + + } else { + + my $cust_main = qsearchs( 'cust_main', { 'custnum' => $custnum } ); + $cust_main->bill_and_collect( %args, 'debug' => $debug ); + + } } -- 2.11.0