mirror of
https://github.com/nginx/nginx.git
synced 2025-02-25 18:55:26 -06:00
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.
This commit is contained in:
parent
c83922b18d
commit
8644d9491a
@ -2518,6 +2518,7 @@ ngx_http_subrequest(ngx_http_request_t *r,
|
||||
|
||||
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 *r,
|
||||
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;
|
||||
}
|
||||
if (!sr->background) {
|
||||
if (c->data == r && r->postponed == NULL) {
|
||||
c->data = sr;
|
||||
}
|
||||
|
||||
pr->request = sr;
|
||||
pr->out = NULL;
|
||||
pr->next = NULL;
|
||||
pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
|
||||
if (pr == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (r->postponed) {
|
||||
for (p = r->postponed; p->next; p = p->next) { /* void */ }
|
||||
p->next = pr;
|
||||
pr->request = sr;
|
||||
pr->out = NULL;
|
||||
pr->next = NULL;
|
||||
|
||||
} else {
|
||||
r->postponed = pr;
|
||||
if (r->postponed) {
|
||||
for (p = r->postponed; p->next; p = p->next) { /* void */ }
|
||||
p->next = pr;
|
||||
|
||||
} else {
|
||||
r->postponed = pr;
|
||||
}
|
||||
}
|
||||
|
||||
sr->internal = 1;
|
||||
|
@ -2357,6 +2357,26 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
|
||||
}
|
||||
|
||||
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_request_t *r, ngx_int_t rc)
|
||||
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_request_t *r, ngx_int_t rc)
|
||||
}
|
||||
|
||||
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_request_t *r)
|
||||
return;
|
||||
}
|
||||
|
||||
r = r->main;
|
||||
|
||||
if (r->reading_body) {
|
||||
r->keepalive = 0;
|
||||
r->lingering_close = 1;
|
||||
|
@ -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 */
|
||||
|
@ -879,7 +879,7 @@ ngx_http_upstream_cache(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
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_t *r, ngx_http_upstream_t *u)
|
||||
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_update(ngx_http_request_t *r,
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user