From 7dc223b30ac399da5c04456cde1f7afd65c600e4 Mon Sep 17 00:00:00 2001 From: Kyle M Hall Date: Thu, 7 May 2026 06:30:36 -0400 Subject: [PATCH] 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 Signed-off-by: Martin Renvoize Signed-off-by: Lucas Gass --- C4/SIP/Sip/Configuration.pm | 6 +++- .../Koha/SIP2/SIP2ModuleMigration.t | 30 ++++++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/C4/SIP/Sip/Configuration.pm b/C4/SIP/Sip/Configuration.pm index b8e5075e03..a6757ea6cc 100644 --- a/C4/SIP/Sip/Configuration.pm +++ b/C4/SIP/Sip/Configuration.pm @@ -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; diff --git a/t/db_dependent/Koha/SIP2/SIP2ModuleMigration.t b/t/db_dependent/Koha/SIP2/SIP2ModuleMigration.t index 3e5982fa31..275f09c372 100755 --- a/t/db_dependent/Koha/SIP2/SIP2ModuleMigration.t +++ b/t/db_dependent/Koha/SIP2/SIP2ModuleMigration.t @@ -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;