fix: harden retention cleanup safety

This commit is contained in:
2026-09-12 14:12:17 +08:00
parent da5c2b4503
commit b3ab1bfc52
6 changed files with 259 additions and 55 deletions
+13 -13
View File
@@ -117,25 +117,25 @@ class CleanupService:
report.deleted_job_ids.append(item.job_id)
for candidate in report.pending_products:
# Re-read logical state so a concurrent restore wins over cleanup.
try:
product = self.product_store.get_product(candidate.product_id)
except ValueError:
continue
if (
product.status != "pending_cleanup"
or product.purge_after is None
or _as_utc(product.purge_after) > now_utc
):
product = self.product_store.claim_product_purge(candidate.product_id, now_utc)
if product is None:
continue
product_dir = self.product_store.root.parent / product.product_id
if product_dir.exists():
shutil.rmtree(product_dir)
self.product_store.purge_product(product.product_id, now=now_utc)
try:
self._before_product_files_delete(product.product_id)
if product_dir.exists():
shutil.rmtree(product_dir)
except Exception:
self.product_store.release_product_purge(product.product_id)
raise
self.product_store.finalize_product_purge(product.product_id, now=now_utc)
report.deleted_product_ids.append(product.product_id)
return report
def _before_product_files_delete(self, product_id: str) -> None:
"""Interleaving seam between the durable claim and physical deletion."""
@staticmethod
def _directory_size(root: Path) -> int:
if not root.exists():