Bug 35948: Add jobs_unfinished_days and jobs_unfinished_type to cleanup_database.pl

This patch adds two new parameters to control the deletion of background jobs that did not complete.
Some libraries may want to keep a failed job longer than a completed one for debugging reasons.

To test:
0 - Apply patch
1 - Make some old failed jobs:
    INSERT INTO background_jobs (status,type,enqueued_on) VALUES
    ('started','update_elastic_index','2020-01-01'),
    ('failed','update_elastic_index','2026-01-01'),
    ('started','other_type','2021-01-01'),
    ('failed','other_type','2026-01-01');
2 - Confirm defaults of 365 and update_elastic_index for new params:
    perl misc/cronjobs/cleanup_database.pl -v --jobs-unfinished-days
3 - Should indicate 1 job older than 365 of type update_elastic_index would have been deleted
4 - Confirm days param works
    perl misc/cronjobs/cleanup_database.pl -v --jobs-unfinished-days 30
5 - Shoudl find 2 elastic jobs
6 - Confirm type param
    perl misc/cronjobs/cleanup_database.pl -v --jobs-unfinished-days --jobs-unfinished-type=other_type
7 - Should find 1
8 - Confirm type and days
    perl misc/cronjobs/cleanup_database.pl -v --jobs-unfinished-days 30 --jobs-unfinished-type=other_type
9 - Should find 2
10 - Confirm repeated type
     perl misc/cronjobs/cleanup_database.pl -v --jobs-unfinished-days=30 --jobs-unfinished-type=other_type --jobs-unfinished-type=update_elastic_index
11 - Finds 4
12 - Confirm deletion
     perl misc/cronjobs/cleanup_database.pl -v --jobs-unfinished-days=30 --jobs-unfinished-type=other_type --jobs-unfinished-type=update_elastic_index --confirm
13 - All your made up jobs are removed

Signed-off-by: Trevor Diamond <trevor.diamond@mainlib.org>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This commit is contained in:
Nick Clemens 2026-05-22 14:25:23 +00:00 committed by Pedro Amorim
parent f81ec88697
commit c81d27de08
No known key found for this signature in database
GPG Key ID: 06B75BA7F3894D55
1 changed files with 50 additions and 11 deletions

View File

