Skip to content

Commit

Permalink
HTTP/2: graceful shutdown of active connections (closes #1106).
Browse files Browse the repository at this point in the history
Previously, while shutting down gracefully, the HTTP/2 connections were
closed in transition to idle state after all active streams have been
processed.  That might never happen if the client continued opening new
streams.

Now, nginx sends GOAWAY to all HTTP/2 connections and ignores further
attempts to open new streams.  A worker process will quit as soon as
processing of already opened streams is finished.
  • Loading branch information
VBart committed Oct 20, 2016
1 parent 9b8b33b commit 70d0530
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 9 deletions.
47 changes: 38 additions & 9 deletions src/http/v2/ngx_http_v2.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ static ngx_int_t ngx_http_v2_send_window_update(ngx_http_v2_connection_t *h2c,
ngx_uint_t sid, size_t window);
static ngx_int_t ngx_http_v2_send_rst_stream(ngx_http_v2_connection_t *h2c,
ngx_uint_t sid, ngx_uint_t status);
static ngx_int_t ngx_http_v2_send_goaway(ngx_http_v2_connection_t *h2c,
ngx_uint_t status);

static ngx_http_v2_out_frame_t *ngx_http_v2_get_frame(
ngx_http_v2_connection_t *h2c, size_t length, ngx_uint_t type,
Expand Down Expand Up @@ -293,6 +295,8 @@ ngx_http_v2_init(ngx_event_t *rev)
rev->handler = ngx_http_v2_read_handler;
c->write->handler = ngx_http_v2_write_handler;

c->idle = 1;

ngx_http_v2_read_handler(rev);
}

Expand Down Expand Up @@ -320,6 +324,25 @@ ngx_http_v2_read_handler(ngx_event_t *rev)

h2c->blocked = 1;

if (c->close) {
c->close = 0;
h2c->goaway = 1;

if (ngx_http_v2_send_goaway(h2c, NGX_HTTP_V2_NO_ERROR) == NGX_ERROR) {
ngx_http_v2_finalize_connection(h2c, 0);
return;
}

if (ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) {
ngx_http_v2_finalize_connection(h2c, 0);
return;
}

h2c->blocked = 0;

return;
}

h2mcf = ngx_http_get_module_main_conf(h2c->http_connection->conf_ctx,
ngx_http_v2_module);

Expand Down Expand Up @@ -633,18 +656,18 @@ ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c)
/* rc == NGX_OK */
}

if (h2c->goaway) {
ngx_http_close_connection(c);
return;
}

h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
ngx_http_v2_module);
if (h2c->state.incomplete) {
ngx_add_timer(c->read, h2scf->recv_timeout);
return;
}

if (ngx_terminate || ngx_exiting) {
ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_NO_ERROR);
return;
}

ngx_destroy_pool(h2c->pool);

h2c->pool = NULL;
Expand All @@ -658,7 +681,6 @@ ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c)
#endif

c->destroyed = 1;
c->idle = 1;
ngx_reusable_connection(c, 1);

c->write->handler = ngx_http_empty_handler;
Expand Down Expand Up @@ -1027,6 +1049,12 @@ ngx_http_v2_state_headers(ngx_http_v2_connection_t *h2c, u_char *pos,
return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
}

if (h2c->goaway) {
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
"skipping http2 HEADERS frame");
return ngx_http_v2_state_skip(h2c, pos, end);
}

if ((size_t) (end - pos) < size) {
return ngx_http_v2_state_save(h2c, pos, end,
ngx_http_v2_state_headers);
Expand Down Expand Up @@ -4162,7 +4190,6 @@ ngx_http_v2_idle_handler(ngx_event_t *rev)
#endif

c->destroyed = 0;
c->idle = 0;
ngx_reusable_connection(c, 0);

h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
Expand Down Expand Up @@ -4197,8 +4224,10 @@ ngx_http_v2_finalize_connection(ngx_http_v2_connection_t *h2c,

h2c->blocked = 1;

if (!c->error && ngx_http_v2_send_goaway(h2c, status) != NGX_ERROR) {
(void) ngx_http_v2_send_output_queue(h2c);
if (!c->error && !h2c->goaway) {
if (ngx_http_v2_send_goaway(h2c, status) != NGX_ERROR) {
(void) ngx_http_v2_send_output_queue(h2c);
}
}

c->error = 1;
Expand Down
1 change: 1 addition & 0 deletions src/http/v2/ngx_http_v2.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ struct ngx_http_v2_connection_s {
unsigned closed_nodes:8;
unsigned settings_ack:1;
unsigned blocked:1;
unsigned goaway:1;
};


Expand Down

0 comments on commit 70d0530

Please sign in to comment.