| From: | Christoph Berg <myon(at)debian(dot)org> |
|---|---|
| To: | Dave Page <dpage(at)pgadmin(dot)org> |
| Cc: | Magnus Hagander <magnus(at)hagander(dot)net>, "Jonathan S(dot) Katz" <jkatz(at)postgresql(dot)org>, Daniel Gustafsson <daniel(at)yesql(dot)se>, pgsql-www(at)lists(dot)postgresql(dot)org, Andrey Borodin <x4mmm(at)yandex-team(dot)ru>, Melanie Plageman <melanieplageman(at)gmail(dot)com>, PostgreSQL Contributors <contributors(at)lists(dot)postgresql(dot)org> |
| Subject: | Re: Introduce contributor badges |
| Date: | 2026-10-16 14:18:41 |
| Message-ID: | atIyQWx_PwMv-PsI@msg.df7cb.de |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-www |
Re: To Dave Page
> > ## Varnish cache invalidation
>
> > 4. **The image URL never changes when the image does.**
> > `/community/badge/<slug>/image/` has no file extension and no version in
> > it. The docs say Varnish applies a longer policy to images "because they
> > are considered never to change". Varnish itself is purged, but if the
> > Varnish configuration (VCL) also sends long browser cache headers for
> > images, browsers will keep showing the old image.
>
> I think purging Varnish is enough here. Badge image changes aren't
> critical, if a user sees the image somewhat longer, that doesn't cause
> trouble.
I did more research on this point, and that's the result (poking
around and by Deepseek):
Key finding: the cache policy is s-maxage, i.e. shared-cache only
docs/frontend.rst:39-46:
│ There is a longer default policy set for images, because they are considered never to change. Any view …
│ can override this default, by specifying the Cache-control: s-maxage=xxx http header … using the @cache()
│ decorator.
And that's exactly what the decorator emits (pgweb/util/decorators.py):
resp['Cache-Control'] = 's-maxage=%s' % (...)
s-maxage is honoured only by shared caches (Varnish); browsers ignore it and fall back to no explicit
freshness. badge_image itself sets no Cache-Control at all (only ETag), so:
- the "longer policy for images" is a Varnish TTL (how long Varnish holds it) — and that's the copy our
purge_urls already invalidates on save;
- browsers are never asked to cache the image long, so a changed image can't go stale in a browser under the
documented design (they'll revalidate via ETag, or not cache).
So the risk in comment #4 only materialises if the out-of-repo VCL re-adds a browser max-age for images —
which would contradict the app's own header. That's a hypothetical, not something the repo does.
Recommendation
No URL versioning. It requires a schema change, and the repository's own contract (s-maxage) is
that only Varnish caches. Adding ?v=<hash> "to avoid the question" pays a real cost to guard against a
configuration the app already argues against.
On the related "minor" comment:
> - `badge_image` fetches the image and computes its MD5 before it checks
> `If-None-Match`; storing the hash would avoid both.
badge_image is only reached on a Varnish miss, and on a miss we're
almost always about to serve the image anyway. Storing the hash only
helps the narrow (?) "Django itself receives a conditional request"
case.
So, I would say everything already works like it should.
(If we wanted, We could add explicit Cache-Control headers on
badge_image.)
Christoph
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Dave Page | 2026-10-16 15:18:53 | Re: Introduce contributor badges |
| Previous Message | Daniel Gustafsson | 2026-10-16 12:53:51 | Re: Introduce contributor badges |