Commit 55e705f1 authored by bensinober's avatar bensinober Committed by Benjamin
Browse files

DEICH-5660 koha: add a file based locking state for circulation

parent 5e3b0a5e
......@@ -75,6 +75,7 @@ sub do_checkin {
my $item = Deichman::Item->new()->Get($self->{item}->{itemnumber});
my $lib = Deichman::Library->new()->Get($branch);
my $circ = Core::Deichman::Circulation::SIP->new({ item => $item, library => $lib });
$circ->setActiveCheckinState();
$circ->Checkin($return_date); # SHOULD WE TRUST SIP RETURN DATE?
my $messages = $circ->{messages};
my $iteminformation = $circ->{iteminformation};
......@@ -156,6 +157,7 @@ sub do_checkin {
$self->{item}->destination_loc($item->{destination}->{dest});
$self->alert(1) if defined $self->alert_type; # alert_type could be "00", hypothetically
$circ->{error} ? $self->ok(0) : $self->ok(1);
$circ->unsetActiveCheckinState();
}
sub resensitize {
......
......@@ -13,6 +13,7 @@ use DateTime;
use DateTime::Duration;
use DateTime::Format::Strptime;
use POSIX qw /floor/;
use Fcntl qw(:flock);
use Deichman::BiblioItem;
use Deichman::IssuingRule;
......@@ -57,6 +58,7 @@ use parent qw(Deichman::Main);
messages : legacy messages hashmap (for ui/SIP)
iteminfo : legacy iteminfo hashmap (for ui/SIP)
=cut
our $lockfile = "/tmp/circulation.lock";
sub new {
my ($class, $args) = @_;
($args->{item} and $args->{library}) or Core::Exception::Circulation::ArgumentError->throw("Missing item or library");
......@@ -1144,4 +1146,24 @@ sub removeOverdueDebarments {
}
}
# DEICH-5660 - introducing a file-based circulation lock
# uses linux non blocking file lock with an alarm signal timeout of 3 secs to prevent unforseen deadlocks
sub setActiveCheckinState {
try {
open(FILE, ">>", $lockfile) or Core::Exception::Circulation->throw("Failed opening circulation lockfile $lockfile");
local $SIG{ALRM} = sub { Core::Exception::Circulation::LockTimeOut->throw(); }; # alarm handler
alarm(3);
until (my $res = flock(FILE, LOCK_EX|LOCK_NB)) {}
alarm(0);
} catch {
if ($_->isa("Core::Exception::Circulation::LockTimeOut")) {
flock(FILE, LOCK_UN); # remove lock after alarm signal
}
};
}
sub unsetActiveCheckinState {
open(FILE, ">>", $lockfile) or Core::Exception::Circulation->throw("Failed opening circulation lockfile $lockfile");
flock(FILE, LOCK_UN);
}
1;
......@@ -51,6 +51,10 @@ use Exception::Class (
"Core::Exception::Circulation::Checkout::CheckedOutToAnother" => {
description => "Unable to checkout - checked out to another",
isa => "Core::Exception::Circulation::Checkout",
},
"Core::Exception::Circulation::LockTimeOut" => {
description => "Circulation Lock Timeout",
isa => "Core::Exception::Circulation",
}
);
......
......@@ -272,6 +272,7 @@ resource item => sub {
item => $item,
library => $lib,
});
$circ->setActiveCheckinState();
$circ->Checkin();
if ($circ->{error} and not $circ->{error}->isa("Core::Exception::Circulation::Checkout::NotFound") ) {
Deichman::Exception::Item::CheckinFailure->throw($circ->{messages});
......@@ -292,6 +293,7 @@ resource item => sub {
my $p = Deichman::Picklist->new();
$p->Reset($item->{item}->{biblionumber});
}
$circ->unsetActiveCheckinState();
app->logg(info => "checkin item. id: " . $params->{barcode} . " branchcode: " .$params->{branchcode});
# $circ->{messages} is for legacy support (intra/sip), we should provide something better
{ messages => $circ->{messages}, item => $item->{item}, biblio => $biblio->{biblio}, metadata => $biblio->{metadata} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment