From 615e1183a81752e1b79601e973742e3214f4f51e Mon Sep 17 00:00:00 2001 From: Ian Renton Date: Sun, 21 Jun 2026 22:07:29 +0100 Subject: [PATCH] Fix cache multithreading issues on startup? --- core/cache_utils.py | 20 +++++++++++++++++--- templates/add_spot.html | 2 +- templates/alerts.html | 2 +- templates/bands.html | 4 ++-- templates/base.html | 10 +++++----- templates/conditions.html | 2 +- templates/map.html | 4 ++-- templates/spots.html | 4 ++-- templates/status.html | 2 +- 9 files changed, 32 insertions(+), 18 deletions(-) diff --git a/core/cache_utils.py b/core/cache_utils.py index 3093c2f..2ec492c 100644 --- a/core/cache_utils.py +++ b/core/cache_utils.py @@ -1,3 +1,4 @@ +import threading from datetime import timedelta from requests_cache import CachedSession @@ -5,6 +6,19 @@ from requests_cache import CachedSession # Cache for "semi-static" data such as the locations of parks, CSVs of reference lists, etc. # This has an expiry time of 30 days, so will re-request from the source after that amount # of time has passed. This is used throughout Spothole to cache data that does not change -# rapidly. -SEMI_STATIC_URL_DATA_CACHE = CachedSession("cache/semi_static_url_data_cache", - expire_after=timedelta(days=30)) +# rapidly. The ThreadSafeSession construct here protects it against some multithreading +# contention weirdness we sometimes used to see on startup where the cache was hammered +# pretty hard. +_session = CachedSession("cache/semi_static_url_data_cache", expire_after=timedelta(days=30)) +_lock = threading.Lock() + + +class _ThreadSafeSession: + """Wraps CachedSession with a lock to prevent concurrent SQLite access across threads.""" + + def get(self, *args, **kwargs): + with _lock: + return _session.get(*args, **kwargs) + + +SEMI_STATIC_URL_DATA_CACHE = _ThreadSafeSession() diff --git a/templates/add_spot.html b/templates/add_spot.html index 36992f7..380afec 100644 --- a/templates/add_spot.html +++ b/templates/add_spot.html @@ -76,7 +76,7 @@ - + diff --git a/templates/alerts.html b/templates/alerts.html index 9a240b9..fef1ee6 100644 --- a/templates/alerts.html +++ b/templates/alerts.html @@ -75,7 +75,7 @@ - + diff --git a/templates/bands.html b/templates/bands.html index 21c6af2..50fce7a 100644 --- a/templates/bands.html +++ b/templates/bands.html @@ -77,8 +77,8 @@ - - + + diff --git a/templates/base.html b/templates/base.html index b6cbc90..36341da 100644 --- a/templates/base.html +++ b/templates/base.html @@ -1,6 +1,6 @@ {% extends "skeleton.html" %} {% block head_extra %} - + @@ -10,10 +10,10 @@ - - - - + + + + {% end %} {% block body %}
diff --git a/templates/conditions.html b/templates/conditions.html index 8a07ffb..dbcdf49 100644 --- a/templates/conditions.html +++ b/templates/conditions.html @@ -284,7 +284,7 @@
- + diff --git a/templates/map.html b/templates/map.html index c135728..ca953b5 100644 --- a/templates/map.html +++ b/templates/map.html @@ -95,8 +95,8 @@ - - + + diff --git a/templates/spots.html b/templates/spots.html index c921a6e..df3a546 100644 --- a/templates/spots.html +++ b/templates/spots.html @@ -116,8 +116,8 @@ - - + + diff --git a/templates/status.html b/templates/status.html index 191d443..9472818 100644 --- a/templates/status.html +++ b/templates/status.html @@ -59,7 +59,7 @@ - +