-
Notifications
You must be signed in to change notification settings - Fork 5.5k
health check: gracefully handle GOAWAY in grpc health checker #11324
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 16 commits
e4ddb8e
70263a6
a069698
725caf8
58d2143
00a1fea
1828a2b
64c6aef
6ba45a4
c5958dc
b474edd
9171180
73e7308
dc5effd
7c7d930
41ea1e1
a66c176
bf9c59c
878bd4a
541eb54
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -471,7 +471,7 @@ ConnectionImpl::ConnectionImpl(Network::Connection& connection, CodecStats& stat | |
| http2_options.max_inbound_priority_frames_per_stream().value()), | ||
| max_inbound_window_update_frames_per_data_frame_sent_( | ||
| http2_options.max_inbound_window_update_frames_per_data_frame_sent().value()), | ||
| dispatching_(false), raised_goaway_(false), pending_deferred_reset_(false) {} | ||
| dispatching_(false), pending_deferred_reset_(false) {} | ||
|
|
||
| ConnectionImpl::~ConnectionImpl() { nghttp2_session_del(session_); } | ||
|
|
||
|
|
@@ -563,6 +563,16 @@ int ConnectionImpl::onBeforeFrameReceived(const nghttp2_frame_hd* hd) { | |
| return 0; | ||
| } | ||
|
|
||
| ABSL_MUST_USE_RESULT | ||
| enum GoAwayErrorCode ngHttp2ErrorCodeToErrorCode(uint32_t code) noexcept { | ||
| switch (code) { | ||
| case NGHTTP2_NO_ERROR: | ||
| return GoAwayErrorCode::NoError; | ||
| default: | ||
| return GoAwayErrorCode::Other; | ||
| } | ||
| } | ||
|
|
||
| int ConnectionImpl::onFrameReceived(const nghttp2_frame* frame) { | ||
| ENVOY_CONN_LOG(trace, "recv frame type={}", connection_, static_cast<uint64_t>(frame->hd.type)); | ||
|
|
||
|
|
@@ -577,12 +587,10 @@ int ConnectionImpl::onFrameReceived(const nghttp2_frame* frame) { | |
| } | ||
| } | ||
|
|
||
| // Only raise GOAWAY once, since we don't currently expose stream information. Shutdown | ||
| // notifications are the same as a normal GOAWAY. | ||
| if (frame->hd.type == NGHTTP2_GOAWAY && !raised_goaway_) { | ||
| // Shutdown notifications are the same as a normal GOAWAY. | ||
| if (frame->hd.type == NGHTTP2_GOAWAY) { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure if this is fine or if we want to track which goaway error codes we've already seen, and run the callbacks once per error code.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it expected to get multiple GOAWAY frames with different error codes? If yes, it seems bad only look at the first one, if no then we can probably keep the old logic.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is possible to receive GOAWAY frames with different error codes:
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm in that case should the logic for failing the HC be that we see a NO_ERROR + no error GOAWAYs? Also I'm not sure what the implications are of making
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Hm, I don't quite follow, could you rephrase?
Agreed. It seems it was added in #103. I'm not sure if that was an optimization back then. I'm also not sure if it has become an expected behaviour (intentionally or not) since then.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if a GOAWAY error follows a NO_ERROR then
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I see. I don't expect that to change the behaviour as it stands:
I admit this isn't obvious / does feel a bit brittle -- happy to add a comment and/or reset the flag anyways.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Friendly ping @mattklein123 @alyssawilk
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry for the delay. My preference would be to not raise multiple goaways from the codec as I'm guessing there will be code that won't expect this and will break. Can we just keep the previous behavior and not handle the case where multiple go away frames are received? We can potentially deal with this in a follow up if someone requests it?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the feedback - that seems reasonable to me. I've reverted that specific commit and added a TODO instead. |
||
| ASSERT(frame->hd.stream_id == 0); | ||
| raised_goaway_ = true; | ||
| callbacks().onGoAway(); | ||
| callbacks().onGoAway(ngHttp2ErrorCodeToErrorCode(frame->goaway.error_code)); | ||
| return 0; | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -317,7 +317,8 @@ TEST_P(Http2CodecImplTest, ShutdownNotice) { | |
| EXPECT_CALL(request_decoder_, decodeHeaders_(_, true)); | ||
| request_encoder_->encodeHeaders(request_headers, true); | ||
|
|
||
| EXPECT_CALL(client_callbacks_, onGoAway()); | ||
| // Called once from the shutdown notice and once from the goaway. | ||
| EXPECT_CALL(client_callbacks_, onGoAway(_)).Times(2); | ||
| server_->shutdownNotice(); | ||
| server_->goAway(); | ||
|
|
||
|
|
@@ -1456,7 +1457,7 @@ TEST_P(Http2CodecImplTest, LargeRequestHeadersExceedPerHeaderLimit) { | |
| request_headers.addCopy("big", long_string); | ||
|
|
||
| EXPECT_CALL(request_decoder_, decodeHeaders_(_, _)).Times(0); | ||
| EXPECT_CALL(client_callbacks_, onGoAway()); | ||
| EXPECT_CALL(client_callbacks_, onGoAway(_)); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't completely follow why this test doesn't trigger |
||
| server_->shutdownNotice(); | ||
| server_->goAway(); | ||
| request_encoder_->encodeHeaders(request_headers, true); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry should have mention this but this should have a doc comment as its in
include/