From: Bill Erickson Date: Tue, 7 Jun 2016 21:32:14 +0000 (-0400) Subject: LP#1596595 Hold targeter refactoring and optimization. X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=55907fec8e56475121de765801e8ff321fb67b22;p=evergreen%2Fpines.git LP#1596595 Hold targeter refactoring and optimization. * New open-ils.hold-targeter service * Ports hold targeter code to a Perl utility function, communicating w/ the DB via cstore instead of storage. * Adds a new global flag 'circ.holds.retarget_interval' for configuring the hold retarget interval in the database. * Adds a new DB function to regenerating hold copy maps to make map deletion and creation more efficient. * Adds an option for targeting holds in newest to oldest order. * Caches all org unit settings per targeter run. * Adds support for "skip_viable" option. This tells the hold targeter to avoid modifying any holds that target viable copies. AKA "fix broken" mode. For example, you might run in skip_viable mode with a retarget interval of 24hr once a day to repair non-viable holds, then also run the targeter in regular mode once a day with a retarget interval of 48 hours to give staff 2 days to process viable holds. * Hold target loops logic changes: ** Org units with fewer target attempts are prioritized during loop processing. So, instead of segregating org units into 2 categetories, those attempted in the current loop and those not attempted, sort those not attempted by the number number of times they have been attempted. Within each grouping, prioritize by target weight/proximity as before. ** All org units that have been attempted less than the max configured amount are on the table for targeting, not just those that have been targeted less than the current loop max. If no orgs with less-than-current-max attempts are found, try orgs that match the current max (but are still less than the configured max). ** When activated, target looping treats the pickup lib like any other org unit. If a targeted copy at the pickup lib remains un-captured, at re-target time, a copy at a different branch is chosen (if one is available) even if other copies at the pickup lib are targetable. * Parallel targeting support baked into service. Teach the targeter to process a subset of holds based on the number of parallel targeters at play and the parallel targeting slot each targeter instance occupies. As with the existing hold targeter, group holds by their metarecord to avoid multiple targeter processes targeting the same sets of potential copies. * Logging / code refactoring and clean up. * New hold_targeter_v2.pl script for batch hold targeting. Existing targeter remains for backwards-compat. hold_targeter_v2.pl options: --verbose Print process counts --parallel Number of parallel hold processors to run. This overrides any value found in opensrf.xml --target-all Target all active holds, regardless of when they were last targeted. --skip-viable Avoid modifying holds that currently target viable copies. In other words, only (re)target holds in a non-viable state. --retarget-interval Override the 'circ.holds.retarget_interval' global_flag value. --parallel-init-sleep Time to wait between starting each parallel instance. Useful for avoiding dog-piling the DB. Signed-off-by: Bill Erickson --- diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Utils/HoldTargeter.pm b/Open-ILS/src/perlmods/lib/OpenILS/Utils/HoldTargeter.pm index 9aab446002..fa8b40e6cf 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Utils/HoldTargeter.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Utils/HoldTargeter.pm @@ -37,7 +37,6 @@ sub new { return bless($self, $class); } -# Returns a list of hold ID's sub find_holds_to_target { my $self = shift; diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.hold_targeter.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.hold_targeter.sql new file mode 100644 index 0000000000..ba584f0f57 --- /dev/null +++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.hold_targeter.sql @@ -0,0 +1,25 @@ +BEGIN; + +CREATE OR REPLACE FUNCTION + action.hold_request_regen_copy_maps( + hold_id INTEGER, copy_ids INTEGER[]) RETURNS VOID AS $$ + DELETE FROM action.hold_copy_map WHERE hold = $1; + INSERT INTO action.hold_copy_map (hold, target_copy) SELECT $1, UNNEST($2); +$$ LANGUAGE SQL; + +-- DATA + +INSERT INTO config.global_flag (name, label, value, enabled) VALUES ( + 'circ.holds.retarget_interval', + oils_i18n_gettext( + 'circ.holds.retarget_interval', + 'Holds Retarget Interval', + 'cgf', + 'label' + ), + '24h', + TRUE +); + +COMMIT; +