This is an automated email from the ASF dual-hosted git repository. cmcfarlen pushed a commit to branch 10.0.x in repository https://gitbox.apache.org/repos/asf/trafficserver.git
commit 615ab6bfb586b45cbbcb4c4eeae8bf060f941ebe Author: Chris McFarlen <[email protected]> AuthorDate: Tue Sep 10 11:02:34 2024 -0500 use exponential backoff for restarting streams after going past watermark (#11759) Co-authored-by: Chris McFarlen <[email protected]> (cherry picked from commit 7d3670e6ab6ecd826c286127416e14b599f0781e) --- include/proxy/http2/Http2ConnectionState.h | 5 +++++ src/proxy/http2/Http2ConnectionState.cc | 12 +++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/include/proxy/http2/Http2ConnectionState.h b/include/proxy/http2/Http2ConnectionState.h index 289918754c..53054416d9 100644 --- a/include/proxy/http2/Http2ConnectionState.h +++ b/include/proxy/http2/Http2ConnectionState.h @@ -388,6 +388,9 @@ private: * acknowledged by the peer. */ std::queue<OutstandingSettingsFrame> _outstanding_settings_frames; + static constexpr const int DATA_EVENT_BACKOFF_START = 10; + static constexpr const int DATA_EVENT_BACKOFF_MAX = 1000; + // NOTE: Id of stream which MUST receive CONTINUATION frame. // - [RFC 7540] 6.2 HEADERS // "A HEADERS frame without the END_HEADERS flag set MUST be followed by a @@ -399,6 +402,8 @@ private: bool fini_received = false; bool in_destroy = false; int recursion = 0; + int _data_event_backoff = DATA_EVENT_BACKOFF_START; + bool _data_event_retry = false; Http2ShutdownState shutdown_state = HTTP2_SHUTDOWN_NONE; Http2ErrorCode shutdown_reason = Http2ErrorCode::HTTP2_ERROR_MAX; Event *shutdown_cont_event = nullptr; diff --git a/src/proxy/http2/Http2ConnectionState.cc b/src/proxy/http2/Http2ConnectionState.cc index affbf0b813..2bebac321e 100644 --- a/src/proxy/http2/Http2ConnectionState.cc +++ b/src/proxy/http2/Http2ConnectionState.cc @@ -1537,7 +1537,11 @@ Http2ConnectionState::main_event_handler(int event, void *edata) case HTTP2_SESSION_EVENT_DATA: { REMEMBER(event, this->recursion); SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread()); + // mark the retry flag here so if the writes fail again we will + // backoff the next attempt + _data_event_retry = true; this->restart_streams(); + _data_event_retry = false; } break; case HTTP2_SESSION_EVENT_XMIT: { @@ -2169,7 +2173,13 @@ Http2ConnectionState::schedule_stream_to_send_data_frames(Http2Stream *stream) if (_data_event == nullptr) { SET_HANDLER(&Http2ConnectionState::main_event_handler); - _data_event = this_ethread()->schedule_in(static_cast<Continuation *>(this), HRTIME_MSECOND, HTTP2_SESSION_EVENT_DATA); + // exponential backoff scheduling event if we are in a retry. + // assume a slow reader will always be slow so don't reset the backoff + if (_data_event_retry) { + _data_event_backoff = std::min(DATA_EVENT_BACKOFF_MAX, _data_event_backoff << 1); + } + _data_event = this_ethread()->schedule_in(static_cast<Continuation *>(this), HRTIME_MSECONDS(_data_event_backoff), + HTTP2_SESSION_EVENT_DATA); } }
