Bug 28833 - Speed up holds queue builder via parallel processing
Summary: Speed up holds queue builder via parallel processing
Status: Needs documenting
Alias: None
Product: Koha
Classification: Unclassified
Component: Hold requests (show other bugs)
Version: Main
Hardware: All All
: P5 - low enhancement
Assignee: Kyle M Hall (khall)
QA Contact: Martin Renvoize (ashimema)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-08-09 17:45 UTC by Kyle M Hall (khall)
Modified: 2024-11-19 04:23 UTC (History)
7 users (show)

See Also:
Change sponsored?: ---
Patch complexity: ---
Documentation contact:
Documentation submission:
Text to go in the release notes:
This enhancement adds the ability to increase the amount of parallel calculations used to create the Holds Queue. The amount of calculations or "loops" done in parallel is set in the new system preference 'HoldsQueueParallelLoopsCount'. This enhancement will allow faster holds queue building for libraries with a very large amount of holds. Note that increasing the value in the system preference also causes Koha to use more resources when building the holds queue.
Version(s) released in:
24.11.00
Circulation function:


Attachments
Bug 28833: Speed up holds queue builder via parallel processing (4.32 KB, patch)
2021-08-09 17:52 UTC, Kyle M Hall (khall)
Details | Diff | Splinter Review
Bug 28833: Speed up holds queue builder via parallel processing (4.26 KB, patch)
2021-08-09 17:54 UTC, Kyle M Hall (khall)
Details | Diff | Splinter Review
Bug 28833: Speed up holds queue builder via parallel processing (3.51 KB, patch)
2021-08-09 19:12 UTC, Kyle M Hall (khall)
Details | Diff | Splinter Review
Bug 28833: Speed up holds queue builder via parallel processing (7.15 KB, patch)
2021-08-10 11:05 UTC, Kyle M Hall (khall)
Details | Diff | Splinter Review
Bug 28833: Speed up holds queue builder via parallel processing (7.12 KB, patch)
2021-08-10 11:53 UTC, Kyle M Hall (khall)
Details | Diff | Splinter Review
Bug 28833: Speed up holds queue builder via parallel processing (7.82 KB, patch)
2021-08-10 13:26 UTC, Kyle M Hall (khall)
Details | Diff | Splinter Review
Bug 28833: Speed up holds queue builder via parallel processing (7.81 KB, patch)
2021-08-10 13:27 UTC, Kyle M Hall (khall)
Details | Diff | Splinter Review
Bug 28833: (follow-up) Move loops count control to koha conf (4.39 KB, patch)
2021-08-11 11:47 UTC, Kyle M Hall (khall)
Details | Diff | Splinter Review
Bug 28833: (follow-up) Only spawn multiple processes if there are more records than loops specified (953 bytes, patch)
2021-08-11 11:47 UTC, Kyle M Hall (khall)
Details | Diff | Splinter Review
Bug 28833: (follow-up) Move loops count control to koha conf (4.90 KB, patch)
2021-08-11 11:50 UTC, Kyle M Hall (khall)
Details | Diff | Splinter Review
Bug 28833: (follow-up) Only spawn multiple processes if there are more records than loops specified (953 bytes, patch)
2021-08-11 11:50 UTC, Kyle M Hall (khall)
Details | Diff | Splinter Review
Bug 28833: Speed up holds queue builder via parallel processing (5.68 KB, patch)
2021-08-20 11:53 UTC, Kyle M Hall (khall)
Details | Diff | Splinter Review
Bug 28833: Balance the number of holds each chunk contains (2.32 KB, patch)
2021-10-13 13:46 UTC, Kyle M Hall (khall)
Details | Diff | Splinter Review
Bug 28833: Speed up holds queue builder via parallel processing (6.32 KB, patch)
2021-10-13 13:53 UTC, Kyle M Hall (khall)
Details | Diff | Splinter Review
Bug 28833: Speed up holds queue builder via parallel processing (6.33 KB, patch)
2021-10-13 15:03 UTC, Kyle M Hall (khall)
Details | Diff | Splinter Review
Bug 28833: Speed up holds queue builder via parallel processing (6.14 KB, patch)
2024-06-03 14:56 UTC, Kyle M Hall (khall)
Details | Diff | Splinter Review
Bug 28833: Speed up holds queue builder via parallel processing (8.09 KB, patch)
2024-10-21 12:38 UTC, Kyle M Hall (khall)
Details | Diff | Splinter Review
Bug 28833: Speed up holds queue builder via parallel processing (8.10 KB, patch)
2024-10-21 12:41 UTC, Kyle M Hall (khall)
Details | Diff | Splinter Review
Bug 28833: Speed up holds queue builder via parallel processing (8.14 KB, patch)
2024-10-24 11:43 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review