@ -29,6 +29,8 @@ use constant DEFAULT_SHARE_INVITATION_EXPIRY_DAYS => 14;
use constant DEFAULT_DEBARMENTS_PURGEDAYS => 30;
use constant DEFAULT_JOBS_PURGEDAYS => 1;
use constant DEFAULT_JOBS_PURGETYPES => qw{ update_elastic_index };
use constant DEFAULT_JOBS_UNFINISHED_PURGEDAYS => 365;
use constant DEFAULT_JOBS_UNFINISHED_PURGETYPES => qw{ update_elastic_index };
use constant DEFAULT_EDIFACT_MSG_PURGEDAYS => 365;
use Getopt::Long qw( GetOptions );
@ -124,6 +126,9 @@ Usage: $0
--cards DAY Purge card creator batches last added to more than DAYS days ago.
--return-claims Purge all resolved return claims older than the number of days specified in
the system preference CleanUpDatabaseReturnClaims.
--jobs-unfinished-days DAYS Purge all unfinished background jobs this many days old. Defaults to 365 if no DAYS provided.
--jobs-unfinished-type TYPES What type of unfinished background jobs to purge. Defaults to "update_elastic_index" if omitted
Specifying "all" will purge all types. Repeatable.
--jobs-days DAYS Purge all finished background jobs this many days old. Defaults to 1 if no DAYS provided.
--jobs-type TYPES What type of background job to purge. Defaults to "update_elastic_index" if omitted
Specifying "all" will purge all types. Repeatable.
@ -174,6 +179,8 @@ my $cards;
my @log_modules;
my @preserve_logs;
my @log_actions;
my $jobs_unfinished_days;
my @jobs_unfinished_types;
my $jobs_days;
my @jobs_types;
my $reports;
@ -224,6 +231,8 @@ GetOptions(
'labels:i' => \$labels,
'cards:i' => \$cards,
'return-claims' => \$return_claims,
'jobs-unfinished-type:s' => \@jobs_unfinished_types,
'jobs-unfinished-days:i' => \$jobs_unfinished_days,
'jobs-type:s' => \@jobs_types,
'jobs-days:i' => \$jobs_days,
'reports:i' => \$reports,
@ -231,17 +240,20 @@ GetOptions(
) || usage(1);
# Use default values
$sessions = 1 if $sess_days && $sess_days > 0;
$pImport = DEFAULT_IMPORT_PURGEDAYS if defined($pImport) && $pImport == 0;
$pLogs = DEFAULT_LOGS_PURGEDAYS if defined($pLogs) && $pLogs == 0;
$zebraqueue_days = DEFAULT_ZEBRAQ_PURGEDAYS if defined($zebraqueue_days) && $zebraqueue_days == 0;
$mail = DEFAULT_MAIL_PURGEDAYS if defined($mail) && $mail == 0;
$pSearchhistory = DEFAULT_SEARCHHISTORY_PURGEDAYS if defined($pSearchhistory) && $pSearchhistory == 0;
$pDebarments = DEFAULT_DEBARMENTS_PURGEDAYS if defined($pDebarments) && $pDebarments == 0;
$pMessages = DEFAULT_MESSAGES_PURGEDAYS if defined($pMessages) && $pMessages == 0;
$jobs_days = DEFAULT_JOBS_PURGEDAYS if defined($jobs_days) && $jobs_days == 0;
@jobs_types = (DEFAULT_JOBS_PURGETYPES) if $jobs_days && @jobs_types == 0;
$edifact_msg_days = DEFAULT_EDIFACT_MSG_PURGEDAYS if defined($edifact_msg_days) && $edifact_msg_days == 0;
$sessions = 1 if $sess_days && $sess_days > 0;
$pImport = DEFAULT_IMPORT_PURGEDAYS if defined($pImport) && $pImport == 0;
$pLogs = DEFAULT_LOGS_PURGEDAYS if defined($pLogs) && $pLogs == 0;
$zebraqueue_days = DEFAULT_ZEBRAQ_PURGEDAYS if defined($zebraqueue_days) && $zebraqueue_days == 0;
$mail = DEFAULT_MAIL_PURGEDAYS if defined($mail) && $mail == 0;
$pSearchhistory = DEFAULT_SEARCHHISTORY_PURGEDAYS if defined($pSearchhistory) && $pSearchhistory == 0;
$pDebarments = DEFAULT_DEBARMENTS_PURGEDAYS if defined($pDebarments) && $pDebarments == 0;
$pMessages = DEFAULT_MESSAGES_PURGEDAYS if defined($pMessages) && $pMessages == 0;
$jobs_unfinished_days = DEFAULT_JOBS_UNFINISHED_PURGEDAYS
if defined($jobs_unfinished_days) && $jobs_unfinished_days == 0;
@jobs_unfinished_types = (DEFAULT_JOBS_UNFINISHED_PURGETYPES) if $jobs_unfinished_days && @jobs_unfinished_types == 0;
$jobs_days = DEFAULT_JOBS_PURGEDAYS if defined($jobs_days) && $jobs_days == 0;
@jobs_types = (DEFAULT_JOBS_PURGETYPES) if $jobs_days && @jobs_types == 0;
$edifact_msg_days = DEFAULT_EDIFACT_MSG_PURGEDAYS if defined($edifact_msg_days) && $edifact_msg_days == 0;
@statistics_types = ( @statistics_types, @Koha::Statistic::pseudonymization_types ) if defined($statistics_type_pseudo);
@statistics_types = keys %{ { map { $_, 1 } @statistics_types } }; # remove duplicate types
@ -295,6 +307,7 @@ unless ( $sessions
|| $cards
|| $return_claims
|| $jobs_days
|| $jobs_unfinished_days
|| $reports
|| $edifact_msg_days )
{
@ -780,6 +793,32 @@ if ($cards) {
}
}
if ($jobs_unfinished_days) {
print "Purging unfinished background jobs more than $jobs_unfinished_days days ago.\n"
if $verbose;
my $jobs = Koha::BackgroundJobs->search(
{
status => { '!=' => 'finished' },
( $jobs_unfinished_types[0] eq 'all' ? () : ( type => \@jobs_unfinished_types ) )
}
)->filter_by_last_update(
{
timestamp_column_name => 'enqueued_on',
days => $jobs_unfinished_days,
}
);
my $count = $jobs->count;
$jobs->delete if $confirm;
if ($verbose) {
say $confirm
? sprintf "Done with purging unfinished %d background jobs of type(s): %s added more than %d days ago.\n",
$count, join( ',', @jobs_unfinished_types ), $jobs_unfinished_days
: sprintf
"%d unfinished background jobs of type(s): %s added more than %d days ago would have been purged.",
$count, join( ',', @jobs_unfinished_types ), $jobs_unfinished_days;
}
}
if ($jobs_days) {
print "Purging background jobs more than $jobs_days days ago.\n"
if $verbose;