]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/lib/OpenILS/Application/HoldTargeter.pm
LP#1849212: (follow-up) numerous fixes to open-ils.courses.detach_material
[Evergreen.git] / Open-ILS / src / perlmods / lib / OpenILS / Application / HoldTargeter.pm
1 package OpenILS::Application::HoldTargeter;
2 use strict; 
3 use warnings;
4 use OpenILS::Application;
5 use base qw/OpenILS::Application/;
6 use OpenILS::Utils::HoldTargeter;
7 use OpenSRF::Utils::Logger qw(:logger);
8
9 __PACKAGE__->register_method(
10     method    => 'hold_targeter',
11     api_name  => 'open-ils.hold-targeter.target',
12     api_level => 1,
13     argc      => 1,
14     stream    => 1,
15     # Caller is given control over how often to receive responses.
16     max_chunk_size => 0,
17     signature => {
18         desc     => q/Batch or single hold targeter./,
19         params   => [
20             {   name => 'args',
21                 type => 'hash',
22                 desc => q/
23 API Options:
24
25 return_count - Return number of holds processed so far instead 
26   of hold targeter result summary objects.
27
28 return_throttle - Only reply each time this many holds have been 
29   targeted.  This prevents dumping a fast stream of responses
30   at the client if the client doesn't need them.
31
32 Targeter Options:
33
34 hold => <id> OR [<id>, <id>, ...]
35  (Re)target one or more specific holds.  Specified as a single hold ID
36  or an array ref of hold IDs.
37
38 retarget_interval => <interval string>
39   Override the 'circ.holds.retarget_interval' global_flag value.
40
41 soft_retarget_interval => <interval string>
42   Apply soft retarget logic to holds whose prev_check_time sits
43   between the retarget_interval and the soft_retarget_interval.
44
45 next_check_interval => <interval string>
46   Use this interval to determine when the targeter will run next
47   instead of relying on the retarget_interval.  This value is used
48   to determine if an org unit will be closed during the next iteration
49   of the targeter.  Applying a specific interval is useful when
50   the retarget_interval is shorter than the time between targeter runs.
51
52 newest_first => 1
53   Target holds in reverse order of create_time. 
54
55 parallel_count => n
56   Number of parallel targeters running.  This acts as the indication
57   that other targeter instances are running.
58
59 parallel_slot => n [starts at 1]
60   Sets the parallel targeter instance slot.  Used to determine
61   which holds to process to avoid conflicts with other running instances.
62 /
63             }
64         ],
65         return => {desc => 'See API Options for return types'}
66     }
67 );
68
69 sub hold_targeter {
70     my ($self, $client, $args) = @_;
71
72     my $targeter = OpenILS::Utils::HoldTargeter->new(%$args);
73
74     $targeter->init;
75
76     my $throttle = $args->{return_throttle} || 1;
77     my $count = 0;
78
79     my @hold_ids = $targeter->find_holds_to_target;
80     my $total = scalar(@hold_ids);
81
82     $logger->info("targeter processing $total holds");
83
84     for my $hold_id (@hold_ids) {
85         $count++;
86
87         my $single = 
88             OpenILS::Utils::HoldTargeter::Single->new(parent => $targeter);
89
90         # Don't let an explosion on a single hold stop processing
91         eval { $single->target($hold_id) };
92
93         if ($@) {
94             my $msg = "Targeter failed processing hold: $hold_id : $@";
95             $single->error(1);
96             $logger->error($msg);
97             $single->message($msg) unless $single->message;
98         }
99
100         if (($count % $throttle) == 0) { 
101             # Time to reply to the caller.  Return either the number
102             # processed thus far or the most recent summary object.
103
104             my $res = $args->{return_count} ? $count : $single->result;
105             $client->respond($res);
106
107             $logger->info("targeted $count of $total holds");
108         }
109     }
110
111     return undef;
112 }
113
114 1;
115