|
|
|
@ -881,6 +881,9 @@ class CallData { |
|
|
|
|
// ChannelData::SubchannelWrapper
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
using ServerAddressAttributeMap = |
|
|
|
|
std::map<const char*, std::unique_ptr<ServerAddress::AttributeInterface>>; |
|
|
|
|
|
|
|
|
|
// This class is a wrapper for Subchannel that hides details of the
|
|
|
|
|
// channel's implementation (such as the health check service name and
|
|
|
|
|
// connected subchannel) from the LB policy API.
|
|
|
|
@ -892,11 +895,13 @@ class CallData { |
|
|
|
|
class ChannelData::SubchannelWrapper : public SubchannelInterface { |
|
|
|
|
public: |
|
|
|
|
SubchannelWrapper(ChannelData* chand, Subchannel* subchannel, |
|
|
|
|
grpc_core::UniquePtr<char> health_check_service_name) |
|
|
|
|
grpc_core::UniquePtr<char> health_check_service_name, |
|
|
|
|
ServerAddressAttributeMap attributes) |
|
|
|
|
: SubchannelInterface(&grpc_client_channel_routing_trace), |
|
|
|
|
chand_(chand), |
|
|
|
|
subchannel_(subchannel), |
|
|
|
|
health_check_service_name_(std::move(health_check_service_name)) { |
|
|
|
|
health_check_service_name_(std::move(health_check_service_name)), |
|
|
|
|
attributes_(std::move(attributes)) { |
|
|
|
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { |
|
|
|
|
gpr_log(GPR_INFO, |
|
|
|
|
"chand=%p: creating subchannel wrapper %p for subchannel %p", |
|
|
|
@ -974,14 +979,21 @@ class ChannelData::SubchannelWrapper : public SubchannelInterface { |
|
|
|
|
|
|
|
|
|
void ResetBackoff() override { subchannel_->ResetBackoff(); } |
|
|
|
|
|
|
|
|
|
void ThrottleKeepaliveTime(int new_keepalive_time) { |
|
|
|
|
subchannel_->ThrottleKeepaliveTime(new_keepalive_time); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const grpc_channel_args* channel_args() override { |
|
|
|
|
return subchannel_->channel_args(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const ServerAddress::AttributeInterface* GetAttribute( |
|
|
|
|
const char* key) const override { |
|
|
|
|
auto it = attributes_.find(key); |
|
|
|
|
if (it == attributes_.end()) return nullptr; |
|
|
|
|
return it->second.get(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ThrottleKeepaliveTime(int new_keepalive_time) { |
|
|
|
|
subchannel_->ThrottleKeepaliveTime(new_keepalive_time); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void UpdateHealthCheckServiceName( |
|
|
|
|
grpc_core::UniquePtr<char> health_check_service_name) { |
|
|
|
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { |
|
|
|
@ -1175,6 +1187,7 @@ class ChannelData::SubchannelWrapper : public SubchannelInterface { |
|
|
|
|
ChannelData* chand_; |
|
|
|
|
Subchannel* subchannel_; |
|
|
|
|
grpc_core::UniquePtr<char> health_check_service_name_; |
|
|
|
|
ServerAddressAttributeMap attributes_; |
|
|
|
|
// Maps from the address of the watcher passed to us by the LB policy
|
|
|
|
|
// to the address of the WrapperWatcher that we passed to the underlying
|
|
|
|
|
// subchannel. This is needed so that when the LB policy calls
|
|
|
|
@ -1349,6 +1362,18 @@ class ChannelData::ConnectivityWatcherRemover { |
|
|
|
|
// ChannelData::ClientChannelControlHelper
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
// Allows accessing the attributes from a ServerAddress.
|
|
|
|
|
class ChannelServerAddressPeer { |
|
|
|
|
public: |
|
|
|
|
static ServerAddressAttributeMap GetAttributes(ServerAddress* address) { |
|
|
|
|
return std::move(address->attributes_); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
namespace { |
|
|
|
|
|
|
|
|
|
class ChannelData::ClientChannelControlHelper |
|
|
|
|
: public LoadBalancingPolicy::ChannelControlHelper { |
|
|
|
|
public: |
|
|
|
@ -1362,7 +1387,8 @@ class ChannelData::ClientChannelControlHelper |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
RefCountedPtr<SubchannelInterface> CreateSubchannel( |
|
|
|
|
const grpc_channel_args& args) override { |
|
|
|
|
ServerAddress address, const grpc_channel_args& args) override { |
|
|
|
|
// Determine health check service name.
|
|
|
|
|
bool inhibit_health_checking = grpc_channel_arg_get_bool( |
|
|
|
|
grpc_channel_args_find(&args, GRPC_ARG_INHIBIT_HEALTH_CHECKING), false); |
|
|
|
|
grpc_core::UniquePtr<char> health_check_service_name; |
|
|
|
@ -1370,21 +1396,37 @@ class ChannelData::ClientChannelControlHelper |
|
|
|
|
health_check_service_name.reset( |
|
|
|
|
gpr_strdup(chand_->health_check_service_name_.get())); |
|
|
|
|
} |
|
|
|
|
// Remove channel args that should not affect subchannel uniqueness.
|
|
|
|
|
static const char* args_to_remove[] = { |
|
|
|
|
GRPC_ARG_INHIBIT_HEALTH_CHECKING, |
|
|
|
|
GRPC_ARG_CHANNELZ_CHANNEL_NODE, |
|
|
|
|
}; |
|
|
|
|
grpc_arg arg = SubchannelPoolInterface::CreateChannelArg( |
|
|
|
|
chand_->subchannel_pool_.get()); |
|
|
|
|
// Add channel args needed for the subchannel.
|
|
|
|
|
absl::InlinedVector<grpc_arg, 3> args_to_add = { |
|
|
|
|
Subchannel::CreateSubchannelAddressArg(&address.address()), |
|
|
|
|
SubchannelPoolInterface::CreateChannelArg( |
|
|
|
|
chand_->subchannel_pool_.get()), |
|
|
|
|
}; |
|
|
|
|
if (address.args() != nullptr) { |
|
|
|
|
for (size_t j = 0; j < address.args()->num_args; ++j) { |
|
|
|
|
args_to_add.emplace_back(address.args()->args[j]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove( |
|
|
|
|
&args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &arg, 1); |
|
|
|
|
&args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), |
|
|
|
|
args_to_add.data(), args_to_add.size()); |
|
|
|
|
gpr_free(args_to_add[0].value.string); |
|
|
|
|
// Create subchannel.
|
|
|
|
|
Subchannel* subchannel = |
|
|
|
|
chand_->client_channel_factory_->CreateSubchannel(new_args); |
|
|
|
|
grpc_channel_args_destroy(new_args); |
|
|
|
|
if (subchannel == nullptr) return nullptr; |
|
|
|
|
// Make sure the subchannel has updated keepalive time.
|
|
|
|
|
subchannel->ThrottleKeepaliveTime(chand_->keepalive_time_); |
|
|
|
|
// Create and return wrapper for the subchannel.
|
|
|
|
|
return MakeRefCounted<SubchannelWrapper>( |
|
|
|
|
chand_, subchannel, std::move(health_check_service_name)); |
|
|
|
|
chand_, subchannel, std::move(health_check_service_name), |
|
|
|
|
ChannelServerAddressPeer::GetAttributes(&address)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void UpdateState( |
|
|
|
@ -1662,9 +1704,12 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error) |
|
|
|
|
&new_args); |
|
|
|
|
target_uri_.reset(proxy_name != nullptr ? proxy_name |
|
|
|
|
: gpr_strdup(server_uri)); |
|
|
|
|
channel_args_ = new_args != nullptr |
|
|
|
|
? new_args |
|
|
|
|
: grpc_channel_args_copy(args->channel_args); |
|
|
|
|
// Strip out service config channel arg, so that it doesn't affect
|
|
|
|
|
// subchannel uniqueness when the args flow down to that layer.
|
|
|
|
|
const char* arg_to_remove = GRPC_ARG_SERVICE_CONFIG; |
|
|
|
|
channel_args_ = grpc_channel_args_copy_and_remove( |
|
|
|
|
new_args != nullptr ? new_args : args->channel_args, &arg_to_remove, 1); |
|
|
|
|
grpc_channel_args_destroy(new_args); |
|
|
|
|
keepalive_time_ = grpc_channel_args_find_integer( |
|
|
|
|
channel_args_, GRPC_ARG_KEEPALIVE_TIME_MS, |
|
|
|
|
{-1 /* default value, unset */, 1, INT_MAX}); |
|
|
|
|