Bug 32481: Limit prefetch size for background jobs worker
[koha.git] / misc / process_ill_updates.pl
1 #!/usr/bin/perl
2
3 # This file is part of Koha.
4 #
5 # Copyright (C) 2022 PTFS Europe
6 #
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20 use Modern::Perl;
21 use Getopt::Long qw( GetOptions );
22 use POSIX;
23
24 use Koha::Script;
25 use Koha::Illrequests;
26
27 # Command line option values
28 my $get_help = 0;
29 my $statuses = "";
30 my $status_alias = "";
31 my $status_to = "";
32 my $status_alias_to = "";
33 my $backend = "";
34 my $dry_run = 0;
35 my $delay = 0;
36 my $debug = 0;
37
38 my $options = GetOptions(
39     'h|help'            => \$get_help,
40     'statuses:s'        => \$statuses,
41     'status-alias:s'    => \$status_alias,
42     'status-to:s'       => \$status_to,
43     'status-alias-to:s' => \$status_alias_to,
44     'backend=s'         => \$backend,
45     'dry-run'           => \$dry_run,
46     'api-delay:i'       => \$delay,
47     'debug'             => \$debug
48 );
49
50 if ($get_help) {
51     get_help();
52     exit 1;
53 }
54
55 if (!$backend) {
56     print "No backend specified\n";
57     exit 0;
58 }
59
60 # First check we can proceed
61 my $cfg = Koha::Illrequest::Config->new;
62 my $backends = $cfg->available_backends;
63 my $has_branch = $cfg->has_branch;
64 my $backends_available = ( scalar @{$backends} > 0 );
65 if (!$has_branch || $backends_available == 0) {
66     print "Unable to proceed:\n";
67     print "Branch configured: $has_branch\n";
68     print "Backends available: $backends_available\n";
69     exit 0;
70 }
71
72 # Get all required requests
73 my @statuses_arr = split(/:/, $statuses);
74 my @status_alias_arr = split(/:/, $status_alias);
75
76 my $where = {
77     backend => $backend
78 };
79
80 if (scalar @statuses_arr > 0) {
81     my @or = grep(!/null/, @statuses_arr);
82     if (scalar @or < scalar @statuses_arr) {
83         push @or, undef;
84     }
85     $where->{status} = \@or;
86 }
87
88 if (scalar @status_alias_arr > 0) {
89     my @or = grep(!/null/, @status_alias_arr);
90     if (scalar @or < scalar @status_alias_arr) {
91         push @or, undef;
92     }
93     $where->{status_alias} = \@or;
94 }
95
96 debug_msg("DBIC WHERE:");
97 debug_msg($where);
98
99 my $requests = Koha::Illrequests->search($where);
100
101 debug_msg("Processing " . $requests->count . " requests");
102
103 # Create an options hashref to pass to processors
104 my $options_to_pass = {
105     dry_run         => $dry_run,
106     status_to       => $status_to,
107     status_alias_to => $status_alias_to,
108     delay           => $delay,
109     debug           => \&debug_msg
110 };
111
112 # The progress log
113 my $output = [];
114
115 while (my $request = $requests->next) {
116     debug_msg("- Request ID " . $request->illrequest_id);
117     my $update = $request->backend_get_update($options_to_pass);
118     # The log for this request
119     my $update_log = {
120         request_id     => $request->illrequest_id,
121         processed_by   => $request->_backend->name,
122         processors_run => []
123     };
124     if ($update) {
125         # Currently we make an assumption, this may need revisiting
126         # if we need to extend the functionality:
127         #
128         # Only the backend that originated the update will want to
129         # process it
130         #
131         # Since each backend's update format is different, it may
132         # be necessary for a backend to subclass Koha::Illrequest::SupplierUpdate
133         # so it can provide methods (corresponding to a generic interface) that
134         # return pertinent info to core ILL when it is processing updates
135         #
136         # Attach any request processors
137         $request->attach_processors($update);
138         # Attach any processors from this request's backend
139         $request->_backend->attach_processors($update);
140         my $processor_results = $update->run_processors($options_to_pass);
141         # Update our progress log
142         $update_log->{processors_run} = $processor_results;
143     }
144     push @{$output}, $update_log;
145 }
146
147 print_summary($output);
148
149 sub print_summary {
150     my ( $log ) = @_;
151
152     my $timestamp = POSIX::strftime("%d/%m/%Y %H:%M:%S\n", localtime);
153     print "Run details:\n";
154     foreach my $entry(@{$log}) {
155         my @processors_run = @{$entry->{processors_run}};
156         print "Request ID: " . $entry->{request_id} . "\n";
157         print "  Processing by: " . $entry->{processed_by} . "\n";
158         print "  Number of processors run: " . scalar @processors_run . "\n";
159         if (scalar @processors_run > 0) {
160             print "  Processor details:\n";
161             foreach my $processor(@processors_run) {
162                 print "    Processor name: " . $processor->{name} . "\n";
163                 print "    Success messages: " . join(", ", @{$processor->{result}->{success}}) . "\n";
164                 print "    Error messages: " . join(", ", @{$processor->{result}->{error}}) . "\n";
165             }
166         }
167     }
168     print "Job completed at $timestamp\n====================================\n\n"
169 }
170
171 sub debug_msg {
172     my ( $msg ) = @_;
173
174     if (!$debug) {
175         return;
176     }
177
178     if (ref $msg eq 'HASH') {
179         use Data::Dumper;
180         $msg = Dumper $msg;
181     }
182     print STDERR "$msg\n";
183 }
184
185 sub get_help {
186     print <<"HELP";
187 $0: Fetch and process outstanding ILL updates
188
189 This script will fetch all requests that have the specified
190 statuses and run any applicable processor scripts on them.
191 For example, the RapidILL backend provides a processor script
192 that emails users when their requested electronic resource
193 request has been fulfilled
194
195 Parameters:
196     --statuses <statuses>                specify the statuses a request must have in order to be processed,
197                                          statuses should be separated by a : e.g. REQ:COMP:NEW. A null value
198                                          can be specified by passing null, e.g. --statuses null
199
200     --status-aliases <status-aliases>    specify the statuses aliases a request must have in order to be processed,
201                                          statuses should be separated by a : e.g. STA:OLD:PRE. A null value
202                                          can be specified by passing null, e.g. --status-aliases null
203     --status-to <status-to>              specify the status a successfully processed request must be set to
204                                          after processing
205     --status-alias-to <status-alias-to>  specify the status alias a successfully processed request must be set to
206                                          after processing
207     --dry-run                            only produce a run report, without actually doing anything permanent
208     --api-delay <seconds>                if a processing script needs to make an API call, how long a pause
209                                          should be inserted between each API call
210     --debug                              print additional debugging info during run
211
212     --help or -h                         get help
213 HELP
214 }