[nginx] Background subrequests for cache updates.
Roman Arutyunyan
arut at nginx.com
Thu May 25 15:18:52 UTC 2017
details: http://hg.nginx.org/nginx/rev/9552758a786e
branches:
changeset: 7006:9552758a786e
user: Roman Arutyunyan <arut at nginx.com>
date: Thu May 25 15:57:59 2017 +0300
description:
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.
diffstat:
src/http/ngx_http_core_module.c | 41 ++++++++++++++++++++++-------------------
src/http/ngx_http_request.c | 27 ++++++++++++++++++++++++---
src/http/ngx_http_request.h | 3 ++-
src/http/ngx_http_upstream.c | 8 ++++----
4 files changed, 52 insertions(+), 27 deletions(-)
diffs (185 lines):
diff -r 3e2d90073adf -r 9552758a786e src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c Wed May 24 13:17:08 2017 +0300
+++ b/src/http/ngx_http_core_module.c Thu May 25 15:57:59 2017 +0300
@@ -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;
diff -r 3e2d90073adf -r 9552758a786e src/http/ngx_http_request.c
--- a/src/http/ngx_http_request.c Wed May 24 13:17:08 2017 +0300
+++ b/src/http/ngx_http_request.c Thu May 25 15:57:59 2017 +0300
@@ -2357,6 +2357,26 @@ ngx_http_finalize_request(ngx_http_reque
}
if (r != r->main) {
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+ if (r->background) {
+ if (!r->logged) {
+ if (clcf->log_subrequest) {
+ ngx_http_log_request(r);
+ }
+
+ r->logged = 1;
+
+ } else {
+ ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+ "subrequest: \"%V?%V\" logged again",
+ &r->uri, &r->args);
+ }
+
+ r->done = 1;
+ ngx_http_finalize_connection(r);
+ return;
+ }
if (r->buffered || r->postponed) {
@@ -2374,9 +2394,6 @@ ngx_http_finalize_request(ngx_http_reque
r->main->count--;
if (!r->logged) {
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
if (clcf->log_subrequest) {
ngx_http_log_request(r);
}
@@ -2440,6 +2457,8 @@ ngx_http_finalize_request(ngx_http_reque
}
r->done = 1;
+
+ r->read_event_handler = ngx_http_block_reading;
r->write_event_handler = ngx_http_request_empty_handler;
if (!r->post_action) {
@@ -2558,6 +2577,8 @@ ngx_http_finalize_connection(ngx_http_re
return;
}
+ r = r->main;
+
if (r->reading_body) {
r->keepalive = 0;
r->lingering_close = 1;
diff -r 3e2d90073adf -r 9552758a786e src/http/ngx_http_request.h
--- a/src/http/ngx_http_request.h Wed May 24 13:17:08 2017 +0300
+++ b/src/http/ngx_http_request.h Thu May 25 15:57:59 2017 +0300
@@ -64,6 +64,7 @@
#define NGX_HTTP_SUBREQUEST_IN_MEMORY 2
#define NGX_HTTP_SUBREQUEST_WAITED 4
#define NGX_HTTP_SUBREQUEST_CLONE 8
+#define NGX_HTTP_SUBREQUEST_BACKGROUND 16
#define NGX_HTTP_LOG_UNSAFE 1
@@ -486,7 +487,6 @@ struct ngx_http_request_s {
#if (NGX_HTTP_CACHE)
unsigned cached:1;
- unsigned cache_updater:1;
#endif
#if (NGX_HTTP_GZIP)
@@ -543,6 +543,7 @@ struct ngx_http_request_s {
unsigned stat_writing:1;
unsigned stat_processing:1;
+ unsigned background:1;
unsigned health_check:1;
/* used to parse HTTP headers */
diff -r 3e2d90073adf -r 9552758a786e src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c Wed May 24 13:17:08 2017 +0300
+++ b/src/http/ngx_http_upstream.c Thu May 25 15:57:59 2017 +0300
@@ -879,7 +879,7 @@ ngx_http_upstream_cache(ngx_http_request
case NGX_HTTP_CACHE_STALE:
if (((u->conf->cache_use_stale & NGX_HTTP_UPSTREAM_FT_UPDATING)
- || c->stale_updating) && !r->cache_updater
+ || c->stale_updating) && !r->background
&& u->conf->cache_background_update)
{
r->cache->background = 1;
@@ -892,7 +892,7 @@ ngx_http_upstream_cache(ngx_http_request
case NGX_HTTP_CACHE_UPDATING:
if (((u->conf->cache_use_stale & NGX_HTTP_UPSTREAM_FT_UPDATING)
- || c->stale_updating) && !r->cache_updater)
+ || c->stale_updating) && !r->background)
{
u->cache_status = rc;
rc = NGX_OK;
@@ -1076,14 +1076,14 @@ ngx_http_upstream_cache_background_updat
}
if (ngx_http_subrequest(r, &r->uri, &r->args, &sr, NULL,
- NGX_HTTP_SUBREQUEST_CLONE)
+ NGX_HTTP_SUBREQUEST_CLONE
+ |NGX_HTTP_SUBREQUEST_BACKGROUND)
!= NGX_OK)
{
return NGX_ERROR;
}
sr->header_only = 1;
- sr->cache_updater = 1;
return NGX_OK;
}
More information about the nginx-devel
mailing list