Note You need to log in before you can comment on or make changes to this bug.
Description Kyle M Hall (khall) 2021-08-09 17:45:42 UTC
The holds queue builder can take a very long time to run on systems with many holds. For example, a partner with 124,784 unfilled ( not found ) holds, is taking about 64 minutes to run. If we run that same number of holds in 5 parallel chunks ( splitting the number of records as evenly as possible, but *not* taking into account the holds per bib ), it takes 21.5 minutes. If we use 10 loops, it takes less then 14 minutes.
Comment 1 Kyle M Hall (khall) 2021-08-09 17:52:05 UTC
Created attachment 123656 [details] [review]
Bug 28833: Speed up holds queue builder via parallel processing

The holds queue builder can take a very long time to run on systems with many holds. For example, a partner with 124,784 unfilled ( not found ) holds, is taking about 64 minutes to run. If we run that same number of holds in 5 parallel chunks ( splitting the number of records as evenly as possible, but *not* taking into account the holds per bib ), it takes 21.5 minutes. If we use 10 loops, it takes less then 14 minutes.
Comment 2 Kyle M Hall (khall) 2021-08-09 17:52:50 UTC
This patch provides a tremendous speedup for large numbers of holds. However, it causes HoldsQueue.t to fail spectacularly.
Comment 3 Kyle M Hall (khall) 2021-08-09 17:54:51 UTC
Created attachment 123657 [details] [review]
Bug 28833: Speed up holds queue builder via parallel processing

The holds queue builder can take a very long time to run on systems with many holds. For example, a partner with 124,784 unfilled ( not found ) holds, is taking about 64 minutes to run. If we run that same number of holds in 5 parallel chunks ( splitting the number of records as evenly as possible, but *not* taking into account the holds per bib ), it takes 21.5 minutes. If we use 10 loops, it takes less then 14 minutes.
Comment 4 Kyle M Hall (khall) 2021-08-09 19:12:27 UTC
Created attachment 123659 [details] [review]
Bug 28833: Speed up holds queue builder via parallel processing

The holds queue builder can take a very long time to run on systems with many holds. For example, a partner with 124,784 unfilled ( not found ) holds, is taking about 64 minutes to run. If we run that same number of holds in 5 parallel chunks ( splitting the number of records as evenly as possible, but *not* taking into account the holds per bib ), it takes 21.5 minutes. If we use 10 loops, it takes less then 14 minutes.
Comment 5 Kyle M Hall (khall) 2021-08-10 11:05:52 UTC
Created attachment 123671 [details] [review]
Bug 28833: Speed up holds queue builder via parallel processing

The holds queue builder can take a very long time to run on systems with many holds. For example, a partner with 124,784 unfilled ( not found ) holds, is taking about 64 minutes to run. If we run that same number of holds in 5 parallel chunks ( splitting the number of records as evenly as possible, but *not* taking into account the holds per bib ), it takes 21.5 minutes. If we use 10 loops, it takes less then 14 minutes.

Test Plan:
1) Generate a huge number of holds ( a few thousand at the minimum )
2) Run the holds queue builder, use the `time` utility to track how much
   time it took to run
3) Set HoldsQueueParallelLoopsCount to 10
4) Repeat step 2, note the improvement in speed
5) Experiment with other values for HoldsQueueParallelLoopsCount
6) prove t/db_dependent/HoldsQueue.t
Comment 6 Kyle M Hall (khall) 2021-08-10 11:53:24 UTC
Created attachment 123679 [details] [review]
Bug 28833: Speed up holds queue builder via parallel processing

The holds queue builder can take a very long time to run on systems with many holds. For example, a partner with 124,784 unfilled ( not found ) holds, is taking about 64 minutes to run. If we run that same number of holds in 5 parallel chunks ( splitting the number of records as evenly as possible, but *not* taking into account the holds per bib ), it takes 21.5 minutes. If we use 10 loops, it takes less then 14 minutes.

