mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-17 08:53:28 -05:00
fix: write the database cache atomically
This commit is contained in:
1 parent
9ea581d1d6
commit
78162e7022
2 files changed
+28
-4
No files matched your search
@@ -29,6 +29,7 @@ from common import (
|
||||
require_yaml,
|
||||
source_yaml_paths,
|
||||
write_if_changed,
|
||||
write_text_atomic,
|
||||
yaml_load,
|
||||
)
|
||||
|
||||
@@ -258,11 +259,14 @@ def load_cache(cache_path: str) -> dict:
|
||||
return {}
|
||||
|
||||
|
||||
def save_cache(cache_path: str, cache: dict):
|
||||
"""Save cache to disk."""
|
||||
def save_cache(cache_path: str, cache: dict) -> None:
|
||||
"""Save the cache whole or not at all.
|
||||
|
||||
Written in place, a crash while serializing left a truncated file that
|
||||
the next run read as empty and rehashed the collection from scratch.
|
||||
"""
|
||||
os.makedirs(os.path.dirname(cache_path), exist_ok=True)
|
||||
with open(cache_path, "w") as f:
|
||||
json.dump(cache, f)
|
||||
write_text_atomic(cache_path, json.dumps(cache))
|
||||
|
||||
|
||||
def _load_gitignored_large_files() -> set[str]:
|
||||
|
||||
@@ -2161,6 +2161,26 @@ class ContributorsSurviveAFailedRequest(unittest.TestCase):
|
||||
)
|
||||
|
||||
|
||||
class TheDatabaseCacheIsWrittenWhole(unittest.TestCase):
|
||||
"""A crash while serializing left a truncated db_cache.json behind, and
|
||||
the next run rehashed the whole collection from scratch."""
|
||||
|
||||
def test_a_failed_save_keeps_the_previous_cache(self):
|
||||
import json
|
||||
from unittest import mock
|
||||
|
||||
from scripts import generate_db
|
||||
|
||||
with tempfile.TemporaryDirectory(dir=TMP_ROOT) as directory:
|
||||
path = os.path.join(directory, "cache", "db_cache.json")
|
||||
generate_db.save_cache(path, {"a": 1})
|
||||
with mock.patch.object(json, "dumps", side_effect=TypeError("miscomputed")):
|
||||
with self.assertRaises(TypeError):
|
||||
generate_db.save_cache(path, {"a": 2})
|
||||
self.assertEqual(generate_db.load_cache(path), {"a": 1})
|
||||
self.assertEqual(os.listdir(os.path.dirname(path)), ["db_cache.json"])
|
||||
|
||||
|
||||
class KidVidTapesStayWithTheContent(unittest.TestCase):
|
||||
"""Stella opens its KidVid tapes by bare name (stella2014, from the
|
||||
working directory) or from its base directory (stella2023, the content
|
||||
|
||||
Reference in new issue
Block a user