mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-06-21 16:41:13 +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:
@@ -7,7 +7,7 @@
|
||||
- AZ-TBD-c6-freshness-gate (insert hook collaborator)
|
||||
- AZ-TBD-c6-cache-budget-eviction (uses `tile_exists` + `delete_tile`)
|
||||
- TBD at decompose time: E-C2.5 (AZ-256), E-C3 (AZ-257), E-C11 (AZ-251 — both `TileDownloader` and `TileUploader`)
|
||||
**Version**: 1.0.0
|
||||
**Version**: 1.1.0
|
||||
**Status**: draft
|
||||
**Last Updated**: 2026-05-10
|
||||
|
||||
@@ -104,11 +104,12 @@ All under `c6_tile_cache.errors`:
|
||||
|
||||
```
|
||||
TileCacheError (Exception subclass)
|
||||
├── TileNotFoundError # tile_id not present on disk
|
||||
├── TileFsError # I/O error on read/write/rename
|
||||
├── TileMetadataError # row missing despite file present, or vice-versa (consistency violation)
|
||||
├── ContentHashMismatchError # supplied JPEG bytes don't match declared content_sha256
|
||||
└── FreshnessRejectionError # rejected by the C6 freshness gate (raised on insert in active_conflict)
|
||||
├── TileNotFoundError # tile_id not present on disk
|
||||
├── TileFsError # I/O error on read/write/rename
|
||||
├── TileMetadataError # row missing despite file present, or vice-versa (consistency violation)
|
||||
├── ContentHashMismatchError # supplied JPEG bytes don't match declared content_sha256
|
||||
├── FreshnessRejectionError # rejected by the C6 freshness gate (raised on insert in active_conflict)
|
||||
└── CacheBudgetExhaustedError # LRU sweep ran to completion but couldn't free `needed_bytes` (AZ-308)
|
||||
```
|
||||
|
||||
`IndexUnavailableError` lives under the same package but is exclusively raised by `DescriptorIndex` — it is not part of `TileStore`'s envelope.
|
||||
@@ -164,3 +165,4 @@ JPEG body lands at `<root>/tiles/{zoom_level}/{x}/{y}.jpg` where `(x, y)` is der
|
||||
| Version | Date | Change | Author |
|
||||
|---------|------|--------|--------|
|
||||
| 1.0.0 | 2026-05-10 | Initial contract — Protocol + DTOs + 5-error family + filesystem byte-identity invariant. | autodev (decompose Step 2 of AZ-250 / E-C6) |
|
||||
| 1.1.0 | 2026-05-12 | Additive: `CacheBudgetExhaustedError` joins the `TileCacheError` family for AZ-308 cache-budget enforcement. No existing-shape changes. | autodev (AZ-308) |
|
||||
|
||||
Reference in New Issue
Block a user