-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Add retries to policy checks on failed transport error #2113
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 all commits
e7dbf6a
1e832f4
1e8cee0
686d8c5
01e1763
66778ac
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 |
|---|---|---|
|
|
@@ -76,7 +76,7 @@ FilterHeadersStatus Filter::decodeHeaders(HeaderMap& headers, bool) { | |
| decoder_callbacks_->connection()); | ||
| Utils::HeaderUpdate header_update(&headers); | ||
| headers_ = &headers; | ||
| cancel_check_ = handler_->Check( | ||
| handler_->Check( | ||
|
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 cancel check fn replaced by reset cancel? A comment would help.
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. See explanation in #2113 (comment) |
||
| &check_data, &header_update, | ||
| control_.GetCheckTransport(decoder_callbacks_->activeSpan()), | ||
| [this](const CheckResponseInfo& info) { completeCheck(info); }); | ||
|
|
@@ -203,14 +203,12 @@ void Filter::completeCheck(const CheckResponseInfo& info) { | |
|
|
||
| void Filter::onDestroy() { | ||
| ENVOY_LOG(debug, "Called Mixer::Filter : {} state: {}", __func__, state_); | ||
| if (state_ != Calling) { | ||
| cancel_check_ = nullptr; | ||
| if (state_ != Calling && handler_) { | ||
| handler_->ResetCancel(); | ||
| } | ||
| state_ = Responded; | ||
| if (cancel_check_) { | ||
| ENVOY_LOG(debug, "Cancelling check call"); | ||
| cancel_check_(); | ||
| cancel_check_ = nullptr; | ||
| if (handler_) { | ||
| handler_->CancelCheck(); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -43,14 +43,12 @@ void Filter::initializeReadFilterCallbacks( | |
| } | ||
|
|
||
| void Filter::cancelCheck() { | ||
| if (state_ != State::Calling) { | ||
| cancel_check_ = nullptr; | ||
| if (state_ != State::Calling && handler_) { | ||
| handler_->ResetCancel(); | ||
| } | ||
| state_ = State::Closed; | ||
| if (cancel_check_) { | ||
| ENVOY_LOG(debug, "Cancelling check call"); | ||
| cancel_check_(); | ||
| cancel_check_ = nullptr; | ||
| if (handler_) { | ||
| handler_->CancelCheck(); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -61,7 +59,7 @@ void Filter::callCheck() { | |
| state_ = State::Calling; | ||
| filter_callbacks_->connection().readDisable(true); | ||
| calling_check_ = true; | ||
| cancel_check_ = handler_->Check( | ||
| handler_->Check( | ||
| this, [this](const CheckResponseInfo &info) { completeCheck(info); }); | ||
| calling_check_ = false; | ||
| } | ||
|
|
@@ -140,7 +138,7 @@ Network::FilterStatus Filter::onNewConnection() { | |
| void Filter::completeCheck(const CheckResponseInfo &info) { | ||
| const auto &status = info.status(); | ||
| ENVOY_LOG(debug, "Called tcp filter completeCheck: {}", status.ToString()); | ||
| cancel_check_ = nullptr; | ||
| handler_->ResetCancel(); | ||
|
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 the
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 think callCheck is always invoked before completeCheck. I'm pretty unfamiliar with this code, but other code in the same function calls handler_ without checking for null. |
||
| if (state_ == State::Closed) { | ||
| return; | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,6 +31,7 @@ using ::istio::mixerclient::MixerClientOptions; | |
| using ::istio::mixerclient::QuotaOptions; | ||
| using ::istio::mixerclient::ReportOptions; | ||
| using ::istio::mixerclient::Statistics; | ||
| using ::istio::mixerclient::TimerCreateFunc; | ||
| using ::istio::mixerclient::TransportCheckFunc; | ||
| using ::istio::utils::CreateLocalAttributes; | ||
| using ::istio::utils::LocalNode; | ||
|
|
@@ -39,6 +40,16 @@ namespace istio { | |
| namespace control { | ||
| namespace { | ||
|
|
||
| static constexpr uint32_t MaxDurationSec = 24 * 60 * 60; | ||
|
|
||
| static uint32_t DurationToMsec(const ::google::protobuf::Duration& duration) { | ||
| uint32_t msec = | ||
| 1000 * (duration.seconds() > MaxDurationSec ? MaxDurationSec | ||
| : duration.seconds()); | ||
| msec += duration.nanos() / 1000 / 1000; | ||
| return msec; | ||
| } | ||
|
|
||
| CheckOptions GetJustCheckOptions(const TransportConfig& config) { | ||
| if (config.disable_check_cache()) { | ||
| return CheckOptions(0); | ||
|
|
@@ -48,9 +59,25 @@ CheckOptions GetJustCheckOptions(const TransportConfig& config) { | |
|
|
||
| CheckOptions GetCheckOptions(const TransportConfig& config) { | ||
| auto options = GetJustCheckOptions(config); | ||
| if (config.has_network_fail_policy() && | ||
| config.network_fail_policy().policy() == NetworkFailPolicy::FAIL_CLOSE) { | ||
| options.network_fail_open = false; | ||
| if (config.has_network_fail_policy()) { | ||
| if (config.network_fail_policy().policy() == | ||
| NetworkFailPolicy::FAIL_CLOSE) { | ||
| options.network_fail_open = false; | ||
| } | ||
|
|
||
| if (0 <= config.network_fail_policy().max_retry()) { | ||
| options.retries = config.network_fail_policy().max_retry(); | ||
|
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. Question: What is the value of
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. As long as the protobuf defines it as a uint32, then the value returned will always be >= 0. So currently this if statement is useless. It could be seen as an extreme form of defensive programming in case the return type ever changed to a signed int... or I could just remove it and unconditionally clobber options.retries. Thoughts? |
||
| } | ||
|
|
||
| if (config.network_fail_policy().has_base_retry_wait()) { | ||
| options.base_retry_ms = | ||
| DurationToMsec(config.network_fail_policy().base_retry_wait()); | ||
| } | ||
|
|
||
| if (config.network_fail_policy().has_max_retry_wait()) { | ||
| options.max_retry_ms = | ||
| DurationToMsec(config.network_fail_policy().max_retry_wait()); | ||
| } | ||
| } | ||
| return options; | ||
| } | ||
|
|
@@ -81,9 +108,10 @@ ClientContextBase::ClientContextBase(const TransportConfig& config, | |
| mixer_client_ = ::istio::mixerclient::CreateMixerClient(options); | ||
| CreateLocalAttributes(local_node, &local_attributes_); | ||
| network_fail_open_ = options.check_options.network_fail_open; | ||
| retries_ = options.check_options.retries; | ||
| } | ||
|
|
||
| CancelFunc ClientContextBase::SendCheck( | ||
| void ClientContextBase::SendCheck( | ||
| const TransportCheckFunc& transport, const CheckDoneFunc& on_done, | ||
| ::istio::mixerclient::CheckContextSharedPtr& context) { | ||
| MIXER_DEBUG("Check attributes: %s", | ||
|
|
||
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.
nit: We may adopt the macro PURE in envoy/common/pure.h