Fix genre cache merge race when API thread runs alongside main thread

_save_genre_cache now reads the on-disk state and merges before writing,
so a concurrent writer can't shrink the cache. Likewise the API thread's
progress/done handlers now `update()` the in-memory cache instead of
replacing it wholesale.

Reachable only in the rare path where both the appinfo loader and the
API fetch thread run in the same session.
This commit is contained in:
2026-05-08 15:31:24 -04:00
parent bb50d96999
commit b5dc6fb547
+6 -3
View File
@@ -127,11 +127,14 @@ def _load_genre_cache():
def _save_genre_cache(cache):
"""Merge `cache` into the on-disk cache so concurrent writers don't shrink it."""
path = _genre_cache_path()
os.makedirs(os.path.dirname(path), exist_ok=True)
merged = _load_genre_cache()
merged.update(cache)
tmp = path + ".tmp"
with open(tmp, "w") as f:
json.dump(cache, f)
json.dump(merged, f)
os.replace(tmp, path)
@@ -774,14 +777,14 @@ class SteamDice(QMainWindow):
self.genres_thread.start()
def _on_genres_progress(self, done, total, cache_snapshot):
self.genre_cache = cache_snapshot
self.genre_cache.update(cache_snapshot)
self.genre_progress_label.setText(f"{done} / {total}")
# Refresh the dropdown periodically as new genres are discovered.
if done % FetchGenresThread.SAVE_EVERY == 0:
self._rebuild_genre_combo()
def _on_genres_done(self, cache):
self.genre_cache = cache
self.genre_cache.update(cache)
self.genre_progress_label.setVisible(False)
self._rebuild_genre_combo()
self._apply_filter()