comparison src/http/ngx_http_request.c @ 9307:3c71158f5a34 default tip

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 199dc0d6b05b
children
comparison
equal deleted inserted replaced
9306:e46e1ea89ccd 9307:3c71158f5a34
3097 static void 3097 static void
3098 ngx_http_set_keepalive(ngx_http_request_t *r) 3098 ngx_http_set_keepalive(ngx_http_request_t *r)
3099 { 3099 {
3100 int tcp_nodelay; 3100 int tcp_nodelay;
3101 ngx_buf_t *b, *f; 3101 ngx_buf_t *b, *f;
3102 ngx_msec_t timer;
3102 ngx_chain_t *cl, *ln; 3103 ngx_chain_t *cl, *ln;
3103 ngx_event_t *rev, *wev; 3104 ngx_event_t *rev, *wev;
3104 ngx_connection_t *c; 3105 ngx_connection_t *c;
3105 ngx_http_connection_t *hc; 3106 ngx_http_connection_t *hc;
3106 ngx_http_core_loc_conf_t *clcf; 3107 ngx_http_core_loc_conf_t *clcf;
3297 #if 0 3298 #if 0
3298 /* if ngx_http_request_t was freed then we need some other place */ 3299 /* if ngx_http_request_t was freed then we need some other place */
3299 r->http_state = NGX_HTTP_KEEPALIVE_STATE; 3300 r->http_state = NGX_HTTP_KEEPALIVE_STATE;
3300 #endif 3301 #endif
3301 3302
3302 c->idle = 1;
3303 ngx_reusable_connection(c, 1); 3303 ngx_reusable_connection(c, 1);
3304 3304
3305 ngx_add_timer(rev, clcf->keepalive_timeout); 3305 if (clcf->lingering_close
3306 && clcf->lingering_timeout > 0)
3307 {
3308 timer = ngx_min(clcf->keepalive_timeout, clcf->lingering_timeout);
3309 hc->keepalive_timeout = clcf->keepalive_timeout - timer;
3310 ngx_add_timer(rev, timer);
3311
3312 } else {
3313 c->idle = 1;
3314 ngx_add_timer(rev, clcf->keepalive_timeout);
3315 }
3306 3316
3307 if (rev->ready) { 3317 if (rev->ready) {
3308 ngx_post_event(rev, &ngx_posted_events); 3318 ngx_post_event(rev, &ngx_posted_events);
3309 } 3319 }
3310 } 3320 }
3311 3321
3312 3322
3313 static void 3323 static void
3314 ngx_http_keepalive_handler(ngx_event_t *rev) 3324 ngx_http_keepalive_handler(ngx_event_t *rev)
3315 { 3325 {
3316 size_t size; 3326 size_t size;
3317 ssize_t n; 3327 ssize_t n;
3318 ngx_buf_t *b; 3328 ngx_buf_t *b;
3319 ngx_connection_t *c; 3329 ngx_connection_t *c;
3330 ngx_http_connection_t *hc;
3320 3331
3321 c = rev->data; 3332 c = rev->data;
3322 3333
3323 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http keepalive handler"); 3334 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http keepalive handler");
3324 3335
3325 if (rev->timedout || c->close) { 3336 if (rev->timedout) {
3337 if (c->idle || ngx_exiting) {
3338 ngx_http_close_connection(c);
3339 return;
3340 }
3341
3342 hc = c->data;
3343
3344 c->idle = 1;
3345 rev->timedout = 0;
3346 ngx_add_timer(rev, hc->keepalive_timeout);
3347
3348 return;
3349 }
3350
3351 if (c->close) {
3326 ngx_http_close_connection(c); 3352 ngx_http_close_connection(c);
3327 return; 3353 return;
3328 } 3354 }
3329 3355
3330 #if (NGX_HAVE_KQUEUE) 3356 #if (NGX_HAVE_KQUEUE)