﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc	uname	nginx_version
1937	Nginx didn't update cache anymore after ngx_http_upstream_cache_background_update is failed.	haosdent@…		"When I use 
{{{
    proxy_cache_background_update  on;
    proxy_cache_use_stale          updating;
}}}

I found after the background subrequest is failed once, Nginx would not update cache anymore even the upstream recover.

This is due to once the background subrequest is failed.


{{{
    switch (rc) {

    case NGX_HTTP_CACHE_STALE:

        if (((u->conf->cache_use_stale & NGX_HTTP_UPSTREAM_FT_UPDATING)
             || c->stale_updating) && !r->background
            && 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) && !r->background)
        {
            u->cache_status = rc;
            rc = NGX_OK;

        } else {
            rc = NGX_HTTP_CACHE_STALE;
        }

}}}

cache status would become `NGX_HTTP_CACHE_UPDATING`, and because Nginx didn't set `r->cache->background = 1` again if cache status is `NGX_HTTP_CACHE_UPDATING`. Then in `ngx_http_upstream_cache_background_update`, it return directly for all further background subrequests.


{{{
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;
    }


}}}

  
This make Nginx always return stale content.

To fix this, we need to 

{{{#!diff
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index a1647e9d..1a0cbeec 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -967,6 +967,7 @@ ngx_http_upstream_cache(ngx_http_request_t *r, ngx_http_upstream_t *u)
         if (((u->conf->cache_use_stale & NGX_HTTP_UPSTREAM_FT_UPDATING)
              || c->stale_updating) && !r->background)
         {
+            r->cache->background = 1;
             u->cache_status = rc;
             rc = NGX_OK;
}}}"	defect	closed	major	nginx-1.17	documentation	1.16.x	worksforme				"nginx version: nginx/1.14.0
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.11)
built with OpenSSL 1.0.2j  26 Sep 2016
TLS SNI support enabled"
