[PATCH] Keepalive connections now respect lingering_timeout on shutdown
Maxim Dounin
mdounin at mdounin.ru
Wed Jul 10 15:25:17 UTC 2024
# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1720570370 -10800
# Wed Jul 10 03:12:50 2024 +0300
# Node ID 3e36eed5bdaf1eec3d069705f197d04ef942b9d4
# Parent 2a847df382320a54c32abd9e64412ac611fcff0c
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.
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
--- 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;
}
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -331,6 +331,8 @@ typedef struct {
ngx_chain_t *free;
+ ngx_msec_t keepalive_timeout;
+
unsigned ssl:1;
unsigned proxy_protocol:1;
} ngx_http_connection_t;
More information about the nginx-devel
mailing list