pyronear / pyronear/pyro-api

Purge stale-window entries from the presigned-URL cache

Open
#672 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
29
Forks
14
Avg merge
9d 1h
Merged PRs (30d)
5

Description

Context

S3Bucket._url_cache (added in #661 ) exists so that re-presigning the same object returns the same URL string for a while. boto3 stamps the signing clock into every signature, so without it each poll produced a different URL and the browser re-downloaded frames it already had. The cache key is (bucket_key, url_expiration, window_slot) — see src/app/services/storage.py:155.

Problem

The window slot is part of the key, so when the window rolls over (1h at the default S3_URL_EXPIRATION=24h), every entry from the previous slot becomes permanently unreachable — a lookup can never match an old slot again. Nothing removes them. They only leave through the size-based LRU eviction at src/app/services/storage.py:161-165.

Consequence: an active organization climbs to the 8192-entry ceiling and stays there permanently, with a substantial share of it dead weight from expired windows. Effective capacity is roughly half the nominal figure.

Why this is safe to fix

Worth distinguishing from the existing comment at src/app/services/storage.py:162-164, which argues against clearing the cache. That argument is correct for a full clear() — it would re-presign every URL currently in flight, changing them exactly when stability matters most.

It does not apply to purging stale slots. Those entries are already unreachable by construction, so removing them changes nothing observable: no URL being handed out is affected, and no client sees a different string.

Proposal

A two-generation cache: keep a current dict and a previous dict, swap on slot rollover and drop the old one. O(1), no scan, no per-entry timestamp bookkeeping. The window_slot component of the key becomes redundant and can go.

Impact

Roughly doubles usable capacity for the same memory. No behavioral change for clients. Non-urgent — nothing breaks today, the cache is bounded and a miss only costs a local HMAC signature (generate_presigned_url makes no S3 call).

Related: #671 , which covers the size of the bound itself.

Happy to discuss it :)

Co authored with Claude

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at S3Bucket._url_cache in src/app/services/storage.py around lines 155 and 161-165, then trace how the window slot forms cache keys. Verify the rollover behavior and preserve stable URLs within the active window. Done means stale-slot entries are dropped without scanning, the redundant key component is removed, and current URLs remain unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Refactor
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.