From cc2be64bdf63f2b986768f7200fc4369ee11db1c Mon Sep 17 00:00:00 2001 From: Kyle M Hall Date: Tue, 10 May 2016 18:36:40 +0000 Subject: [PATCH] [WIP] Bug 16528 - Add ability to parallel process fines to fines.pl --- misc/cronjobs/fines.pl | 54 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/misc/cronjobs/fines.pl b/misc/cronjobs/fines.pl index 6c3f830..564ae63 100755 --- a/misc/cronjobs/fines.pl +++ b/misc/cronjobs/fines.pl @@ -26,30 +26,32 @@ # You should have received a copy of the GNU General Public License # along with Koha; if not, see . -use strict; -use warnings; -use 5.010; +use Modern::Perl; -use C4::Context; -use C4::Overdues; -use Getopt::Long; use Carp; use File::Spec; +use Getopt::Long; +use Parallel::ForkManager; + +use C4::Context; +use C4::Overdues; +use C4::Log; use Koha::Calendar; use Koha::DateUtils; -use C4::Log; my $help; my $verbose; my $output_dir; my $log; +my $max_processes = 0; GetOptions( - 'h|help' => \$help, - 'v|verbose' => \$verbose, - 'l|log' => \$log, - 'o|out:s' => \$output_dir, + 'h|help' => \$help, + 'v|verbose' => \$verbose, + 'l|log' => \$log, + 'o|out:s' => \$output_dir, + 'm|max-processes:s' => \$max_processes, ); my $usage = << 'ENDUSAGE'; @@ -63,6 +65,7 @@ This script has the following parameters : -l --log: log the output to a file (optional if the -o parameter is given) -o --out: ouput directory for logs (defaults to env or /tmp if !exist) -v --verbose + -m --max-processes: The maximum number of concurrent fine calculating processes ENDUSAGE @@ -97,6 +100,24 @@ if ($filename) { } my $counted = 0; my $overdues = Getoverdues(); + +# Break out overdues per patron, this is needed in case we process overdues +# in parallel. All overdues for a single patron still need to be handled by +# a single process in case there are fine limits in place that need to account +# for previous fines. If they were in parallel the math would be incorrect. +my $overdues_by_patron; +map { push( $overdues_by_patron->{ $_->{borrowernumber} }, $_ ) } @{$overdues}; + +my $pm = Parallel::ForkManager->new( $max_processes, '/tmp' ); +$pm->run_on_finish( # called BEFORE the first call to start() + sub { + my ( $pid, $exit_code, $ident, $exit_signal, $core_dump, $data ) = @_; + + $counted++ if $exit_code; + } +); + +OVERDUES_LOOP: for my $overdue ( @{$overdues} ) { next if $overdue->{itemlost}; @@ -105,6 +126,10 @@ for my $overdue ( @{$overdues} ) { "ERROR in Getoverdues : issues.borrowernumber IS NULL. Repair 'issues' table now! Skipping record.\n"; next; } + + # Forking a child process now, no sense forking earlier as those children would do almost nothing + my $pid = $pm->start and next OVERDUES_LOOP; + my $borrower = BorType( $overdue->{borrowernumber} ); my $branchcode = ( $control eq 'ItemHomeLibrary' ) ? $overdue->{homebranch} @@ -118,9 +143,8 @@ for my $overdue ( @{$overdues} ) { my $datedue = dt_from_string( $overdue->{date_due} ); if ( DateTime->compare( $datedue, $today ) == 1 ) { - next; # not overdue + $pm->finish(0); # not overdue } - ++$counted; my ( $amount, $type, $unitcounttotal ) = CalcFine( $overdue, $borrower->{categorycode}, @@ -152,7 +176,11 @@ for my $overdue ( @{$overdues} ) { push @cells, $type, $unitcounttotal, $amount; say {$fh} join $delim, @cells; } + $pm->finish(1); } + +$pm->wait_all_children; + if ($filename){ close $fh; } -- 2.1.4