[PATCH] Apply cache locking behaviour to stale cache entries.
Maxim Dounin
mdounin at mdounin.ru
Mon Dec 10 19:07:18 UTC 2018
Hello!
On Mon, Dec 03, 2018 at 12:11:15PM +0000, Elliot Thomas wrote:
> This patch applies cache locking behaviour to stale cache entries, so
> in the case where the *_cache_lock directives are used, the same
> locking behaviour is used for stale content as it is for new entries.
>
> Previously, this was only done for new cache entries.
> (see: http://mailman.nginx.org/pipermail/nginx/2016-January/049734.html)
>
> This is useful when serving stale content is not permissable but sending
> many requests upstream is undesriable.
>
>
> This patch exposes the ngx_http_file_cache_lock function; this function
> is then called in ngx_http_upstream if a cache entry has expired.
>
> I have attached two versions of this patch, a "minimal" one that avoids
> changes where not strictly necessary, and a "cleaner" version which is
> more invasive but (in my opinion) cleaner.
>
> Both patches cause no (additional) failures in the nginx test suite.
> I tested with as many modules as I could reasonably enable.
Thank you for the patches. The "cleaner" version looks better,
though it looks like it would be a good idea to clean it even
more. See comments below.
[...]
> -----------------------------
> http://www.bbc.co.uk
> This e-mail (and any attachments) is confidential and
> may contain personal views which are not the views of the BBC unless specifically stated.
> If you have received it in
> error, please delete it from your system.
> Do not use, copy or disclose the
> information in any way nor act in reliance on it and notify the sender
> immediately.
> Please note that the BBC monitors e-mails
> sent or received.
> Further communication will signify your consent to
> this.
> -----------------------------
Note that posting patches to a public mailing list with such a
disclaimer might not be a good idea. If you cannot remove it,
please make sure to add an explicit comment that you understand
that you are posting to a public mailing list, and you've read the
http://nginx.org/en/docs/contributing_changes.html article. In
particular, that you agree with the "License" part.
> # HG changeset patch
> # User Elliot Thomas <elliot.thomas at bbc.co.uk>
> # Date 1543836716 0
> # Mon Dec 03 11:31:56 2018 +0000
> # Node ID 28084fdcef2873df221b13d1a70ab04242e4edc5
> # Parent 2117637f64e981e0e14c3a4b0509252fefd8a78a
> Apply cache locking behaviour to stale cache entries.
>
> Previously, this was only done for new cache entries.
>
> diff -r 2117637f64e9 -r 28084fdcef28 src/http/ngx_http_cache.h
> --- a/src/http/ngx_http_cache.h Tue Nov 27 17:40:21 2018 +0300
> +++ b/src/http/ngx_http_cache.h Mon Dec 03 11:31:56 2018 +0000
> @@ -188,6 +188,7 @@
> ngx_int_t ngx_http_file_cache_create(ngx_http_request_t *r);
> void ngx_http_file_cache_create_key(ngx_http_request_t *r);
> ngx_int_t ngx_http_file_cache_open(ngx_http_request_t *r);
> +ngx_int_t ngx_http_file_cache_lock(ngx_http_request_t *r, ngx_int_t rc);
> ngx_int_t ngx_http_file_cache_set_header(ngx_http_request_t *r, u_char *buf);
> void ngx_http_file_cache_update(ngx_http_request_t *r, ngx_temp_file_t *tf);
> void ngx_http_file_cache_update_header(ngx_http_request_t *r);
> diff -r 2117637f64e9 -r 28084fdcef28 src/http/ngx_http_file_cache.c
> --- a/src/http/ngx_http_file_cache.c Tue Nov 27 17:40:21 2018 +0300
> +++ b/src/http/ngx_http_file_cache.c Mon Dec 03 11:31:56 2018 +0000
> @@ -11,8 +11,6 @@
> #include <ngx_md5.h>
>
>
> -static ngx_int_t ngx_http_file_cache_lock(ngx_http_request_t *r,
> - ngx_http_cache_t *c);
> static void ngx_http_file_cache_lock_wait_handler(ngx_event_t *ev);
> static void ngx_http_file_cache_lock_wait(ngx_http_request_t *r,
> ngx_http_cache_t *c);
> @@ -391,22 +389,21 @@
>
> done:
>
> - if (rv == NGX_DECLINED) {
> - return ngx_http_file_cache_lock(r, c);
> - }
> -
> return rv;
> }
This changes makes the "done" label useless. It can be removed,
and corresponding gotos in the function replaced with explicit
returns (as it was before the introduction of cache locks in
revision 70ba81827472, http://hg.nginx.org/nginx/rev/70ba81827472).
> -static ngx_int_t
> -ngx_http_file_cache_lock(ngx_http_request_t *r, ngx_http_cache_t *c)
> +ngx_int_t
> +ngx_http_file_cache_lock(ngx_http_request_t *r, ngx_int_t rc)
> {
> ngx_msec_t now, timer;
> + ngx_http_cache_t *c;
> ngx_http_file_cache_t *cache;
>
> + c = r->cache;
> +
> if (!c->lock) {
Note that c->lock is not really needed now, as
u->conf->cache_lock can be used directly by the caller. It might
be a good idea to get rid of it (not sure though).
> - return NGX_DECLINED;
> + return rc;
> }
>
> now = ngx_current_msec;
> @@ -431,7 +428,7 @@
> c->updating, c->wait_time);
>
> if (c->updating) {
> - return NGX_DECLINED;
> + return rc;
> }
>
> if (c->lock_timeout == 0) {
I don't like the idea of pass-through of the return code. Rather,
return code of the ngx_http_file_cache_lock() should be checked by
the caller, and appropriate actions takens depending on it.
> diff -r 2117637f64e9 -r 28084fdcef28 src/http/ngx_http_upstream.c
> --- a/src/http/ngx_http_upstream.c Tue Nov 27 17:40:21 2018 +0300
> +++ b/src/http/ngx_http_upstream.c Mon Dec 03 11:31:56 2018 +0000
> @@ -923,6 +923,11 @@
> u->cache_status = NGX_HTTP_CACHE_HIT;
> }
>
> + if (rc == NGX_DECLINED || rc == NGX_HTTP_CACHE_STALE)
> + {
Style: "{" should be on the same line as "if" unless there isn't
enough room.
> + rc = ngx_http_file_cache_lock(r, rc);
> + }
> +
> switch (rc) {
>
> case NGX_OK:
Overall, this part of the ngx_http_upstream_cache() function seems
to be overcomplicated, and it is really not clear how this is
expected to interact with various possible rc values and various
possible ngx_http_file_cache_lock() outcomes.
It may be a good idea to move ngx_http_file_cache_lock() further
down instead of trying to slip it in between these switches().
This will require separate handling of ngx_http_file_cache_lock()
return codes, but this actually looks like a good change, see
comments above.
Also, moving ngx_http_file_cache_lock() further down will allow us
to avoid cache locks when proxy_cache_max_range_offset prevents
caching anyway.
[...]
--
Maxim Dounin
http://mdounin.ru/
More information about the nginx-devel
mailing list