Test Plan:
0) Install the Perl library Parallel::Loops
1) Generate a huge number of holds ( a few thousand at the minimum )
2) Run the holds queue builder, use the `time` utility to track how much
   time it took to run
3) Set HoldsQueueParallelLoopsCount to 10
4) Repeat step 2, note the improvement in speed
5) Experiment with other values for HoldsQueueParallelLoopsCount
6) prove t/db_dependent/HoldsQueue.t
Comment 7 Kyle M Hall (khall) 2021-08-10 13:26:18 UTC
Created attachment 123688 [details] [review]
Bug 28833: Speed up holds queue builder via parallel processing

The holds queue builder can take a very long time to run on systems with many holds. For example, a partner with 124,784 unfilled ( not found ) holds, is taking about 64 minutes to run. If we run that same number of holds in 5 parallel chunks ( splitting the number of records as evenly as possible, but *not* taking into account the holds per bib ), it takes 21.5 minutes. If we use 10 loops, it takes less then 14 minutes.

Test Plan:
0) Install the Perl library Parallel::ForkManager
1) Generate a huge number of holds ( a few thousand at the minimum )
2) Run the holds queue builder, use the `time` utility to track how much
   time it took to run
3) Set HoldsQueueParallelLoopsCount to 10
4) Repeat step 2, note the improvement in speed
5) Experiment with other values for HoldsQueueParallelLoopsCount
6) prove t/db_dependent/HoldsQueue.t
Comment 8 Kyle M Hall (khall) 2021-08-10 13:27:39 UTC
Created attachment 123689 [details] [review]
Bug 28833: Speed up holds queue builder via parallel processing

The holds queue builder can take a very long time to run on systems with many holds. For example, a partner with 124,784 unfilled ( not found ) holds, is taking about 64 minutes to run. If we run that same number of holds in 5 parallel chunks ( splitting the number of records as evenly as possible, but *not* taking into account the holds per bib ), it takes 21.5 minutes. If we use 10 loops, it takes less then 14 minutes.

Test Plan:
0) Install the Perl library Parallel::ForkManager
1) Generate a huge number of holds ( a few thousand at the minimum )
2) Run the holds queue builder, use the `time` utility to track how much
   time it took to run
3) Set HoldsQueueParallelLoopsCount to 10
4) Repeat step 2, note the improvement in speed
5) Experiment with other values for HoldsQueueParallelLoopsCount
6) prove t/db_dependent/HoldsQueue.t
Comment 9 David Cook 2021-08-11 00:34:05 UTC
This is an interesting one! 

On one hand, I like the use of a system preference to allow the value to be set on a per-instance basis.

On the other hand, letting a library define an unrestricted number of forks for a script seems potentially dangerous, especially if you have multiple Koha instances on the same server.

I think this change needs more sanity checks.

Some options:
1) A CLI override that doesn't let the $loops be beyond X. This allows a sysadmin to constrain the resource usage
2) Perhaps the size of $bibs_with_pending_requests should correlate with the number of forks up to a maximum. (If you only have 10 bibs but your $loops is 10, it doesn't make sense to have 10 forks of 1 bib each. )
3) Maybe we should limit nproc in /etc/security/limits.d on a per-user basis (but maybe this is best left to local sysadmins and this is a very blunt instrument)

Actually, we should also do a int() check on $loops before feeding it to Parallel::ForkManager, since it is user-provided input. (I suppose a non-number would just cause a fatal error on a $loops > 1 check, but better to not fork than to fail.)
Comment 10 David Cook 2021-08-11 00:40:05 UTC
Another option might be to use koha-conf.xml instead of a system preference. 

I think it's important for it to be a configurable value per-instance, but I'm opposed to the idea of library staff being able to determine server resource usage.
Comment 11 David Cook 2021-08-11 00:41:45 UTC
The following is totally out of scope but inspired by the above:

What if default values in koha-conf.xml were determined based on a "profile" provided for koha-create? 

By default, we'd have permissive values, so that inexperienced people could have the most power possible through the Web UI, since they might not have a sysadmin to update the backend. 

But we'd have a more restrictive profile that vendors and more experienced people could use to have more locked down/secure Koha instances.

