step 4: add async tiles and persistent cache
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import shutil
|
||||
from dataclasses import asdict, dataclass, field
|
||||
from pathlib import Path
|
||||
from time import time
|
||||
@@ -179,6 +180,24 @@ def write_disk_metadata(path: Path, metadata: DiskCacheMetadata) -> None:
|
||||
raise CacheError(f"could not write cache metadata: {path}") from exc
|
||||
|
||||
|
||||
def touch_disk_metadata(path: Path, *, accessed_at: float | None = None) -> None:
|
||||
"""Update only the last access timestamp for a metadata file."""
|
||||
|
||||
metadata = read_disk_metadata(path)
|
||||
write_disk_metadata(
|
||||
path,
|
||||
DiskCacheMetadata(
|
||||
url=metadata.url,
|
||||
etag=metadata.etag,
|
||||
last_modified=metadata.last_modified,
|
||||
expires=metadata.expires,
|
||||
downloaded_at=metadata.downloaded_at,
|
||||
last_accessed_at=time() if accessed_at is None else accessed_at,
|
||||
size_bytes=metadata.size_bytes,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def scan_disk_cache(cache_dir: str | Path | None) -> list[DiskCacheEntry]:
|
||||
"""Scan tile files under a disk cache root."""
|
||||
|
||||
@@ -237,3 +256,34 @@ def plan_disk_prune(
|
||||
prune.append(entry.tile_path)
|
||||
total -= entry.metadata.size_bytes
|
||||
return prune
|
||||
|
||||
|
||||
def prune_disk_cache(
|
||||
cache_dir: str | Path | None,
|
||||
max_bytes: int | None,
|
||||
*,
|
||||
protected_paths: set[Path] | None = None,
|
||||
) -> list[Path]:
|
||||
"""Delete LRU tile files until the cache fits the configured limit."""
|
||||
|
||||
planned = plan_disk_prune(cache_dir, max_bytes, protected_paths=protected_paths)
|
||||
for path in planned:
|
||||
metadata_path = tile_metadata_path(path)
|
||||
try:
|
||||
path.unlink(missing_ok=True)
|
||||
metadata_path.unlink(missing_ok=True)
|
||||
except OSError as exc:
|
||||
raise CacheError(f"could not prune cached tile: {path}") from exc
|
||||
return planned
|
||||
|
||||
|
||||
def clear_disk_cache_path(cache_dir: str | Path | None) -> None:
|
||||
"""Remove all persistent tile cache files under a cache root."""
|
||||
|
||||
root = disk_cache_root(cache_dir)
|
||||
if not root.exists():
|
||||
return
|
||||
try:
|
||||
shutil.rmtree(root)
|
||||
except OSError as exc:
|
||||
raise CacheError(f"could not clear disk cache: {root}") from exc
|
||||
|
||||
Reference in New Issue
Block a user