Bug 41920: Limit number of concurrent reports that can be run simultaneously for an instance of Koha
As a continuation of bug 41919, we should limit the total number of simultaneous reports that can be run at a time. Test Plan: 1) Set total_running_reports_per_instance_limit to 2 in your koha-conf.xml 2) Create 3 long running reports like: SELECT COUNT(*) FROM items i1 JOIN items i2 JOIN items i3 JOIN items i4 JOIN items i5 JOIN items i6 3) Run each report in turn by opening a new tab, browsing to the reports module, and choosing to run that report 5) Note the first two continue to run, but the last one gives an error that you have too many reports running simultaneously! Signed-off-by: Alex Carver [Acerock7] <alex@rcls.org> Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com> Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This commit is contained in:
parent
92cbbd59d5
commit
7ba7bbab7d
|
|
@ -103,7 +103,8 @@ sub running {
|
|||
$report_ids{$1} = 1 if $row->{info} =~ /saved_sql\.id:\s*(\d+)/;
|
||||
}
|
||||
|
||||
return $class->search( { id => { -in => [ keys %report_ids ] } } );
|
||||
my $rs = $class->search( { id => { -in => [ keys %report_ids ] } } );
|
||||
return wantarray ? $rs->as_list : $rs;
|
||||
}
|
||||
|
||||
=head3 _processlist_rows
|
||||
|
|
|
|||
|
|
@ -348,6 +348,7 @@ __END_SRU_PUBLICSERVER__
|
|||
<!-- SQL report limits, 0 means the feature is disabled -->
|
||||
<duplicate_running_reports_per_user_limit>0</duplicate_running_reports_per_user_limit>
|
||||
<total_running_reports_per_user_limit>0</total_running_reports_per_user_limit>
|
||||
<total_running_reports_per_instance_limit>0</total_running_reports_per_instance_limit>
|
||||
|
||||
<!-- Configuration for X-Forwarded-For -->
|
||||
<!-- Set enable_trusted_proxy_for_headers to 0 to never trust proxy headers, always use given REMOTE_ADDRESS -->
|
||||
|
|
|
|||
|
|
@ -165,6 +165,7 @@
|
|||
<!-- SQL report limits, 0 means the feature is disabled -->
|
||||
<duplicate_running_reports_per_user_limit>0</duplicate_running_reports_per_user_limit>
|
||||
<total_running_reports_per_user_limit>0</total_running_reports_per_user_limit>
|
||||
<total_running_reports_per_instance_limit>0</total_running_reports_per_instance_limit>
|
||||
|
||||
<!-- Configuration for X-Forwarded-For -->
|
||||
<!-- Set enable_trusted_proxy_for_headers to 0 to never trust proxy headers, always use given REMOTE_ADDRESS -->
|
||||
|
|
|
|||
|
|
@ -1714,6 +1714,8 @@
|
|||
<p>This report is already running. Please wait for it to finish before running it again.</p>
|
||||
[% ELSIF ( error.total_running_reports_limit_exceeded ) %]
|
||||
<p>You have too many reports running at the moment. Please wait for some of them to finish before running this report again.</p>
|
||||
[% ELSIF ( error.total_running_reports_per_instance_limit_exceeded ) %]
|
||||
<p>There are too many total reports running at the moment. Please wait for some of them to finish before running this report again.</p>
|
||||
[% ELSIF ( error.sqlerr ) %]
|
||||
<p>This report contains an SQL keyword: <strong>[% error.sqlerr | html %]</strong>. </p>
|
||||
<p>Use of this keyword is not allowed in Koha reports due to security and data integrity risks. Only SELECT queries are allowed.</p>
|
||||
|
|
|
|||
|
|
@ -885,6 +885,42 @@ if ( $op eq 'run' ) {
|
|||
my $template_code = $input->param('template_code');
|
||||
my $want_full_chart = $input->param('want_full_chart') || 0;
|
||||
|
||||
# Determine if the user is running this report too many times
|
||||
my @duplicate_running_report_ids;
|
||||
my $duplicate_running_reports_per_user_limit = C4::Context->config('duplicate_running_reports_per_user_limit');
|
||||
if ( $duplicate_running_reports_per_user_limit && C4::Context->userenv ) {
|
||||
my $user_id = C4::Context->userenv ? C4::Context->userenv->{number} : undef;
|
||||
@duplicate_running_report_ids = Koha::Reports->running( { report_id => $report_id, user_id => $user_id } );
|
||||
}
|
||||
my $duplicate_running_reports_per_user_limit_exceeded =
|
||||
$duplicate_running_reports_per_user_limit
|
||||
? scalar(@duplicate_running_report_ids) >= $duplicate_running_reports_per_user_limit
|
||||
: 0;
|
||||
|
||||
# Determine if the user is running too many reports in total
|
||||
my @total_running_for_user_report_ids;
|
||||
my $total_running_reports_per_user_limit = C4::Context->config('total_running_reports_per_user_limit');
|
||||
if ( $total_running_reports_per_user_limit && C4::Context->userenv ) {
|
||||
my $user_id = C4::Context->userenv ? C4::Context->userenv->{number} : undef;
|
||||
@total_running_for_user_report_ids = Koha::Reports->running( { user_id => $user_id } );
|
||||
}
|
||||
my $total_running_reports_per_user_limit_exceeded =
|
||||
$total_running_reports_per_user_limit
|
||||
? scalar(@total_running_for_user_report_ids) >= $total_running_reports_per_user_limit
|
||||
: 0;
|
||||
|
||||
# Determine if the Koha instance is running too many reports in total
|
||||
my @total_running_for_instance_report_ids;
|
||||
my $total_running_reports_per_instance_limit = C4::Context->config('total_running_reports_per_instance_limit');
|
||||
if ( $total_running_reports_per_instance_limit && C4::Context->userenv ) {
|
||||
my $instance_id = C4::Context->userenv ? C4::Context->userenv->{number} : undef;
|
||||
@total_running_for_instance_report_ids = Koha::Reports->running();
|
||||
}
|
||||
my $total_running_reports_per_instance_limit_exceeded =
|
||||
$total_running_reports_per_instance_limit
|
||||
? scalar(@total_running_for_instance_report_ids) >= $total_running_reports_per_instance_limit
|
||||
: 0;
|
||||
|
||||
# offset algorithm
|
||||
if ( $input->param('page') ) {
|
||||
$offset = ( $input->param('page') - 1 ) * $limit;
|
||||
|
|
@ -1070,6 +1106,33 @@ if ( $op eq 'run' ) {
|
|||
'id' => $report_id,
|
||||
'template_code' => $template_code,
|
||||
);
|
||||
} elsif ( $duplicate_running_reports_per_user_limit_exceeded
|
||||
|| $total_running_reports_per_user_limit_exceeded
|
||||
|| $total_running_reports_per_instance_limit_exceeded )
|
||||
{
|
||||
$template->param(
|
||||
'sql' => $sql,
|
||||
'original_sql' => $original_sql,
|
||||
'id' => $report_id,
|
||||
'execute' => 1,
|
||||
'name' => $name,
|
||||
'notes' => $notes,
|
||||
'errors' => [
|
||||
$duplicate_running_reports_per_user_limit_exceeded
|
||||
? { duplicate_running_report_ids => \@duplicate_running_report_ids }
|
||||
: (),
|
||||
$total_running_reports_per_user_limit_exceeded
|
||||
? { total_running_reports_per_user_limit_exceeded => \@total_running_for_user_report_ids }
|
||||
: (),
|
||||
$total_running_reports_per_instance_limit_exceeded
|
||||
? {
|
||||
total_running_reports_per_instance_limit_exceeded => \@total_running_for_instance_report_ids
|
||||
}
|
||||
: (),
|
||||
],
|
||||
'sql_params' => \@sql_params,
|
||||
'param_names' => \@param_names,
|
||||
);
|
||||
} else {
|
||||
my ( $sql, $header_types );
|
||||
eval { ( $sql, $header_types ) = $report->prep_report( \@param_names, \@sql_params ); };
|
||||
|
|
|
|||
Loading…
Reference in New Issue