Problem/Motivation
After #3626381: Refresh reads a shared, tag-invalidated thread snapshot:, an anonymous refresh costs about 10 ms of PHP at 10,000 comments. It still boots Drupal for every poll and every burst. Once #1 is in place the anonymous payload is identical for all anonymous visitors, so Page Cache or a reverse proxy could serve it.
This changes behavior, so ADR 0009 ("Optional later layer") keeps it out of the core decision:
- A Page Cache or proxy hit never reaches the controller, so neither
enforceFlood() (src/Controller/CommentFragmentController.php:250, :399-420) nor the ECA comment_refresh_before Matrix event (:60-72) runs.
- Refresh returns a
JsonResponse, which Dynamic Page Cache does not handle.
- Page Cache ignores
max-age and honors only Expires. It replaces the ETag with its own timestamp and answers 304 only when If-Modified-Since also matches.
- Today the route is
no_cache (:246), and PrivateResponseSubscriber forces private, no-store on every ACT route (src/EventSubscriber/PrivateResponseSubscriber.php:31-35).
Proposed resolution
- Add an opt-in setting, off by default, for example
anonymous_refresh_http_cache.
- When it is on and the request is anonymous:
- return a
CacheableJsonResponse with the complete snapshot cacheability;
- set
Expires to the polling interval (polling_interval, default 30 s);
- exempt the response from
no_cache and PrivateResponseSubscriber;
- reject unknown query parameters with an uncached 404 so they do not create Page Cache variants.
- The client stores
Last-Modified and sends If-Modified-Since.
- Authenticated responses stay
private, no-store.
- Matrix: with
Expires equal to the polling interval, there is at most one miss per interval, and that miss fires the Matrix event. That acts as a throttle, not a switch-off. Document that large sites should get Matrix messages through an application server or Matrix API's cron/Drush pollers (ADR 0002, docs/matrix-refresh.md).
- Flood: a cache hit skips the flood check. That is acceptable because hits are cheap. Document it.
Remaining tasks
- Settings form, schema and post update.
- Functional tests with Page Cache enabled: hit,
Expires behavior, 304 with If-Modified-Since, authenticated responses unaffected.
- CDN guidance: Purge cache-tag headers, or a short
s-maxage.
User interface changes
One new checkbox on the ACT settings form.
API changes
The anonymous refresh response headers change when the setting is on.
Data model changes
New config key.
Related issues
None.
Comments
Comment #2
freelock