View | Details | Raw Unified | Return to bug 28833
Collapse All | Expand All

(-)a/C4/HoldsQueue.pm (-12 / +33 lines)
Lines 33-41 use Koha::Items; Link Here
33
use Koha::Patrons;
33
use Koha::Patrons;
34
use Koha::Libraries;
34
use Koha::Libraries;
35
35
36
use List::Util qw(shuffle);
37
use List::MoreUtils qw(any);
38
use Data::Dumper;
36
use Data::Dumper;
37
use List::MoreUtils qw(any);
38
use List::Util qw(shuffle);
39
use POSIX qw(ceil);
40
use Parallel::Loops;
39
41
40
use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
42
use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
41
BEGIN {
43
BEGIN {
Lines 176-191 Top level function that turns reserves into tmp_holdsqueue and hold_fill_targets Link Here
176
=cut
178
=cut
177
179
178
sub CreateQueue {
180
sub CreateQueue {
179
    my $dbh   = C4::Context->dbh;
181
    my $loops = shift || 1;
182
183
    my $dbh = C4::Context->dbh;
180
184
181
    $dbh->do("DELETE FROM tmp_holdsqueue");  # clear the old table for new info
185
    $dbh->do("DELETE FROM tmp_holdsqueue");  # clear the old table for new info
182
    $dbh->do("DELETE FROM hold_fill_targets");
186
    $dbh->do("DELETE FROM hold_fill_targets");
183
187
184
    my $total_bibs            = 0;
185
    my $total_requests        = 0;
186
    my $total_available_items = 0;
187
    my $num_items_mapped      = 0;
188
189
    my $branches_to_use;
188
    my $branches_to_use;
190
    my $transport_cost_matrix;
189
    my $transport_cost_matrix;
191
    my $use_transport_cost_matrix = C4::Context->preference("UseTransportCostMatrix");
190
    my $use_transport_cost_matrix = C4::Context->preference("UseTransportCostMatrix");
Lines 202-220 sub CreateQueue { Link Here
202
201
203
    my $bibs_with_pending_requests = GetBibsWithPendingHoldRequests();
202
    my $bibs_with_pending_requests = GetBibsWithPendingHoldRequests();
204
203
204
    # Split the list of bibs into groups to run in parallel
205
    if ( $loops > 1 ) {
206
        my $bibs_per_chunk = ceil( scalar @$bibs_with_pending_requests / $loops );
207
        my @chunks;
208
209
        push( @chunks, [ splice @$bibs_with_pending_requests, 0, $bibs_per_chunk ] ) while @$bibs_with_pending_requests;
210
        push( @{$chunks[0]}, @$bibs_with_pending_requests ); # Add any remainders to the first parallel process
211
212
        my $pl = Parallel::Loops->new($loops);
213
        $pl->foreach( \@chunks, sub {
214
            _ProcessBiblios($_);
215
        });
216
    } else {
217
        _ProcessBiblios($bibs_with_pending_requests, $branches_to_use, $transport_cost_matrix);
218
    }
219
}
220
221
=head2 _ProcessBiblios
222
223
=cut
224
225
sub _ProcessBiblios {
226
    my $bibs_with_pending_requests = shift;
227
    my $branches_to_use = shift;
228
    my $transport_cost_matrix = shift;
229
205
    foreach my $biblionumber (@$bibs_with_pending_requests) {
230
    foreach my $biblionumber (@$bibs_with_pending_requests) {
206
        $total_bibs++;
207
        my $hold_requests   = GetPendingHoldRequestsForBib($biblionumber);
231
        my $hold_requests   = GetPendingHoldRequestsForBib($biblionumber);
208
        my $available_items = GetItemsAvailableToFillHoldRequestsForBib($biblionumber, $branches_to_use);
232
        my $available_items = GetItemsAvailableToFillHoldRequestsForBib($biblionumber, $branches_to_use);
209
        $total_requests        += scalar(@$hold_requests);
210
        $total_available_items += scalar(@$available_items);
211
233
212
        my $item_map = MapItemsToHoldRequests($hold_requests, $available_items, $branches_to_use, $transport_cost_matrix);
234
        my $item_map = MapItemsToHoldRequests($hold_requests, $available_items, $branches_to_use, $transport_cost_matrix);
213
        $item_map  or next;
235
        $item_map  or next;
214
        my $item_map_size = scalar(keys %$item_map)
236
        my $item_map_size = scalar(keys %$item_map)
215
          or next;
237
          or next;
216
238
217
        $num_items_mapped += $item_map_size;
218
        CreatePicklistFromItemMap($item_map);
239
        CreatePicklistFromItemMap($item_map);
219
        AddToHoldTargetMap($item_map);
240
        AddToHoldTargetMap($item_map);
220
        if (($item_map_size < scalar(@$hold_requests  )) and
241
        if (($item_map_size < scalar(@$hold_requests  )) and
(-)a/installer/data/mysql/atomicupdate/bug_28833.perl (+9 lines)
Line 0 Link Here
1
$DBversion = 'XXX'; # will be replaced by the RM
2
if( CheckVersion( $DBversion ) ) {
3
    $dbh->do(q{
4
        INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
5
        ('HoldsQueueParallelLoopsCount', '1', NULL, 'Number of parallel loops to use when running the holds queue builder', 'Integer');
6
    });
7
8
    NewVersion( $DBversion, 28833, "Speed up holds queue builder via parallel processing");
9
}
(-)a/installer/data/mysql/mandatory/sysprefs.sql (+1 lines)
Lines 239-244 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
239
('HoldsAutoFillPrintSlip','0',NULL,'If on, hold slip print dialog will be displayed automatically','YesNo'),
239
('HoldsAutoFillPrintSlip','0',NULL,'If on, hold slip print dialog will be displayed automatically','YesNo'),
240
('HoldsLog','0',NULL,'If ON, log create/cancel/suspend/resume actions on holds.','YesNo'),
240
('HoldsLog','0',NULL,'If ON, log create/cancel/suspend/resume actions on holds.','YesNo'),
241
('HoldsNeedProcessingSIP', '0', NULL, 'Require staff to check-in before hold is set to waiting state', 'YesNo' ),
241
('HoldsNeedProcessingSIP', '0', NULL, 'Require staff to check-in before hold is set to waiting state', 'YesNo' ),
242
('HoldsQueueParallelLoopsCount', '1', NULL, 'Number of parallel loops to use when running the holds queue builder', 'Integer'),
242
('HoldsQueueSkipClosed', '0', NULL, 'If enabled, any libraries that are closed when the holds queue is built will be ignored for the purpose of filling holds.', 'YesNo'),
243
('HoldsQueueSkipClosed', '0', NULL, 'If enabled, any libraries that are closed when the holds queue is built will be ignored for the purpose of filling holds.', 'YesNo'),
243
('HoldsSplitQueue','nothing','nothing|branch|itemtype|branch_itemtype','In the staff interface, split the holds view by the given criteria','Choice'),
244
('HoldsSplitQueue','nothing','nothing|branch|itemtype|branch_itemtype','In the staff interface, split the holds view by the given criteria','Choice'),
244
('HoldsToPullStartDate','2',NULL,'Set the default start date for the Holds to pull list to this many days ago','Integer'),
245
('HoldsToPullStartDate','2',NULL,'Set the default start date for the Holds to pull list to this many days ago','Integer'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref (-1 / +5 lines)
Lines 74-79 Circulation: Link Here
74
            - pref: HoldsToPullStartDate
74
            - pref: HoldsToPullStartDate
75
              class: integer
75
              class: integer
76
            - day(s) ago. Note that the default end date is controlled by the system preference <a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=ConfirmFutureHolds">ConfirmFutureHolds</a>.
76
            - day(s) ago. Note that the default end date is controlled by the system preference <a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=ConfirmFutureHolds">ConfirmFutureHolds</a>.
77
        -
78
            - When building the holds queue, calculate hold matches using
79
            - pref: HoldsQueueParallelLoopsCount
80
              class: integer
81
            - parallel loop(s). The more loops used, the faster it will calculate and the more computing resources it will use.
77
        -
82
        -
78
            - pref: AllowAllMessageDeletion
83
            - pref: AllowAllMessageDeletion
79
              choices:
84
              choices:
80
- 

Return to bug 28833