@@ -913,8 +913,33 @@ Http2ConnectionState::main_event_handler(int event, void *edata)
913913 }
914914 }
915915
916- break ;
917- }
916+ } break ;
917+
918+ // Initiate a gracefull shutdown
919+ case HTTP2_SESSION_EVENT_SHUTDOWN_INIT: {
920+ SCOPED_MUTEX_LOCK (lock, this ->mutex , this_ethread ());
921+ if (shutdown_state != NOT_INITATED)
922+ break ;
923+ shutdown_state = INITIATED;
924+ // [RFC 7540] 6.8. GOAWAY
925+ // A server that is attempting to gracefully shut down a
926+ // connection SHOULD send an initial GOAWAY frame with the last stream
927+ // identifier set to 2^31-1 and a NO_ERROR code.
928+ send_goaway_frame (INT32_MAX, Http2ErrorCode::HTTP2_ERROR_NO_ERROR);
929+ // After allowing time for any in-flight stream creation (at least one round-trip time),
930+ this_ethread ()->schedule_in ((Continuation *)this , HRTIME_SECONDS (2 ), HTTP2_SESSION_EVENT_SHUTDOWN_CONT);
931+ } break ;
932+
933+ // Continue a gracefull shutdown
934+ case HTTP2_SESSION_EVENT_SHUTDOWN_CONT: {
935+ SCOPED_MUTEX_LOCK (lock, this ->mutex , this_ethread ());
936+ if (shutdown_state != INITIATED)
937+ break ;
938+ shutdown_state = IN_PROGREASS;
939+ // [RFC 7540] 6.8. GOAWAY
940+ // ..., the server can send another GOAWAY frame with an updated last stream identifier
941+ send_goaway_frame (latest_streamid_in, Http2ErrorCode::HTTP2_ERROR_NO_ERROR);
942+ } break ;
918943
919944 default :
920945 DebugHttp2Con (ua_session, " unexpected event=%d edata=%p" , event, edata);
@@ -1120,6 +1145,9 @@ Http2ConnectionState::release_stream(Http2Stream *stream)
11201145 // We were shutting down, go ahead and terminate the session
11211146 ua_session->destroy ();
11221147 ua_session = nullptr ;
1148+ } else if (total_client_streams_count == 0 && http2_drain && ua_session && stream) {
1149+ send_goaway_frame (stream->get_id (), Http2ErrorCode::HTTP2_ERROR_NO_ERROR);
1150+ Note (" [Http2ConnectionState::release_stream]: draining http2 connection, GOAWAY is sent" );
11231151 }
11241152}
11251153
0 commit comments