diff src/http/ngx_http_core_module.c @ 7006:9552758a786e

Background subrequests for cache updates. Previously, cache background update might not work as expected, making client wait for it to complete before receiving the final part of a stale response. This could happen if the response could not be sent to the client socket in one filter chain call. Now background cache update is done in a background subrequest. This type of subrequest does not block any other subrequests or the main request.
author Roman Arutyunyan <arut@nginx.com>
date Thu, 25 May 2017 15:57:59 +0300
parents 0cdee26605f3
children 6d0e0d982ec0
line wrap: on
line diff
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -2518,6 +2518,7 @@ ngx_http_subrequest(ngx_http_request_t *
 
     sr->subrequest_in_memory = (flags & NGX_HTTP_SUBREQUEST_IN_MEMORY) != 0;
     sr->waited = (flags & NGX_HTTP_SUBREQUEST_WAITED) != 0;
+    sr->background = (flags & NGX_HTTP_SUBREQUEST_BACKGROUND) != 0;
 
     sr->unparsed_uri = r->unparsed_uri;
     sr->method_name = ngx_http_core_get_method;
@@ -2531,29 +2532,31 @@ ngx_http_subrequest(ngx_http_request_t *
     sr->read_event_handler = ngx_http_request_empty_handler;
     sr->write_event_handler = ngx_http_handler;
 
-    if (c->data == r && r->postponed == NULL) {
-        c->data = sr;
-    }
-
     sr->variables = r->variables;
 
     sr->log_handler = r->log_handler;
 
-    pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
-    if (pr == NULL) {
-        return NGX_ERROR;
-    }
-
-    pr->request = sr;
-    pr->out = NULL;
-    pr->next = NULL;
-
-    if (r->postponed) {
-        for (p = r->postponed; p->next; p = p->next) { /* void */ }
-        p->next = pr;
-
-    } else {
-        r->postponed = pr;
+    if (!sr->background) {
+        if (c->data == r && r->postponed == NULL) {
+            c->data = sr;
+        }
+
+        pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
+        if (pr == NULL) {
+            return NGX_ERROR;
+        }
+
+        pr->request = sr;
+        pr->out = NULL;
+        pr->next = NULL;
+
+        if (r->postponed) {
+            for (p = r->postponed; p->next; p = p->next) { /* void */ }
+            p->next = pr;
+
+        } else {
+            r->postponed = pr;
+        }
     }
 
     sr->internal = 1;