]> git.kaiwu.me - nginx.git/commitdiff
Upstream: proxy_cache_background_update and friends.
authorRoman Arutyunyan <arut@nginx.com>
Fri, 10 Feb 2017 12:13:41 +0000 (15:13 +0300)
committerRoman Arutyunyan <arut@nginx.com>
Fri, 10 Feb 2017 12:13:41 +0000 (15:13 +0300)
The directives enable cache updates in subrequests.

src/http/modules/ngx_http_fastcgi_module.c
src/http/modules/ngx_http_proxy_module.c
src/http/modules/ngx_http_scgi_module.c
src/http/modules/ngx_http_uwsgi_module.c
src/http/ngx_http_cache.h
src/http/ngx_http_core_module.c
src/http/ngx_http_file_cache.c
src/http/ngx_http_request.h
src/http/ngx_http_upstream.c
src/http/ngx_http_upstream.h

index c7c417ba6ae5e70837e00d22e1508d65f491d527..afdea2d022c86a5c86d08c94a160289760b6279a 100644 (file)
@@ -469,6 +469,13 @@ static ngx_command_t  ngx_http_fastcgi_commands[] = {
       offsetof(ngx_http_fastcgi_loc_conf_t, upstream.cache_revalidate),
       NULL },
 
+    { ngx_string("fastcgi_cache_background_update"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+      ngx_conf_set_flag_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_fastcgi_loc_conf_t, upstream.cache_background_update),
+      NULL },
+
 #endif
 
     { ngx_string("fastcgi_temp_path"),
@@ -2769,6 +2776,7 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
     conf->upstream.cache_lock_timeout = NGX_CONF_UNSET_MSEC;
     conf->upstream.cache_lock_age = NGX_CONF_UNSET_MSEC;
     conf->upstream.cache_revalidate = NGX_CONF_UNSET;
+    conf->upstream.cache_background_update = NGX_CONF_UNSET;
 #endif
 
     conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
@@ -3061,6 +3069,9 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
     ngx_conf_merge_value(conf->upstream.cache_revalidate,
                               prev->upstream.cache_revalidate, 0);
 
+    ngx_conf_merge_value(conf->upstream.cache_background_update,
+                              prev->upstream.cache_background_update, 0);
+
 #endif
 
     ngx_conf_merge_value(conf->upstream.pass_request_headers,
index 42b6afc31acc328d9678ed6a9c8ae1d4d48d685b..1a84d78b3fee0de5caac6dc539f0121cc422fa62 100644 (file)
@@ -548,6 +548,13 @@ static ngx_command_t  ngx_http_proxy_commands[] = {
       offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_convert_head),
       NULL },
 
+    { ngx_string("proxy_cache_background_update"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+      ngx_conf_set_flag_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_background_update),
+      NULL },
+
 #endif
 
     { ngx_string("proxy_temp_path"),
@@ -2863,6 +2870,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
     conf->upstream.cache_lock_age = NGX_CONF_UNSET_MSEC;
     conf->upstream.cache_revalidate = NGX_CONF_UNSET;
     conf->upstream.cache_convert_head = NGX_CONF_UNSET;
+    conf->upstream.cache_background_update = NGX_CONF_UNSET;
 #endif
 
     conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
@@ -3168,6 +3176,9 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
     ngx_conf_merge_value(conf->upstream.cache_convert_head,
                               prev->upstream.cache_convert_head, 1);
 
+    ngx_conf_merge_value(conf->upstream.cache_background_update,
+                              prev->upstream.cache_background_update, 0);
+
 #endif
 
     if (conf->method == NULL) {
index aa84a3dbac551276220ed0c95fac5e79b81633d1..288ba092bf900df0610dbe5f8e5cff2bd93cf784 100644 (file)
@@ -319,6 +319,13 @@ static ngx_command_t ngx_http_scgi_commands[] = {
       offsetof(ngx_http_scgi_loc_conf_t, upstream.cache_revalidate),
       NULL },
 
+    { ngx_string("scgi_cache_background_update"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+      ngx_conf_set_flag_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_scgi_loc_conf_t, upstream.cache_background_update),
+      NULL },
+
 #endif
 
     { ngx_string("scgi_temp_path"),
@@ -1219,6 +1226,7 @@ ngx_http_scgi_create_loc_conf(ngx_conf_t *cf)
     conf->upstream.cache_lock_timeout = NGX_CONF_UNSET_MSEC;
     conf->upstream.cache_lock_age = NGX_CONF_UNSET_MSEC;
     conf->upstream.cache_revalidate = NGX_CONF_UNSET;
+    conf->upstream.cache_background_update = NGX_CONF_UNSET;
 #endif
 
     conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
@@ -1506,6 +1514,9 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
     ngx_conf_merge_value(conf->upstream.cache_revalidate,
                               prev->upstream.cache_revalidate, 0);
 
+    ngx_conf_merge_value(conf->upstream.cache_background_update,
+                              prev->upstream.cache_background_update, 0);
+
 #endif
 
     ngx_conf_merge_value(conf->upstream.pass_request_headers,
index b9c8dba2a29450c518b55a9ed4a0e6102a887778..2ba64af86e3a3c08fbb6ad2edffc3e11cd1a9360 100644 (file)
@@ -379,6 +379,13 @@ static ngx_command_t ngx_http_uwsgi_commands[] = {
       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_revalidate),
       NULL },
 
+    { ngx_string("uwsgi_cache_background_update"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_flag_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_background_update),
+      NULL },
+
 #endif
 
     { ngx_string("uwsgi_temp_path"),
@@ -1425,6 +1432,7 @@ ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf)
     conf->upstream.cache_lock_timeout = NGX_CONF_UNSET_MSEC;
     conf->upstream.cache_lock_age = NGX_CONF_UNSET_MSEC;
     conf->upstream.cache_revalidate = NGX_CONF_UNSET;
+    conf->upstream.cache_background_update = NGX_CONF_UNSET;
 #endif
 
     conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
@@ -1720,6 +1728,9 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
     ngx_conf_merge_value(conf->upstream.cache_revalidate,
                               prev->upstream.cache_revalidate, 0);
 
+    ngx_conf_merge_value(conf->upstream.cache_background_update,
+                              prev->upstream.cache_background_update, 0);
+
 #endif
 
     ngx_conf_merge_value(conf->upstream.pass_request_headers,
index d253812f6408de2b582b494fc8df3ffdfc67d9d3..5b135e209fb402208ec6c829af1251621a232d84 100644 (file)
@@ -116,6 +116,7 @@ struct ngx_http_cache_s {
     unsigned                         purged:1;
     unsigned                         reading:1;
     unsigned                         secondary:1;
+    unsigned                         background:1;
 
     unsigned                         stale_updating:1;
     unsigned                         stale_error:1;
index b046235fd4405675eb0633aead4530a298546d4e..9e128908aec4fb9414bbbe12b13b43c02d770517 100644 (file)
@@ -2566,6 +2566,17 @@ ngx_http_subrequest(ngx_http_request_t *r,
 
     *psr = sr;
 
+    if (flags & NGX_HTTP_SUBREQUEST_CLONE) {
+        sr->method = r->method;
+        sr->method_name = r->method_name;
+        sr->loc_conf = r->loc_conf;
+        sr->valid_location = r->valid_location;
+        sr->phase_handler = r->phase_handler;
+        sr->write_event_handler = ngx_http_core_run_phases;
+
+        ngx_http_update_location_config(sr);
+    }
+
     return ngx_http_post_request(sr, NULL);
 }
 
index 731f6b09c3af31fa140c78f6a48bbfa490fe4a89..8c75f95f94cb282e70e4d56115d6ef697bb9bfc3 100644 (file)
@@ -1688,7 +1688,7 @@ ngx_http_file_cache_cleanup(void *data)
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->file.log, 0,
                    "http file cache cleanup");
 
-    if (c->updating) {
+    if (c->updating && !c->background) {
         ngx_log_error(NGX_LOG_ALERT, c->file.log, 0,
                       "stalled cache updating, error:%ui", c->error);
     }
index cf9ee3c61cc4f2e10cec8777755e2cb020894697..4cda7549d6bff799325f492ad5234b457933bf42 100644 (file)
@@ -62,7 +62,9 @@
 /* unused                                  1 */
 #define NGX_HTTP_SUBREQUEST_IN_MEMORY      2
 #define NGX_HTTP_SUBREQUEST_WAITED         4
-#define NGX_HTTP_LOG_UNSAFE                8
+#define NGX_HTTP_SUBREQUEST_CLONE          8
+
+#define NGX_HTTP_LOG_UNSAFE                1
 
 
 #define NGX_HTTP_CONTINUE                  100
@@ -481,6 +483,7 @@ struct ngx_http_request_s {
 
 #if (NGX_HTTP_CACHE)
     unsigned                          cached:1;
+    unsigned                          cache_updater:1;
 #endif
 
 #if (NGX_HTTP_GZIP)
index d33ddd66e7c7555b40cf5960cce9ebf9323931f6..9cbec1fedc745ef1c7b985ef434fa1a50c45d114 100644 (file)
@@ -17,6 +17,8 @@ static ngx_int_t ngx_http_upstream_cache_get(ngx_http_request_t *r,
     ngx_http_upstream_t *u, ngx_http_file_cache_t **cache);
 static ngx_int_t ngx_http_upstream_cache_send(ngx_http_request_t *r,
     ngx_http_upstream_t *u);
+static ngx_int_t ngx_http_upstream_cache_background_update(
+    ngx_http_request_t *r, ngx_http_upstream_t *u);
 static ngx_int_t ngx_http_upstream_cache_check_range(ngx_http_request_t *r,
     ngx_http_upstream_t *u);
 static ngx_int_t ngx_http_upstream_cache_status(ngx_http_request_t *r,
@@ -578,6 +580,10 @@ ngx_http_upstream_init_request(ngx_http_request_t *r)
                 rc = NGX_DECLINED;
                 r->cached = 0;
             }
+
+            if (ngx_http_upstream_cache_background_update(r, u) != NGX_OK) {
+                rc = NGX_ERROR;
+            }
         }
 
         if (rc != NGX_DECLINED) {
@@ -869,10 +875,23 @@ ngx_http_upstream_cache(ngx_http_request_t *r, ngx_http_upstream_t *u)
 
     switch (rc) {
 
+    case NGX_HTTP_CACHE_STALE:
+
+        if (((u->conf->cache_use_stale & NGX_HTTP_UPSTREAM_FT_UPDATING)
+             || c->stale_updating) && !r->cache_updater
+            && u->conf->cache_background_update)
+        {
+            r->cache->background = 1;
+            u->cache_status = rc;
+            rc = NGX_OK;
+        }
+
+        break;
+
     case NGX_HTTP_CACHE_UPDATING:
 
-        if ((u->conf->cache_use_stale & NGX_HTTP_UPSTREAM_FT_UPDATING)
-            || c->stale_updating)
+        if (((u->conf->cache_use_stale & NGX_HTTP_UPSTREAM_FT_UPDATING)
+             || c->stale_updating) && !r->cache_updater)
         {
             u->cache_status = rc;
             rc = NGX_OK;
@@ -1045,6 +1064,30 @@ ngx_http_upstream_cache_send(ngx_http_request_t *r, ngx_http_upstream_t *u)
 }
 
 
+static ngx_int_t
+ngx_http_upstream_cache_background_update(ngx_http_request_t *r,
+    ngx_http_upstream_t *u)
+{
+    ngx_http_request_t  *sr;
+
+    if (!r->cached || !r->cache->background) {
+        return NGX_OK;
+    }
+
+    if (ngx_http_subrequest(r, &r->uri, &r->args, &sr, NULL,
+                            NGX_HTTP_SUBREQUEST_CLONE)
+        != NGX_OK)
+    {
+        return NGX_ERROR;
+    }
+
+    sr->header_only = 1;
+    sr->cache_updater = 1;
+
+    return NGX_OK;
+}
+
+
 static ngx_int_t
 ngx_http_upstream_cache_check_range(ngx_http_request_t *r,
     ngx_http_upstream_t *u)
index 7f601ee0be3aa24da979e529ff47750fc9c280a0..625889b6a3607b67b1ef8d032a9c650675381465 100644 (file)
@@ -202,6 +202,7 @@ typedef struct {
 
     ngx_flag_t                       cache_revalidate;
     ngx_flag_t                       cache_convert_head;
+    ngx_flag_t                       cache_background_update;
 
     ngx_array_t                     *cache_valid;
     ngx_array_t                     *cache_bypass;