Bug 42547: Fix SIP performance if sip2_resource_last_modified not set in cache

In Koha, the sip2_resource_last_modified key is updated any time the SIP config is edited from the SIP2 editor in the staff interface ( institutions, accounts, system preference overrides ).

If sip2_resource_last_modified is missing from memcached, Koha SIP emits "Couldn't find sip2_resource_last_modified, considering configuration not up to date" in the logs, and fetches the entire configuration from the database, *for each request*.

This causes SIP performance to drop significantly. In my production testing with 83 institutions and 171 accounts the login message response time dropped from 0.283 seconds to 2.899 seconds.

I think the solution is pretty simple. If there is a cache miss on sip2_resource_last_modified, SIP should load the config from database as it does already, but then it should also set sip2_resource_last_modified!

Test Plan:
1) Apply this patch
2) Prove t/db_dependent/Koha/SIP2/SIP2ModuleMigration.t

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This commit is contained in:
Kyle M Hall 2026-05-07 06:30:36 -04:00 committed by Lucas Gass
parent c7ee854d9f
commit 7dc223b30a
No known key found for this signature in database
GPG Key ID: 60B447398B0D36CA
2 changed files with 34 additions and 2 deletions

View File

@ -47,7 +47,11 @@ sub get_configuration {
if ($sip2_resource_last_modified) {
$cache->set_in_cache( 'sip2_config_read_timestamp', $sip2_resource_last_modified );
} else {
$cache->set_in_cache( 'sip2_config_read_timestamp', dt_from_string()->epoch );
# Set sip2_resource_last_modified so config won't be read from db on each request
my $now = dt_from_string()->epoch;
$cache->set_in_cache( 'sip2_resource_last_modified', $now );
$cache->set_in_cache( 'sip2_config_read_timestamp', $now );
}
my $cfg;

View File

@ -17,7 +17,7 @@
use Modern::Perl;
use Test::More tests => 4;
use Test::More tests => 5;
use Test::NoWarnings;
use Test::MockModule;
@ -181,6 +181,34 @@ subtest 'config_timestamp is updated when database configuration changes' => sub
$schema->storage->txn_rollback;
};
subtest 'get_configuration() reseeds sip2_resource_last_modified when missing from cache' => sub {
plan tests => 4;
my $schema = Koha::Database->new->schema;
$schema->storage->txn_begin;
my $cache = Koha::Caches->get_instance();
$cache->clear_from_cache('sip2_resource_last_modified');
$cache->clear_from_cache('sip2_config_read_timestamp');
is( $cache->get_from_cache('sip2_resource_last_modified'), undef, 'sip2_resource_last_modified cleared' );
C4::SIP::Sip::Configuration->get_configuration( undef, { listeners => {} } );
my $resource_last_modified = $cache->get_from_cache('sip2_resource_last_modified');
my $config_read_timestamp = $cache->get_from_cache('sip2_config_read_timestamp');
ok( $resource_last_modified, 'sip2_resource_last_modified is repopulated' );
ok( $config_read_timestamp, 'sip2_config_read_timestamp is set' );
is(
$config_read_timestamp, $resource_last_modified,
'sip2_config_read_timestamp matches sip2_resource_last_modified so subsequent requests skip a full reload'
);
$schema->storage->txn_rollback;
};
subtest 'Atomicupdate skips migrating data if provided config file doesn\'t exist or is unreadable' => sub {
plan tests => 1;