Support graceful shutdown using multiple GOAWAY
Add last_stream_id parameter to nghttp2_submit_goaway(). To terminate connection immediately with application chosen last stream ID, nghttp2_session_terminate_session2() was added.
This commit is contained in:
parent
975524a125
commit
b78a51da0e
|
@ -270,10 +270,10 @@ static int on_stream_close_callback(nghttp2_session *session,
|
|||
req = nghttp2_session_get_stream_user_data(session, stream_id);
|
||||
if(req) {
|
||||
int rv;
|
||||
rv = nghttp2_submit_goaway(session, NGHTTP2_FLAG_NONE, NGHTTP2_NO_ERROR,
|
||||
NULL, 0);
|
||||
rv = nghttp2_session_terminate_session(session, NGHTTP2_NO_ERROR);
|
||||
|
||||
if(rv != 0) {
|
||||
diec("nghttp2_submit_goaway", rv);
|
||||
diec("nghttp2_session_terminate_session", rv);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -2003,13 +2003,13 @@ int32_t nghttp2_session_get_stream_remote_window_size(nghttp2_session* session,
|
|||
*
|
||||
* Signals the session so that the connection should be terminated.
|
||||
*
|
||||
* GOAWAY frame with the given |error_code| will be submitted if it
|
||||
* has not been transmitted. After the transmission, both
|
||||
* `nghttp2_session_want_read()` and `nghttp2_session_want_write()`
|
||||
* return 0. If GOAWAY frame has already transmitted at the time when
|
||||
* this function is invoked, `nghttp2_session_want_read()` and
|
||||
* `nghttp2_session_want_write()` returns 0 immediately after this
|
||||
* function succeeds.
|
||||
* The last stream ID is the ID of a stream for which
|
||||
* :type:`nghttp2_on_frame_recv_callback` was called most recently.
|
||||
*
|
||||
* The |error_code| is the error code of this GOAWAY frame.
|
||||
*
|
||||
* After the transmission, both `nghttp2_session_want_read()` and
|
||||
* `nghttp2_session_want_write()` return 0.
|
||||
*
|
||||
* This function should be called when the connection should be
|
||||
* terminated after sending GOAWAY. If the remaining streams should
|
||||
|
@ -2024,6 +2024,25 @@ int32_t nghttp2_session_get_stream_remote_window_size(nghttp2_session* session,
|
|||
int nghttp2_session_terminate_session(nghttp2_session *session,
|
||||
nghttp2_error_code error_code);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* Signals the session so that the connection should be terminated.
|
||||
*
|
||||
* This function behaves like `nghttp2_session_terminate_session()`,
|
||||
* but the last stream ID can be specified by the application for fine
|
||||
* grained control of stream.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* :enum:`NGHTTP2_ERR_NOMEM`
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_session_terminate_session2(nghttp2_session *session,
|
||||
int32_t last_stream_id,
|
||||
nghttp2_error_code error_code);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
|
@ -2529,7 +2548,8 @@ int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags,
|
|||
/**
|
||||
* @function
|
||||
*
|
||||
* Submits GOAWAY frame with the error code |error_code|.
|
||||
* Submits GOAWAY frame with the last stream ID |last_stream_id| and
|
||||
* the error code |error_code|.
|
||||
*
|
||||
* The |flags| is currently ignored and should be
|
||||
* :enum:`NGHTTP2_FLAG_NONE`.
|
||||
|
@ -2541,15 +2561,22 @@ int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags,
|
|||
* keep this memory after the return of this function. If the
|
||||
* |opaque_data_len| is 0, the |opaque_data| could be ``NULL``.
|
||||
*
|
||||
* To shutdown gracefully, first send GOAWAY with ``last_stream_id =
|
||||
* (1u << 31) - 1``. After 1 RTT, call either
|
||||
* `nghttp2_submit_goaway()`, `nghttp2_session_terminate_session()` or
|
||||
* `nghttp2_session_terminate_session2()`. The latter 2 will close
|
||||
* HTTP/2 session immediately after transmission of the frame.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* :enum:`NGHTTP2_ERR_NOMEM`
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_INVALID_ARGUMENT
|
||||
* :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
|
||||
* The |opaque_data_len| is too large.
|
||||
*/
|
||||
int nghttp2_submit_goaway(nghttp2_session *session, uint8_t flags,
|
||||
int32_t last_stream_id,
|
||||
nghttp2_error_code error_code,
|
||||
const uint8_t *opaque_data, size_t opaque_data_len);
|
||||
|
||||
|
|
|
@ -134,14 +134,23 @@ static int session_detect_idle_stream(nghttp2_session *session,
|
|||
|
||||
int nghttp2_session_terminate_session(nghttp2_session *session,
|
||||
nghttp2_error_code error_code)
|
||||
{
|
||||
return nghttp2_session_terminate_session2(session,
|
||||
session->last_proc_stream_id,
|
||||
error_code);
|
||||
}
|
||||
|
||||
int nghttp2_session_terminate_session2(nghttp2_session *session,
|
||||
int32_t last_stream_id,
|
||||
nghttp2_error_code error_code)
|
||||
{
|
||||
if(session->goaway_flags & NGHTTP2_GOAWAY_FAIL_ON_SEND) {
|
||||
return 0;
|
||||
}
|
||||
session->goaway_flags |= NGHTTP2_GOAWAY_FAIL_ON_SEND;
|
||||
|
||||
return nghttp2_submit_goaway(session, NGHTTP2_FLAG_NONE, error_code,
|
||||
NULL, 0);
|
||||
return nghttp2_submit_goaway(session, NGHTTP2_FLAG_NONE, last_stream_id,
|
||||
error_code, NULL, 0);
|
||||
}
|
||||
|
||||
int nghttp2_session_is_my_stream_id(nghttp2_session *session,
|
||||
|
|
|
@ -246,10 +246,11 @@ int nghttp2_submit_rst_stream(nghttp2_session *session, uint8_t flags,
|
|||
}
|
||||
|
||||
int nghttp2_submit_goaway(nghttp2_session *session, uint8_t flags,
|
||||
int32_t last_stream_id,
|
||||
nghttp2_error_code error_code,
|
||||
const uint8_t *opaque_data, size_t opaque_data_len)
|
||||
{
|
||||
return nghttp2_session_add_goaway(session, session->last_proc_stream_id,
|
||||
return nghttp2_session_add_goaway(session, last_stream_id,
|
||||
error_code, opaque_data, opaque_data_len);
|
||||
}
|
||||
|
||||
|
|
|
@ -4429,7 +4429,8 @@ void test_nghttp2_session_on_ctrl_not_send(void)
|
|||
user_data.frame_not_send_cb_called = 0;
|
||||
/* Send GOAWAY */
|
||||
CU_ASSERT(0 == nghttp2_submit_goaway(session, NGHTTP2_FLAG_NONE,
|
||||
NGHTTP2_NO_ERROR, NULL, 0));
|
||||
(1u << 31) - 1, NGHTTP2_NO_ERROR,
|
||||
NULL, 0));
|
||||
|
||||
session->next_stream_id = 9;
|
||||
|
||||
|
@ -4456,7 +4457,7 @@ void test_nghttp2_session_get_outbound_queue_size(void)
|
|||
CU_ASSERT(1 == nghttp2_session_get_outbound_queue_size(session));
|
||||
|
||||
CU_ASSERT(0 == nghttp2_submit_goaway(session, NGHTTP2_FLAG_NONE,
|
||||
NGHTTP2_NO_ERROR, NULL, 0));
|
||||
3, NGHTTP2_NO_ERROR, NULL, 0));
|
||||
CU_ASSERT(2 == nghttp2_session_get_outbound_queue_size(session));
|
||||
|
||||
nghttp2_session_del(session);
|
||||
|
|
Loading…
Reference in New Issue