mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-06-22 18:51:15 +00:00
[AZ-308] c6 CacheBudgetEnforcer: 10 GB hard cap + LRU sweep
CacheBudgetEnforcer.reserve_headroom(needed_bytes) returns immediately when total_disk_bytes() + needed_bytes <= budget, otherwise iterates lru_candidates in eviction_batch_size batches, deletes via delete_tile, emits one INFO log per evicted tile (c6.evicted) and one FDR record per eviction batch (c6.eviction_batch, evicted_tile_ids capped to 5). Raises CacheBudgetExhaustedError AFTER a full sweep if the budget cannot be met. BudgetEnforcedTileStore decorates a TileStore so the policy stays separable from PostgresFilesystemStore. Composition root in storage_factory.build_tile_store wires the wrapper unconditionally. PostgresFilesystemStore now accepts lru_clock: Clock | None = None; when set, read_tile_pixels calls record_lru_access(tile_id, now) so eviction picks the right LRU candidates. Production wiring injects WallClock(); AZ-305 unit tests still construct without the clock and keep their pass-through semantics. Contract tile_store.md bumped to v1.1.0 to add CacheBudgetExhaustedError to the TileCacheError family; shared FDR schema bumped to v1.3.0 for the new c6.eviction_batch kind. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -145,6 +145,19 @@ KNOWN_PAYLOAD_KEYS: Final[dict[str, frozenset[str]]] = {
|
||||
"c6.freshness.downgraded": frozenset(
|
||||
{"tile_id", "age_seconds", "classification", "rule_action", "rule_max_age_seconds"}
|
||||
),
|
||||
# AZ-308 / E-C6: emitted by the CacheBudgetEnforcer at the end of every
|
||||
# LRU sweep that evicted at least one tile (RESTRICT-SAT-2). One record
|
||||
# per ``reserve_headroom`` call that hit the eviction path, never per
|
||||
# evicted tile (per-tile detail goes to logs). ``trigger_tile_id`` is
|
||||
# the canonical UUIDv5 of the tile whose write triggered the sweep;
|
||||
# ``freed_bytes`` is the integer total reclaimed; ``evicted_count`` is
|
||||
# the full count regardless of how many ids fit in
|
||||
# ``evicted_tile_ids`` (capped to 5 to keep the record bounded —
|
||||
# AC-11). The full eviction list is replayable from the per-tile
|
||||
# ``c6.evicted`` INFO log records.
|
||||
"c6.eviction_batch": frozenset(
|
||||
{"trigger_tile_id", "freed_bytes", "evicted_count", "evicted_tile_ids"}
|
||||
),
|
||||
}
|
||||
|
||||
KNOWN_KINDS: Final[frozenset[str]] = frozenset(KNOWN_PAYLOAD_KEYS.keys())
|
||||
|
||||
Reference in New Issue
Block a user