Mark stale cache content as "invalid" on non-cacheable responses

Maxim Dounin mdounin at
Tue Nov 17 18:25:00 UTC 2015


On Tue, Nov 17, 2015 at 05:25:30PM +0000, Mindaugas Rasiukevicius wrote:

> Hi,
> Context: consider nginx used as a cache with proxy_cache_use_stale set
> to 'http_500' and the 'updating' parameter set i.e. it caches errors and
> serves the stale content while updating.  Suppose the upstream temporarily
> responds with HTTP 504 and Cache-Control being max-age=3.  The error gets
> cached, but after 3 seconds it expires.  At this point, let's say the
> upstream server starts serving HTTP 200 responses, but with Cache-Control
> set to 'no-cache'.
> The cache manager will not LRU the expired content immediately; it will
> stay in the EXPIRED state while subsequent requests will result in 200s.
> Problem: if there are multiple processes racing, the ones in the UPDATING
> state will serve stale 504s.  That results in sporadic errors, e.g.:
> ...
> At the very least, I think the stale cache content should be marked as
> "invalid" after the no-cache response (with the possibility to become
> valid again if it becomes cacheable).  Whether the object should be kept
> at all is something to debate.
> Please find the preliminary patch attached.

I don't see how a response with "no-cache" is no different from an 
earlier error.  Consider slightly different scenario:

- a response is cached and then expires,

- an attempt to fetch new response results in a non-cacheable 

In such a case, removing previously cached response is the worst 
thing we can possibly do.  We are expected to return previously 
cached stale responses in all cases we are configured to do so.

The change you've proposed completely rules out possibility of 
correct handling of this scenario.

Trivial solutions to the problem you've described would be to 
disable use of stale responses completely (which is the default), 
or use "proxy_cache_use_stale http_504", or to avoid caching of 
504 errors (and the later is something RFC suggests to do by 
default with any errors).

And while I agree that it would be good to behave better in the 
scenario you've described, I tend to disagree with the change 
suggested, and I'm not even sure a good solution exists.

Maxim Dounin

More information about the nginx-devel mailing list