Lines 5-10
use strict;
Link Here
|
5 |
|
5 |
|
6 |
use C4::Context; |
6 |
use C4::Context; |
7 |
use Getopt::Long; |
7 |
use Getopt::Long; |
|
|
8 |
use Fcntl qw(:flock); |
8 |
use File::Temp qw/ tempdir /; |
9 |
use File::Temp qw/ tempdir /; |
9 |
use File::Path; |
10 |
use File::Path; |
10 |
use C4::Biblio; |
11 |
use C4::Biblio; |
Lines 151-162
my $dbh = C4::Context->dbh;
Link Here
|
151 |
my ($biblionumbertagfield,$biblionumbertagsubfield) = &GetMarcFromKohaField("biblio.biblionumber",""); |
152 |
my ($biblionumbertagfield,$biblionumbertagsubfield) = &GetMarcFromKohaField("biblio.biblionumber",""); |
152 |
my ($biblioitemnumbertagfield,$biblioitemnumbertagsubfield) = &GetMarcFromKohaField("biblioitems.biblioitemnumber",""); |
153 |
my ($biblioitemnumbertagfield,$biblioitemnumbertagsubfield) = &GetMarcFromKohaField("biblioitems.biblioitemnumber",""); |
153 |
|
154 |
|
|
|
155 |
# Protect against simultaneous update of the zebra index by using a lock file. |
156 |
# Create our own lock directory if its missing. This shouild be created |
157 |
# by koha-zebra-ctl.sh. |
158 |
|
159 |
my $lockdir = C4::Context->config("zebra_lockdir") // "/var/lock"; |
160 |
$lockdir .= '/rebuild'; |
161 |
mkpath($lockdir, 0, oct(755)) unless (-d $lockdir); |
162 |
my $lockfile = $lockdir . "/rebuild..LCK"; |
163 |
|
154 |
if ( $verbose_logging ) { |
164 |
if ( $verbose_logging ) { |
155 |
print "Zebra configuration information\n"; |
165 |
print "Zebra configuration information\n"; |
156 |
print "================================\n"; |
166 |
print "================================\n"; |
157 |
print "Zebra biblio directory = $biblioserverdir\n"; |
167 |
print "Zebra biblio directory = $biblioserverdir\n"; |
158 |
print "Zebra authorities directory = $authorityserverdir\n"; |
168 |
print "Zebra authorities directory = $authorityserverdir\n"; |
159 |
print "Koha directory = $kohadir\n"; |
169 |
print "Koha directory = $kohadir\n"; |
|
|
170 |
print "Lockfile = $lockfile\n"; |
160 |
print "BIBLIONUMBER in : $biblionumbertagfield\$$biblionumbertagsubfield\n"; |
171 |
print "BIBLIONUMBER in : $biblionumbertagfield\$$biblionumbertagsubfield\n"; |
161 |
print "BIBLIOITEMNUMBER in : $biblioitemnumbertagfield\$$biblioitemnumbertagsubfield\n"; |
172 |
print "BIBLIOITEMNUMBER in : $biblioitemnumbertagfield\$$biblioitemnumbertagsubfield\n"; |
162 |
print "================================\n"; |
173 |
print "================================\n"; |
Lines 164-176
if ( $verbose_logging ) {
Link Here
|
164 |
|
175 |
|
165 |
my $tester = XML::LibXML->new(); |
176 |
my $tester = XML::LibXML->new(); |
166 |
|
177 |
|
|
|
178 |
# The main work is done here by calling do_one_pass(). We have added locking |
179 |
# avoid race conditions between Full rebuilds and incremental updates either from |
180 |
# daemon mode or periodic invocation from cron. The race can lead to an updated |
181 |
# record being overwritten by a rebuild if the update is applied after the export |
182 |
# by the rebuild and before the rebuild finishes (more likely to effect large |
183 |
# catalogs). |
184 |
open my $LockFH, q{>}, $lockfile or die "$lockfile: $!"; |
167 |
if ($daemon_mode) { |
185 |
if ($daemon_mode) { |
168 |
while (1) { |
186 |
while (1) { |
169 |
do_one_pass() if ( zebraqueue_not_empty() ); |
187 |
# For incremental updates, skip the update if the updates are locked |
|
|
188 |
if (flock($LockFH, LOCK_EX|LOCK_NB)) { |
189 |
do_one_pass() if ( zebraqueue_not_empty() ); |
190 |
flock($LockFH, LOCK_UN); |
191 |
} |
170 |
sleep $daemon_sleep; |
192 |
sleep $daemon_sleep; |
171 |
} |
193 |
} |
172 |
} else { |
194 |
} else { |
|
|
195 |
# all one-off invocations, wait for the lock to free |
196 |
flock($LockFH, LOCK_EX); |
173 |
do_one_pass(); |
197 |
do_one_pass(); |
|
|
198 |
flock($LockFH, LOCK_UN); |
174 |
} |
199 |
} |
175 |
|
200 |
|
176 |
|
201 |
|