Koha/Koha/Z3950Responder.pm
Jonathan Druart e466c41304 Bug 25292: Flushing L1 on every Z3950 server search
This patch flushes the L1 cache on each Z3950 server search.

There is no need to flush it in init_handler (when the connection is
made), the L1 cache is not accessed (this behaviour goes against what I
expected).

This means each search will fetch values from the
L2 cache (ie memcached) and persist the L1 cache (in Perl
memory cache) until the result are returned (or longer?).

Test plan:
% perl misc/z3950_responder.pl --config-dir=/kohadevbox/koha/etc/z3950
% zoomsh
ZOOM>connect localhost:2100
ZOOM>set databaseName biblios
ZOOM>search x
ZOOM>search x

Between the 2 searches you can modify the value of SearchEngine, you
will notice that the number of hits is different

Signed-off-by: Fridolin Somers <fridolin.somers@biblibre.com>

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
2021-01-11 10:27:37 +01:00

216 lines
5.4 KiB
Perl

package Koha::Z3950Responder;
# Copyright ByWater Solutions 2016
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Koha is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Koha; if not, see <http://www.gnu.org/licenses>.
use Modern::Perl;
use C4::Biblio qw( GetMarcFromKohaField );
use C4::Koha qw( GetAuthorisedValues );
use Koha::Caches;
use Net::Z3950::SimpleServer;
=head1 NAME
Koha::Z3950Responder - Main class for interfacing with Net::Z3950::SimpleServer
=head1 SYNOPSIS
use Koha::Z3950Responder;
my $z = Koha::Z3950Responder->new( {
add_item_status_subfield => 1,
add_status_multi_subfield => 1,
debug => 0,
num_to_prefetch => 20,
config_dir => '/home/koha/etc',
yaz_options => [ ],
} );
$z->start();
=head1 DESCRIPTION
A daemon class that interfaces with Net::Z3950::SimpleServer to provider Z39.50/SRU
service. Uses a Session class for the actual functionality.
=head1 METHODS
=head2 INSTANCE METHODS
=head3 new
$self->new({
add_item_status_subfield => 1
});
=cut
sub new {
my ( $class, $config ) = @_;
my ($item_tag, $itemnumber_subfield) = GetMarcFromKohaField( "items.itemnumber" );
# We hardcode the strings for English so SOMETHING will work if the authorized value doesn't exist.
my $status_strings = {
AVAILABLE => 'Available',
CHECKED_OUT => 'Checked Out',
LOST => 'Lost',
NOT_FOR_LOAN => 'Not for Loan',
DAMAGED => 'Damaged',
WITHDRAWN => 'Withdrawn',
IN_TRANSIT => 'In Transit',
ON_HOLD => 'On Hold',
};
foreach my $val ( @{ GetAuthorisedValues( 'Z3950_STATUS' ) } ) {
$status_strings->{ $val->{authorised_value} } = $val->{lib};
}
my $self = {
%$config,
item_tag => $item_tag,
itemnumber_subfield => $itemnumber_subfield,
status_strings => $status_strings,
};
# If requested, turn on debugging.
if ( $self->{debug} ) {
# Turn on single-process mode.
unshift @{ $self->{yaz_options} }, '-S';
} else {
# Turn off Yaz's built-in logging apart from fatal errors (can be turned back on if desired).
unshift @{ $self->{yaz_options} }, '-v', 'none,fatal';
}
# Set main config for SRU support and working directory
if ( $self->{config_dir} ) {
unshift @{ $self->{yaz_options} }, '-f', $self->{config_dir} . 'config.xml';
unshift @{ $self->{yaz_options} }, '-w', $self->{config_dir};
}
# Set num to prefetch if not passed
$self->{num_to_prefetch} //= 20;
$self->{server} = Net::Z3950::SimpleServer->new(
INIT => sub { $self->init_handler(@_) },
SEARCH => sub { $self->search_handler(@_) },
FETCH => sub { $self->fetch_handler(@_) },
CLOSE => sub { $self->close_handler(@_) },
);
return bless( $self, $class );
}
=head3 start
$z->start();
Start the daemon and begin serving requests. Does not return unless initialization fails or a
fatal error occurs.
=cut
sub start {
my ( $self ) = @_;
$self->{server}->launch_server( 'Koha::Z3950Responder', @{ $self->{yaz_options} } )
}
=head2 CALLBACKS
These methods are SimpleServer callbacks bound to this Z3950Responder object.
It's worth noting that these callbacks don't return anything; they both
receive and return data in the $args hashref.
=head3 init_handler
Callback that is called when a new connection is initialized
=cut
sub init_handler {
# Called when the client first connects.
my ( $self, $args ) = @_;
# This holds all of the per-connection state.
my $session;
if (C4::Context->preference('SearchEngine') eq 'Zebra') {
use Koha::Z3950Responder::ZebraSession;
$session = Koha::Z3950Responder::ZebraSession->new({
server => $self,
peer => $args->{PEER_NAME},
});
} else {
use Koha::Z3950Responder::GenericSession;
$session = Koha::Z3950Responder::GenericSession->new({
server => $self,
peer => $args->{PEER_NAME}
});
}
$args->{HANDLE} = $session;
$args->{IMP_NAME} = "Koha";
$args->{IMP_VER} = Koha::version;
}
=head3 search_handler
Callback that is called when a new search is performed
=cut
sub search_handler {
my ( $self, $args ) = @_;
my $SearchEngine = C4::Context->preference('SearchEngine');
# Flushing L1 to make sure the search will be processed using the correct data
Koha::Caches->flush_L1_caches();
$self->init_handler($args)
if $SearchEngine ne C4::Context->preference('SearchEngine');
$args->{HANDLE}->search_handler($args);
}
=head3 fetch_handler
Callback that is called when records are requested
=cut
sub fetch_handler {
my ( $self, $args ) = @_;
$args->{HANDLE}->fetch_handler( $args );
}
=head3 close_handler
Callback that is called when a session is terminated
=cut
sub close_handler {
my ( $self, $args ) = @_;
$args->{HANDLE}->close_handler( $args );
}
1;