From 697fd49b727f80f9e63ab24770f8fa37d436c2b8 Mon Sep 17 00:00:00 2001 From: Jonathan Druart Date: Thu, 24 Feb 2022 10:41:16 +0100 Subject: [PATCH] Bug 30172: Prevent race condition when enqueuing a new task As we are sending the job to the rabbitmq before in the transaction, the worker can receive the job to process before the transaction committed. --- Koha/BackgroundJob.pm | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/Koha/BackgroundJob.pm b/Koha/BackgroundJob.pm index cb8a71fb046..c9f1a89ada7 100644 --- a/Koha/BackgroundJob.pm +++ b/Koha/BackgroundJob.pm @@ -117,26 +117,29 @@ sub enqueue { $job_id = $self->id; $job_args->{job_id} = $job_id; $json_args = encode_json $job_args; - - try { - my $conn = $self->connect; - # This namespace is wrong, it must be a vhost instead. - # But to do so it needs to be created on the server => much more work when a new Koha instance is created. - # Also, here we just want the Koha instance's name, but it's not in the config... - # Picking a random id (memcached_namespace) from the config - my $namespace = C4::Context->config('memcached_namespace'); - $conn->send_with_receipt( { destination => sprintf("/queue/%s-%s", $namespace, $job_type), body => $json_args } ) - or Koha::Exceptions::Exception->throw('Job has not been enqueued'); - } catch { - if ( ref($_) eq 'Koha::Exceptions::Exception' ) { - $_->rethrow; - } else { - warn sprintf "The job has not been sent to the message broker: (%s)", $_; - } - }; } ); + Koha::Exceptions::Exception->throw('Job has not been enqueued') + unless $job_id; + + try { + my $conn = $self->connect; + # This namespace is wrong, it must be a vhost instead. + # But to do so it needs to be created on the server => much more work when a new Koha instance is created. + # Also, here we just want the Koha instance's name, but it's not in the config... + # Picking a random id (memcached_namespace) from the config + my $namespace = C4::Context->config('memcached_namespace'); + $conn->send_with_receipt( { destination => sprintf("/queue/%s-%s", $namespace, $job_type), body => $json_args } ) + or Koha::Exceptions::Exception->throw('Job has not been enqueued'); + } catch { + if ( ref($_) eq 'Koha::Exceptions::Exception' ) { + $_->rethrow; + } else { + warn sprintf "The job has not been sent to the message broker: (%s)", $_; + } + }; + return $job_id; } -- 2.25.1