fix(blog): confirmer l'état mémoire après sauvegarde

This commit is contained in:
2026-09-13 00:14:38 +02:00
parent e6f0659cbf
commit 46d9942c56
2 changed files with 63 additions and 9 deletions
+26 -9
View File
@@ -97,7 +97,10 @@ class BlogRSSState:
redact_exception(exc),
)
def _save(self) -> None:
def _save(
self,
state: tuple[set[str], str | None, str | None] | None = None,
) -> bool:
"""Sauvegarde l'état dans le fichier JSON de manière atomique.
La sortie est déterministe : ``known_guids`` est trié
@@ -107,20 +110,30 @@ class BlogRSSState:
jamais laisser un fichier partiel en cas d'interruption. En cas
d'erreur d'écriture, une erreur est journalisée sans être
propagée et le fichier temporaire est supprimé.
:param state: État à sauvegarder ; l'état courant est utilisé par défaut.
:return: ``True`` si l'état a été sauvegardé ou si la persistance est désactivée.
:rtype: bool
"""
if not self._persistence_enabled:
return
return True
known_guids, etag, last_modified = state or (
self._known_guids,
self._etag,
self._last_modified,
)
payload = {
"version": _STATE_VERSION,
"known_guids": sorted(self._known_guids),
"etag": self._etag,
"last_modified": self._last_modified,
"known_guids": sorted(known_guids),
"etag": etag,
"last_modified": last_modified,
}
tmp_file = self._state_file.with_suffix(".tmp")
try:
with open(tmp_file, "w", encoding="utf-8") as handle:
json.dump(payload, handle, indent=2)
tmp_file.replace(self._state_file)
return True
except Exception as exc:
logger.error(
"Impossible d'écrire le fichier d'état blog RSS %s : %s.",
@@ -134,6 +147,7 @@ class BlogRSSState:
"Nettoyage du fichier temporaire échoué : %s",
redact_exception(cleanup_exc),
)
return False
def get_known_guids(self) -> frozenset[str]:
"""Renvoie une copie immuable des GUID d'articles déjà connus.
@@ -168,10 +182,13 @@ class BlogRSSState:
"""
if result.not_modified:
return
self._known_guids.update(article.id for article in result.articles)
self._etag = result.etag
self._last_modified = result.last_modified
self._save()
new_state = (
self._known_guids | {article.id for article in result.articles},
result.etag,
result.last_modified,
)
if self._save(new_state):
self._known_guids, self._etag, self._last_modified = new_state
def get_cache_headers(self) -> tuple[str | None, str | None]:
"""Renvoie les en-têtes de cache HTTP mémorisés.