I'm trying to think of an approach that could make everyone happy...
Comment 12 Kyle M Hall (khall) 2021-08-11 11:47:42 UTC
Created attachment 123783 [details] [review]
Bug 28833: (follow-up) Move loops count control to koha conf
Comment 13 Kyle M Hall (khall) 2021-08-11 11:47:51 UTC
Created attachment 123784 [details] [review]
Bug 28833: (follow-up) Only spawn multiple processes if there are more records than loops specified
Comment 14 Kyle M Hall (khall) 2021-08-11 11:50:31 UTC
Created attachment 123785 [details] [review]
Bug 28833: (follow-up) Move loops count control to koha conf
Comment 15 Kyle M Hall (khall) 2021-08-11 11:50:40 UTC
Created attachment 123786 [details] [review]
Bug 28833: (follow-up) Only spawn multiple processes if there are more records than loops specified
Comment 16 David Cook 2021-08-12 01:13:09 UTC
Comment on attachment 123786 [details] [review]
Bug 28833: (follow-up) Only spawn multiple processes if there are more records than loops specified

Review of attachment 123786 [details] [review]:
-----------------------------------------------------------------

::: C4/HoldsQueue.pm
@@ +201,4 @@
>      # Split the list of bibs into groups to run in parallel
>      if ( $loops > 1 ) {
>          my $bibs_per_chunk = ceil( scalar @$bibs_with_pending_requests / $loops );
> +        $bibs_per_chunk = @$bibs_with_pending_requests if @$bibs_with_pending_requests <= $bibs_per_chunk;

I don't understand this logic. 

scalar @$bibs_with_pending_requests = 10
$loops = 10
$bibs_per_chunk =  1

$bibs_per_chunk would still be 1.

Maybe I'm confused but I can't think of a case where $bibs_per_chunk could be greater than scalar @$bibs_with_pending_requests.

--

I was thinking we'd do the $loops would be changed to $max_loops, and $loops would be based on an arbitrary ratio. Perhaps 1000 bibs per 1 loop. 

So $loops = scalar @$bibs_with_pending_requests / 1000. 

If $loops < 1, then we don't fork. If $loops > 1, we double-check that we're not exceeding our maximum number of loops. 

For example:
$max_loops = 4 
scalar @$bibs_with_pending_requests = 10000
$loops = 10

We throttle $loops down from 10 to 4, because 4 is our maximum. 

Likewise, if @$bibs_with_pending_requests = 2000, we're only using 2 forks instead of our maximum of 4, so we're not using more resources than necessary. 

--

Alternatively, we could have an arbitrary threshold of 1000. Below that and we use $loops = 1. Above that, we use the $loops value supplied from config. 

I'm just trying to avoid scenarios where you have 50 Koha instances each spinning up 10 child processes to process 2 requests each. 

But maybe I'm just prematurely optimizing. I suppose most instances will have the default of 1 anyway.
Comment 17 David Cook 2021-08-12 01:14:00 UTC
Comment on attachment 123689 [details] [review]
Bug 28833: Speed up holds queue builder via parallel processing

Review of attachment 123689 [details] [review]:
-----------------------------------------------------------------

::: C4/HoldsQueue.pm
@@ +210,5 @@
> +
> +        DATA_LOOP:
> +        foreach my $chunk (@chunks) {
> +            my $pid = $pm->start and next DATA_LOOP;
> +            _ProcessBiblios($chunk);

I notice that the other _ProcessBiblios has arguments for $branches_to_use and $transport_cost_matrix. I'm guessing those should be included here too?
Comment 18 Kyle M Hall (khall) 2021-08-20 11:53:00 UTC
Created attachment 123996 [details] [review]
Bug 28833: Speed up holds queue builder via parallel processing

The holds queue builder can take a very long time to run on systems with many holds. For example, a partner with 124,784 unfilled ( not found ) holds, is taking about 64 minutes to run. If we run that same number of holds in 5 parallel chunks ( splitting the number of records as evenly as possible, but *not* taking into account the holds per bib ), it takes 21.5 minutes. If we use 10 loops, it takes less then 14 minutes.

Test Plan:
0) Install the Perl library Parallel::ForkManager
1) Generate a huge number of holds ( a few thousand at the minimum )
2) Run the holds queue builder, use the `time` utility to track how much
   time it took to run
