From 4196c4dd9eb64dd45a2857c760b5e85e8198c882 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Mon, 5 Dec 2016 15:46:41 -0500 Subject: [PATCH] LP#1596595 Find parallel holds in main query Identify holds to process by which metarecord the hold is (ultimately) linked to within the main holds query instead of via a secondary filter. This avoids the overhead of starting a new batch of hold targeters, where each process has to fetch all possible holds, then filter down to those targetable within the current parallel slot. In thise case, each process only retrieves the holds it plans to process. Signed-off-by: Bill Erickson --- .../src/perlmods/lib/OpenILS/Utils/HoldTargeter.pm | 47 ++++++++++------------ 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Utils/HoldTargeter.pm b/Open-ILS/src/perlmods/lib/OpenILS/Utils/HoldTargeter.pm index 2a871801bb..5555c86b81 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Utils/HoldTargeter.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Utils/HoldTargeter.pm @@ -143,7 +143,6 @@ sub find_holds_to_target { if ($parallel) { # In parallel mode, we need to also grab the metarecord for each hold. - $query->{select}->{mmrsm} = ['metarecord']; $query->{from} = { ahr => { rhrr => { @@ -158,6 +157,28 @@ sub find_holds_to_target { } } }; + + # In parallel mode, only process holds within the current process + # whose metarecord ID modulo the parallel targeter count matches + # our paralell targeting slot. This ensures that no 2 processes + # will be operating on the same potential copy sets. + # + # E.g. Running 5 parallel and we are slot 3 (0-based slot 2) of 5, + # process holds whose metarecord ID's are 2, 7, 12, 17, ... + # WHERE MOD(mmrsm.id, 5) = 2 + + # Slots are 1-based at the API level, but 0-based for modulo. + my $slot = $self->{parallel_slot} - 1; + + $query->{where}->{'+mmrsm'} = { + id => { + '=' => { + transform => 'mod', + value => $slot, + params => [$parallel] + } + } + }; } # Newest-first sorting cares only about hold create_time. @@ -167,30 +188,6 @@ sub find_holds_to_target { my $holds = $self->editor->json_query($query, {substream => 1}); - # In parallel mode, only process holds within the current process - # whose metarecord ID modulo the parallel targeter count matches - # our paralell targeting slot. This ensures that no 2 processes - # will be operating on the same potential copy sets. - # - # E.g. Running 5 parallel and we are slot 3 (0-based slot 2) of 5, - # process holds whose metarecord ID's are 2, 7, 12, 17, ... - if ($parallel) { - - # Slots are 1-based at the API level, but 0-based for modulo. - my $slot = $self->{parallel_slot} - 1; - - my @slot_holds = - grep { ($_->{metarecord} % $parallel) == $slot } @$holds; - - $logger->info(sprintf( - "targeter: parallel targeter (slot %d of %d) trimmed ". - "targetable holds set down to %d from %d holds", - $slot + 1, $parallel, scalar(@slot_holds), scalar(@$holds) - )); - - $holds = \@slot_holds; - } - return map {$_->{id}} @$holds; } -- 2.11.0