|
|
@ -68,6 +68,9 @@ namespace grpc_core { |
|
|
|
|
|
|
|
|
|
|
|
TraceFlag grpc_outlier_detection_lb_trace(false, "outlier_detection_lb"); |
|
|
|
TraceFlag grpc_outlier_detection_lb_trace(false, "outlier_detection_lb"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const char* DisableOutlierDetectionAttribute::kName = |
|
|
|
|
|
|
|
"disable_outlier_detection"; |
|
|
|
|
|
|
|
|
|
|
|
namespace { |
|
|
|
namespace { |
|
|
|
|
|
|
|
|
|
|
|
using ::grpc_event_engine::experimental::EventEngine; |
|
|
|
using ::grpc_event_engine::experimental::EventEngine; |
|
|
@ -368,6 +371,8 @@ class OutlierDetectionLb : public LoadBalancingPolicy { |
|
|
|
|
|
|
|
|
|
|
|
~OutlierDetectionLb() override; |
|
|
|
~OutlierDetectionLb() override; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Returns the address map key for an address, or the empty string if
|
|
|
|
|
|
|
|
// the address should be ignored.
|
|
|
|
static std::string MakeKeyForAddress(const ServerAddress& address); |
|
|
|
static std::string MakeKeyForAddress(const ServerAddress& address); |
|
|
|
|
|
|
|
|
|
|
|
void ShutdownLocked() override; |
|
|
|
void ShutdownLocked() override; |
|
|
@ -546,9 +551,21 @@ OutlierDetectionLb::~OutlierDetectionLb() { |
|
|
|
|
|
|
|
|
|
|
|
std::string OutlierDetectionLb::MakeKeyForAddress( |
|
|
|
std::string OutlierDetectionLb::MakeKeyForAddress( |
|
|
|
const ServerAddress& address) { |
|
|
|
const ServerAddress& address) { |
|
|
|
|
|
|
|
// If the address has the DisableOutlierDetectionAttribute attribute,
|
|
|
|
|
|
|
|
// ignore it.
|
|
|
|
|
|
|
|
// TODO(roth): This is a hack to prevent outlier_detection from
|
|
|
|
|
|
|
|
// working with pick_first, as per discussion in
|
|
|
|
|
|
|
|
// https://github.com/grpc/grpc/issues/32967. Remove this as part of
|
|
|
|
|
|
|
|
// implementing dualstack backend support.
|
|
|
|
|
|
|
|
if (address.GetAttribute(DisableOutlierDetectionAttribute::kName) != |
|
|
|
|
|
|
|
nullptr) { |
|
|
|
|
|
|
|
return ""; |
|
|
|
|
|
|
|
} |
|
|
|
// Use only the address, not the attributes.
|
|
|
|
// Use only the address, not the attributes.
|
|
|
|
auto addr_str = grpc_sockaddr_to_string(&address.address(), false); |
|
|
|
auto addr_str = grpc_sockaddr_to_string(&address.address(), false); |
|
|
|
return addr_str.ok() ? addr_str.value() : addr_str.status().ToString(); |
|
|
|
// If address couldn't be stringified, ignore it.
|
|
|
|
|
|
|
|
if (!addr_str.ok()) return ""; |
|
|
|
|
|
|
|
return std::move(*addr_str); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void OutlierDetectionLb::ShutdownLocked() { |
|
|
|
void OutlierDetectionLb::ShutdownLocked() { |
|
|
@ -621,6 +638,7 @@ absl::Status OutlierDetectionLb::UpdateLocked(UpdateArgs args) { |
|
|
|
std::set<std::string> current_addresses; |
|
|
|
std::set<std::string> current_addresses; |
|
|
|
for (const ServerAddress& address : *args.addresses) { |
|
|
|
for (const ServerAddress& address : *args.addresses) { |
|
|
|
std::string address_key = MakeKeyForAddress(address); |
|
|
|
std::string address_key = MakeKeyForAddress(address); |
|
|
|
|
|
|
|
if (address_key.empty()) continue; |
|
|
|
auto& subchannel_state = subchannel_state_map_[address_key]; |
|
|
|
auto& subchannel_state = subchannel_state_map_[address_key]; |
|
|
|
if (subchannel_state == nullptr) { |
|
|
|
if (subchannel_state == nullptr) { |
|
|
|
subchannel_state = MakeRefCounted<SubchannelState>(); |
|
|
|
subchannel_state = MakeRefCounted<SubchannelState>(); |
|
|
@ -722,12 +740,20 @@ OrphanablePtr<LoadBalancingPolicy> OutlierDetectionLb::CreateChildPolicyLocked( |
|
|
|
RefCountedPtr<SubchannelInterface> OutlierDetectionLb::Helper::CreateSubchannel( |
|
|
|
RefCountedPtr<SubchannelInterface> OutlierDetectionLb::Helper::CreateSubchannel( |
|
|
|
ServerAddress address, const ChannelArgs& args) { |
|
|
|
ServerAddress address, const ChannelArgs& args) { |
|
|
|
if (outlier_detection_policy_->shutting_down_) return nullptr; |
|
|
|
if (outlier_detection_policy_->shutting_down_) return nullptr; |
|
|
|
std::string key = MakeKeyForAddress(address); |
|
|
|
|
|
|
|
RefCountedPtr<SubchannelState> subchannel_state; |
|
|
|
RefCountedPtr<SubchannelState> subchannel_state; |
|
|
|
|
|
|
|
std::string key = MakeKeyForAddress(address); |
|
|
|
|
|
|
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_outlier_detection_lb_trace)) { |
|
|
|
|
|
|
|
gpr_log(GPR_INFO, |
|
|
|
|
|
|
|
"[outlier_detection_lb %p] using key %s for subchannel address %s", |
|
|
|
|
|
|
|
outlier_detection_policy_.get(), key.c_str(), |
|
|
|
|
|
|
|
address.ToString().c_str()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (!key.empty()) { |
|
|
|
auto it = outlier_detection_policy_->subchannel_state_map_.find(key); |
|
|
|
auto it = outlier_detection_policy_->subchannel_state_map_.find(key); |
|
|
|
if (it != outlier_detection_policy_->subchannel_state_map_.end()) { |
|
|
|
if (it != outlier_detection_policy_->subchannel_state_map_.end()) { |
|
|
|
subchannel_state = it->second->Ref(); |
|
|
|
subchannel_state = it->second->Ref(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
auto subchannel = MakeRefCounted<SubchannelWrapper>( |
|
|
|
auto subchannel = MakeRefCounted<SubchannelWrapper>( |
|
|
|
subchannel_state, |
|
|
|
subchannel_state, |
|
|
|
outlier_detection_policy_->channel_control_helper()->CreateSubchannel( |
|
|
|
outlier_detection_policy_->channel_control_helper()->CreateSubchannel( |
|
|
|