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 { ...@@ -75,6 +75,7 @@ sub do_checkin {
my $item = Deichman::Item->new()->Get($self->{item}->{itemnumber}); my $item = Deichman::Item->new()->Get($self->{item}->{itemnumber});
my $lib = Deichman::Library->new()->Get($branch); my $lib = Deichman::Library->new()->Get($branch);
my $circ = Core::Deichman::Circulation::SIP->new({ item => $item, library => $lib }); my $circ = Core::Deichman::Circulation::SIP->new({ item => $item, library => $lib });
$circ->setActiveCheckinState();
$circ->Checkin($return_date); # SHOULD WE TRUST SIP RETURN DATE? $circ->Checkin($return_date); # SHOULD WE TRUST SIP RETURN DATE?
my $messages = $circ->{messages}; my $messages = $circ->{messages};
my $iteminformation = $circ->{iteminformation}; my $iteminformation = $circ->{iteminformation};
...@@ -156,6 +157,7 @@ sub do_checkin { ...@@ -156,6 +157,7 @@ sub do_checkin {
$self->{item}->destination_loc($item->{destination}->{dest}); $self->{item}->destination_loc($item->{destination}->{dest});
$self->alert(1) if defined $self->alert_type; # alert_type could be "00", hypothetically $self->alert(1) if defined $self->alert_type; # alert_type could be "00", hypothetically
$circ->{error} ? $self->ok(0) : $self->ok(1); $circ->{error} ? $self->ok(0) : $self->ok(1);
$circ->unsetActiveCheckinState();
} }
sub resensitize { sub resensitize {
......
...@@ -13,6 +13,7 @@ use DateTime; ...@@ -13,6 +13,7 @@ use DateTime;
use DateTime::Duration; use DateTime::Duration;
use DateTime::Format::Strptime; use DateTime::Format::Strptime;
use POSIX qw /floor/; use POSIX qw /floor/;
use Fcntl qw(:flock);
use Deichman::BiblioItem; use Deichman::BiblioItem;
use Deichman::IssuingRule; use Deichman::IssuingRule;
...@@ -57,6 +58,7 @@ use parent qw(Deichman::Main); ...@@ -57,6 +58,7 @@ use parent qw(Deichman::Main);
messages : legacy messages hashmap (for ui/SIP) messages : legacy messages hashmap (for ui/SIP)
iteminfo : legacy iteminfo hashmap (for ui/SIP) iteminfo : legacy iteminfo hashmap (for ui/SIP)
=cut =cut
our $lockfile = "/tmp/circulation.lock";
sub new { sub new {
my ($class, $args) = @_; my ($class, $args) = @_;
($args->{item} and $args->{library}) or Core::Exception::Circulation::ArgumentError->throw("Missing item or library"); ($args->{item} and $args->{library}) or Core::Exception::Circulation::ArgumentError->throw("Missing item or library");
...@@ -1144,4 +1146,24 @@ sub removeOverdueDebarments { ...@@ -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; 1;
...@@ -51,6 +51,10 @@ use Exception::Class ( ...@@ -51,6 +51,10 @@ use Exception::Class (
"Core::Exception::Circulation::Checkout::CheckedOutToAnother" => { "Core::Exception::Circulation::Checkout::CheckedOutToAnother" => {
description => "Unable to checkout - checked out to another", description => "Unable to checkout - checked out to another",
isa => "Core::Exception::Circulation::Checkout", isa => "Core::Exception::Circulation::Checkout",
},
"Core::Exception::Circulation::LockTimeOut" => {
description => "Circulation Lock Timeout",
isa => "Core::Exception::Circulation",
} }
); );
......
...@@ -272,6 +272,7 @@ resource item => sub { ...@@ -272,6 +272,7 @@ resource item => sub {
item => $item, item => $item,
library => $lib, library => $lib,
}); });
$circ->setActiveCheckinState();
$circ->Checkin(); $circ->Checkin();
if ($circ->{error} and not $circ->{error}->isa("Core::Exception::Circulation::Checkout::NotFound") ) { if ($circ->{error} and not $circ->{error}->isa("Core::Exception::Circulation::Checkout::NotFound") ) {
Deichman::Exception::Item::CheckinFailure->throw($circ->{messages}); Deichman::Exception::Item::CheckinFailure->throw($circ->{messages});
...@@ -292,6 +293,7 @@ resource item => sub { ...@@ -292,6 +293,7 @@ resource item => sub {
my $p = Deichman::Picklist->new(); my $p = Deichman::Picklist->new();
$p->Reset($item->{item}->{biblionumber}); $p->Reset($item->{item}->{biblionumber});
} }
$circ->unsetActiveCheckinState();
app->logg(info => "checkin item. id: " . $params->{barcode} . " branchcode: " .$params->{branchcode}); app->logg(info => "checkin item. id: " . $params->{barcode} . " branchcode: " .$params->{branchcode});
# $circ->{messages} is for legacy support (intra/sip), we should provide something better # $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} } { 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