3) Set HoldsQueueParallelLoopsCount to 10
4) Repeat step 2, note the improvement in speed
5) Experiment with other values for HoldsQueueParallelLoopsCount
6) prove t/db_dependent/HoldsQueue.t
Comment 19 Kyle M Hall (khall) 2021-08-20 11:55:02 UTC
(In reply to David Cook from comment #17)
> Comment on attachment 123689 [details] [review] [review]
> Bug 28833: Speed up holds queue builder via parallel processing
> 
> Review of attachment 123689 [details] [review] [review]:
> -----------------------------------------------------------------
> 
> ::: C4/HoldsQueue.pm
> @@ +210,5 @@
> > +
> > +        DATA_LOOP:
> > +        foreach my $chunk (@chunks) {
> > +            my $pid = $pm->start and next DATA_LOOP;
> > +            _ProcessBiblios($chunk);
> 
> I notice that the other _ProcessBiblios has arguments for $branches_to_use
> and $transport_cost_matrix. I'm guessing those should be included here too?

Good catch! I've fixed that issue and squashed the patches down for ease of use.
Comment 20 Kyle M Hall (khall) 2021-10-13 13:46:17 UTC
Created attachment 126200 [details] [review]
Bug 28833: Balance the number of holds each chunk contains
Comment 21 Kyle M Hall (khall) 2021-10-13 13:53:11 UTC
Created attachment 126202 [details] [review]
Bug 28833: Speed up holds queue builder via parallel processing

The holds queue builder can take a very long time to run on systems with many holds. For example, a partner with 124,784 unfilled ( not found ) holds, is taking about 64 minutes to run. If we run that same number of holds in 5 parallel chunks ( splitting the number of records as evenly as possible, but *not* taking into account the holds per bib ), it takes 21.5 minutes. If we use 10 loops, it takes less then 14 minutes.

Test Plan:
0) Install the Perl library Parallel::ForkManager
1) Generate a huge number of holds ( a few thousand at the minimum )
2) Run the holds queue builder, use the `time` utility to track how much
   time it took to run
3) Set HoldsQueueParallelLoopsCount to 10
4) Repeat step 2, note the improvement in speed
5) Experiment with other values for HoldsQueueParallelLoopsCount
6) prove t/db_dependent/HoldsQueue.t
Comment 22 Kyle M Hall (khall) 2021-10-13 15:03:59 UTC
Created attachment 126216 [details] [review]
Bug 28833: Speed up holds queue builder via parallel processing

The holds queue builder can take a very long time to run on systems with many holds. For example, a partner with 124,784 unfilled ( not found ) holds, is taking about 64 minutes to run. If we run that same number of holds in 5 parallel chunks ( splitting the number of records as evenly as possible, but *not* taking into account the holds per bib ), it takes 21.5 minutes. If we use 10 loops, it takes less then 14 minutes.

Test Plan:
0) Install the Perl library Parallel::ForkManager
1) Generate a huge number of holds ( a few thousand at the minimum )
2) Run the holds queue builder, use the `time` utility to track how much
   time it took to run
3) Set HoldsQueueParallelLoopsCount to 10
4) Repeat step 2, note the improvement in speed
5) Experiment with other values for HoldsQueueParallelLoopsCount
6) prove t/db_dependent/HoldsQueue.t
Comment 23 David Nind 2023-10-22 20:11:05 UTC
As expected, since this has been in the sign off queue for a while, the patch no longer applies 8-(...

Is there a way to generate a large number of holds? Either an SQL query or a script.


kohadev-koha@kohadevbox:koha(bz28833)$ git bz apply 28833

Bug 28833 - Speed up holds queue builder via parallel processing

126216 - Bug 28833: Speed up holds queue builder via parallel processing

Apply? [(y)es, (n)o, (i)nteractive] y
Applying: Bug 28833: Speed up holds queue builder via parallel processing
Using index info to reconstruct a base tree...
M	C4/HoldsQueue.pm
M	debian/templates/koha-conf-site.xml.in
M	etc/koha-conf.xml
M	misc/cronjobs/holds/build_holds_queue.pl
Falling back to patching base and 3-way merge...
Auto-merging misc/cronjobs/holds/build_holds_queue.pl
CONFLICT (content): Merge conflict in misc/cronjobs/holds/build_holds_queue.pl
Auto-merging etc/koha-conf.xml
CONFLICT (content): Merge conflict in etc/koha-conf.xml
Auto-merging debian/templates/koha-conf-site.xml.in
CONFLICT (content): Merge conflict in debian/templates/koha-conf-site.xml.in
Auto-merging C4/HoldsQueue.pm
CONFLICT (content): Merge conflict in C4/HoldsQueue.pm
error: Failed to merge in the changes.
Patch failed at 0001 Bug 28833: Speed up holds queue builder via parallel processing
Comment 24 Kyle M Hall (khall) 2024-06-03 14:56:46 UTC
Created attachment 167349 [details] [review]
Bug 28833: Speed up holds queue builder via parallel processing

The holds queue builder can take a very long time to run on systems with many holds. For example, a partner with 124,784 unfilled ( not found ) holds, is taking about 64 minutes to run. If we run that same number of holds in 5 parallel chunks ( splitting the number of records as evenly as possible, but *not* taking into account the holds per bib ), it takes 21.5 minutes. If we use 10 loops, it takes less then 14 minutes.

Test Plan:
0) Install the Perl library Parallel::ForkManager
1) Generate a huge number of holds ( a few thousand at the minimum )
2) Run the holds queue builder, use the `time` utility to track how much
   time it took to run
3) Set HoldsQueueParallelLoopsCount to 10
4) Repeat step 2, note the improvement in speed
5) Experiment with other values for HoldsQueueParallelLoopsCount
6) prove t/db_dependent/HoldsQueue.t
Comment 25 David Nind 2024-06-03 21:50:51 UTC
Thanks Kyle for making the patch apply!

Is there an easy way to generate a large number of holds? Either an SQL query or a script.

David
Comment 26 Kyle M Hall (khall) 2024-06-04 13:39:31 UTC
(In reply to David Nind from comment #25)
> Thanks Kyle for making the patch apply!
> 
> Is there an easy way to generate a large number of holds? Either an SQL
> query or a script.
> 
> David

This script will generate 100 holds:

#!/usr/bin/perl
use t::lib::TestBuilder;
my $builder = t::lib::TestBuilder->new;

for ( my $i = 0 ; $i < 100 ; $i++ ) {
    my $hold = $builder->build( { source => 'Reserve' } );
}

Hope this helps!
Comment 27 Brendan Lawlor 2024-07-02 19:29:58 UTC
Test notes:

 > This script will generate 100 holds:
> 
> #!/usr/bin/perl
> use t::lib::TestBuilder;
> my $builder = t::lib::TestBuilder->new;
> 
> for ( my $i = 0 ; $i < 100 ; $i++ ) {
>     my $hold = $builder->build( { source => 'Reserve' } );
> }
> 

I ran this script 10+ times. I noticed that in addition to holds it also makes new patrons, branches, bibs and itemtypes, probably other stuff too. cool!

I could see 1000+ records in the reserves table, but if I went to a patron record where a hold was created by the script the holds table wouldn't load, with error 500. I wasn't able to build the holds queue.

Also the bib detail page returned the error:
DBIC result _type  isn't of the _type BiblioMetadata at /kohadevbox/koha/catalogue/detail.pl line 105.
 at /usr/lib/x86_64-linux-gnu/perl-base/Carp.pm line 289

I think the next step needs to be to reindex for the new bibs, so I tried:
koha-rebuild-zebra -f --force -v kohadev

Something is not working to reindex the bibs created by the script though, once it gets past the ktd default bibs it returns errors like
.error retrieving biblio 3000 at /kohadevbox/koha/misc/migration_tools/rebuild_zebra.pl line 706.

Am I missing a step in the reindexing part? What step/s are required after generating the test data?

I was able to install Parallel::ForkManager and use the time utility, so I will be able to test again once I can resolve the data issue. Thanks!
Comment 28 David Nind 2024-07-04 18:39:32 UTC
The patch no longer applies for me 8-(...

git bz apply 28833

Bug 28833 - Speed up holds queue builder via parallel processing

167349 - Bug 28833: Speed up holds queue builder via parallel processing

Apply? [(y)es, (n)o, (i)nteractive] y
Applying: Bug 28833: Speed up holds queue builder via parallel processing
Using index info to reconstruct a base tree...
M	C4/HoldsQueue.pm
M	debian/templates/koha-conf-site.xml.in
M	etc/koha-conf.xml
M	misc/cronjobs/holds/build_holds_queue.pl
Falling back to patching base and 3-way merge...
Auto-merging misc/cronjobs/holds/build_holds_queue.pl
CONFLICT (content): Merge conflict in misc/cronjobs/holds/build_holds_queue.pl
Auto-merging etc/koha-conf.xml
Auto-merging debian/templates/koha-conf-site.xml.in
Auto-merging C4/HoldsQueue.pm
CONFLICT (content): Merge conflict in C4/HoldsQueue.pm
error: Failed to merge in the changes.
Patch failed at 0001 Bug 28833: Speed up holds queue builder via parallel processing
Comment 29 Martin Renvoize (ashimema) 2024-10-18 07:04:52 UTC
Is this one still relevant Kyle?
Comment 30 Kyle M Hall (khall) 2024-10-21 12:38:30 UTC
Created attachment 173045 [details] [review]
Bug 28833: Speed up holds queue builder via parallel processing

The holds queue builder can take a very long time to run on systems with many holds. For example, a partner with 124,784 unfilled ( not found ) holds, is taking about 64 minutes to run. If we run that same number of holds in 5 parallel chunks ( splitting the number of records as evenly as possible, but *not* taking into account the holds per bib ), it takes 21.5 minutes. If we use 10 loops, it takes less then 14 minutes.

Test Plan:
0) Install the Perl library Parallel::ForkManager
1) Generate a huge number of holds ( a few thousand at the minimum )
2) Run the holds queue builder, use the `time` utility to track how much
   time it took to run
