From c30f39c2e9e7fb4095a0bb577b52712c97840b0d Mon Sep 17 00:00:00 2001 From: Joe Doss Date: Fri, 17 Apr 2026 01:01:48 -0500 Subject: [PATCH] Make serve a read-only consumer of the on-disk cache MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Serve and setup each hold their own in-memory dict of the on-disk cache. Without coordination, serve's cache.save() on a lookup miss overwrites setup's freshly pruned state with serve's older dict — resurrecting the stale entries the prune step in PR #32 just removed. Observed on the test server: cache grew back to 15k+ entries within minutes of setup pruning it down to ~500. Drop the cache.save() call on the serve cache-miss path. Values still populate the in-memory dict (cache.set), so subsequent lookups for the same secret in the same process still hit, and tests asserting on in-memory presence still pass. The disk file is owned exclusively by setup, which prunes on every run. Tradeoff: a secret lazily cached during serve runtime (e.g. an HSM-stored secret outside config.workloads) is lost on serve restart and will miss the cache on its next lookup. Acceptable — the cache's purpose is surviving provider outages for workload secrets, and those are always populated by setup. --- psi/serve.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/psi/serve.py b/psi/serve.py index a315a7b..b84e45a 100644 --- a/psi/serve.py +++ b/psi/serve.py @@ -244,11 +244,7 @@ def _handle_lookup(self, secret_id: str) -> None: return if cache is not None: - try: - cache.set(secret_id, value) - cache.save() - except Exception as e: - logger.warning("Failed to persist cache entry {}: {}", secret_id, e) + cache.set(secret_id, value) self._respond(200, value) audit.bind(outcome="success", source="provider").info("lookup")