Mercurial > hg > nginx
changeset 9307:3c71158f5a34
Keepalive connections now respect lingering_timeout on shutdown.
During graceful shutdown keepalive connections are now closed only after
at least lingering_timeout of inactivity. To do so, c->idle is only
set on keepalive connections after lingering_timeout expires.
This ensures that the connection close race will less likely result in
connections being reset when a client sends a request at the same time
when the connection is closed by ngx_close_idle_connections() during
graceful shutdown.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Wed, 31 Jul 2024 17:50:58 +0300 |
parents | e46e1ea89ccd |
children | d2b87352e5a7 |
files | src/http/ngx_http_request.c src/http/ngx_http_request.h |
diffstat | 2 files changed, 35 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -3099,6 +3099,7 @@ ngx_http_set_keepalive(ngx_http_request_ { int tcp_nodelay; ngx_buf_t *b, *f; + ngx_msec_t timer; ngx_chain_t *cl, *ln; ngx_event_t *rev, *wev; ngx_connection_t *c; @@ -3299,10 +3300,19 @@ ngx_http_set_keepalive(ngx_http_request_ r->http_state = NGX_HTTP_KEEPALIVE_STATE; #endif - c->idle = 1; ngx_reusable_connection(c, 1); - ngx_add_timer(rev, clcf->keepalive_timeout); + if (clcf->lingering_close + && clcf->lingering_timeout > 0) + { + timer = ngx_min(clcf->keepalive_timeout, clcf->lingering_timeout); + hc->keepalive_timeout = clcf->keepalive_timeout - timer; + ngx_add_timer(rev, timer); + + } else { + c->idle = 1; + ngx_add_timer(rev, clcf->keepalive_timeout); + } if (rev->ready) { ngx_post_event(rev, &ngx_posted_events); @@ -3313,16 +3323,32 @@ ngx_http_set_keepalive(ngx_http_request_ static void ngx_http_keepalive_handler(ngx_event_t *rev) { - size_t size; - ssize_t n; - ngx_buf_t *b; - ngx_connection_t *c; + size_t size; + ssize_t n; + ngx_buf_t *b; + ngx_connection_t *c; + ngx_http_connection_t *hc; c = rev->data; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http keepalive handler"); - if (rev->timedout || c->close) { + if (rev->timedout) { + if (c->idle || ngx_exiting) { + ngx_http_close_connection(c); + return; + } + + hc = c->data; + + c->idle = 1; + rev->timedout = 0; + ngx_add_timer(rev, hc->keepalive_timeout); + + return; + } + + if (c->close) { ngx_http_close_connection(c); return; }