edge: purge_header.go's cost paragraph no longer claims PurgeHost scans the cache
Stale after the byHost index landed: PurgeHost used to scan every entry (the "32x at a full cache" figure), but now costs one map lookup for the host's own entry set via byHost (see cache.go). Restated the caps' justification on what still holds — both the capped-targets path and the degrade path are bounded operations whose cost doesn't scale with what the header declares — rather than a cost differential that no longer exists.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 file changed,
+11
−11
internal/edge/purge_header.go+11 −11
diff --git a/internal/edge/purge_header.go b/internal/edge/purge_header.go| index 0112f6697..c9afa81a6 100644 |
| --- a/internal/edge/purge_header.go |
| +++ b/internal/edge/purge_header.go |
| @@ -140,17 +140,17 @@ const PurgeHostHeader = "Carlos-Purge-Host" |
| // path: without them a single response could name a million targets and drive |
| // a million locked cache operations before the client gets its bytes. |
| // |
| -// Degrading is NOT the cheap path — it is the SIMPLE one, and it is more |
| -// expensive than honouring the declaration. Honouring 64 targets is 128 map |
| -// lookups (each target hits the GET and HEAD index groups); PurgeHost takes |
| -// the same global lock and scans EVERY entry in the cache, which at |
| -// DefaultCacheMaxEntries (4096) is an order of magnitude more work — roughly |
| -// 32x at a full cache, and worse the fuller the cache is. So an app gains |
| -// nothing by exceeding the bound except a bigger blast radius on its own |
| -// cache; the bound is a cliff in behaviour (targeted -> whole host), not an |
| -// invitation. What the caps genuinely buy is that the per-response cost has a |
| -// CEILING that does not scale with the header's length — one host scan |
| -// instead of unbounded lookups. |
| +// Degrading is NOT the cheap path — it is the SIMPLE one. Honouring 64 |
| +// targets is a bounded operation: up to 128 map lookups (each target hits |
| +// the GET and HEAD index groups) plus parsing each target string. PurgeHost |
| +// is bounded too — it rides the byHost index (see cache.go), a single map |
| +// lookup for the whole host's entry set, not a scan of the cache. Neither |
| +// path's cost is the point of the caps; what they genuinely buy is that the |
| +// per-response cost has a CEILING that does not scale with how much the |
| +// header declares, whichever path is taken. So an app gains nothing by |
| +// exceeding the bound except a bigger blast radius on its own cache — the |
| +// coarser whole-host purge, not a more precise one; the bound is a cliff in |
| +// behaviour (targeted -> whole host), not an invitation. |
| // |
| // 64 targets is well above what a real write invalidates (a page, its |
| // paginated index, a couple of locale variants). 8 KiB bounds the joined |