3) Set HoldsQueueParallelLoopsCount to 10
4) Repeat step 2, note the improvement in speed
5) Experiment with other values for HoldsQueueParallelLoopsCount
6) prove t/db_dependent/HoldsQueue.t
Comment 31 Kyle M Hall (khall) 2024-10-21 12:41:30 UTC
Created attachment 173046 [details] [review]
Bug 28833: Speed up holds queue builder via parallel processing

The holds queue builder can take a very long time to run on systems with many holds. For example, a partner with 124,784 unfilled ( not found ) holds, is taking about 64 minutes to run. If we run that same number of holds in 5 parallel chunks ( splitting the number of records as evenly as possible, but *not* taking into account the holds per bib ), it takes 21.5 minutes. If we use 10 loops, it takes less then 14 minutes.

Test Plan:
0) Install the Perl library Parallel::ForkManager
1) Generate a huge number of holds ( a few thousand at the minimum )
2) Run the holds queue builder, use the `time` utility to track how much
   time it took to run
3) Set HoldsQueueParallelLoopsCount to 10
4) Repeat step 2, note the improvement in speed
5) Experiment with other values for HoldsQueueParallelLoopsCount
6) prove t/db_dependent/HoldsQueue.t
Comment 32 Martin Renvoize (ashimema) 2024-10-24 11:43:35 UTC
Created attachment 173262 [details] [review]
Bug 28833: Speed up holds queue builder via parallel processing

The holds queue builder can take a very long time to run on systems with many holds. For example, a partner with 124,784 unfilled ( not found ) holds, is taking about 64 minutes to run. If we run that same number of holds in 5 parallel chunks ( splitting the number of records as evenly as possible, but *not* taking into account the holds per bib ), it takes 21.5 minutes. If we use 10 loops, it takes less then 14 minutes.

Test Plan:
0) Install the Perl library Parallel::ForkManager
1) Generate a huge number of holds ( a few thousand at the minimum )
2) Run the holds queue builder, use the `time` utility to track how much
   time it took to run
3) Set HoldsQueueParallelLoopsCount to 10
4) Repeat step 2, note the improvement in speed
5) Experiment with other values for HoldsQueueParallelLoopsCount
6) prove t/db_dependent/HoldsQueue.t

Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
Comment 33 Martin Renvoize (ashimema) 2024-10-24 11:44:49 UTC
This works well and I see no regressions.

Passing QA
Comment 34 Katrin Fischer 2024-10-25 09:08:27 UTC
Wow, old style database update, reformatted to use the newer template on review.
I verified that the holds queue is still built running the script, but didn't test the parallel processing. Trusting the process :)
Comment 35 Katrin Fischer 2024-10-25 09:12:21 UTC
Pushed for 24.11!

Well done everyone, thank you!
Comment 36 Philip Orr 2024-11-08 14:44:00 UTC
added release notes
Comment 37 Lucas Gass (lukeg) 2024-11-18 23:07:24 UTC
Enhancement, no 24.05.x backport
Comment 38 David Nind 2024-11-19 04:23:30 UTC
Changed status to needs documenting - new system preference that needs documenting.