Complete publish preview Phase 2A with retention, refresh and cache consistency
This commit is contained in:
@@ -5,7 +5,11 @@ from pathlib import Path
|
||||
from uuid import uuid4
|
||||
|
||||
from app.core.config import settings
|
||||
from app.repositories.scheme_artifacts import create_scheme_artifact, list_scheme_artifacts
|
||||
from app.repositories.scheme_artifacts import (
|
||||
create_scheme_artifact,
|
||||
delete_scheme_artifacts_by_artifact_ids,
|
||||
list_scheme_artifacts,
|
||||
)
|
||||
|
||||
|
||||
def _preview_storage_dir() -> Path:
|
||||
@@ -14,6 +18,64 @@ def _preview_storage_dir() -> Path:
|
||||
return path
|
||||
|
||||
|
||||
def _cleanup_preview_file(storage_path: str) -> None:
|
||||
path = Path(storage_path)
|
||||
try:
|
||||
if path.exists() and path.is_file():
|
||||
path.unlink()
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
parent = path.parent
|
||||
preview_root = Path(settings.storage_preview_dir)
|
||||
|
||||
try:
|
||||
if parent != preview_root and parent.exists():
|
||||
parent.rmdir()
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
async def cleanup_publish_preview_artifacts(
|
||||
*,
|
||||
scheme_version_id: str,
|
||||
baseline_scheme_version_id: str | None,
|
||||
) -> dict:
|
||||
retention = max(1, settings.publish_preview_retention_per_variant)
|
||||
variant = baseline_scheme_version_id or "default"
|
||||
|
||||
rows = await list_scheme_artifacts(
|
||||
scheme_version_id=scheme_version_id,
|
||||
artifact_type="publish_preview",
|
||||
artifact_variant=variant,
|
||||
)
|
||||
if len(rows) <= retention:
|
||||
return {
|
||||
"retention": retention,
|
||||
"deleted_count": 0,
|
||||
"deleted_artifact_ids": [],
|
||||
}
|
||||
|
||||
rows_sorted = sorted(
|
||||
rows,
|
||||
key=lambda row: (row.created_at, row.id),
|
||||
reverse=True,
|
||||
)
|
||||
to_delete = rows_sorted[retention:]
|
||||
|
||||
deleted_artifact_ids = [row.artifact_id for row in to_delete]
|
||||
for row in to_delete:
|
||||
_cleanup_preview_file(row.storage_path)
|
||||
|
||||
deleted_count = await delete_scheme_artifacts_by_artifact_ids(deleted_artifact_ids)
|
||||
|
||||
return {
|
||||
"retention": retention,
|
||||
"deleted_count": deleted_count,
|
||||
"deleted_artifact_ids": deleted_artifact_ids,
|
||||
}
|
||||
|
||||
|
||||
async def save_publish_preview_artifact(
|
||||
*,
|
||||
scheme_id: str,
|
||||
@@ -37,7 +99,16 @@ async def save_publish_preview_artifact(
|
||||
"summary": payload.get("summary"),
|
||||
},
|
||||
)
|
||||
return artifact
|
||||
|
||||
cleanup = await cleanup_publish_preview_artifacts(
|
||||
scheme_version_id=scheme_version_id,
|
||||
baseline_scheme_version_id=baseline_scheme_version_id,
|
||||
)
|
||||
|
||||
return {
|
||||
"artifact": artifact,
|
||||
"cleanup": cleanup,
|
||||
}
|
||||
|
||||
|
||||
async def get_latest_publish_preview_artifact(
|
||||
@@ -45,15 +116,13 @@ async def get_latest_publish_preview_artifact(
|
||||
scheme_version_id: str,
|
||||
baseline_scheme_version_id: str | None,
|
||||
):
|
||||
rows = await list_scheme_artifacts(scheme_version_id=scheme_version_id)
|
||||
variant = baseline_scheme_version_id or "default"
|
||||
|
||||
matching = [
|
||||
row for row in rows
|
||||
if row.artifact_type == "publish_preview" and row.artifact_variant == variant
|
||||
]
|
||||
if not matching:
|
||||
rows = await list_scheme_artifacts(
|
||||
scheme_version_id=scheme_version_id,
|
||||
artifact_type="publish_preview",
|
||||
artifact_variant=baseline_scheme_version_id or "default",
|
||||
)
|
||||
if not rows:
|
||||
return None
|
||||
|
||||
matching.sort(key=lambda row: (row.created_at, row.id), reverse=True)
|
||||
return matching[0]
|
||||
rows.sort(key=lambda row: (row.created_at, row.id), reverse=True)
|
||||
return rows[0]
|
||||
|
||||
Reference in New Issue
Block a user