|
|
|
@ -111,8 +111,9 @@ class SubchannelData { |
|
|
|
|
// Synchronously checks the subchannel's connectivity state. Calls
|
|
|
|
|
// ProcessConnectivityChangeLocked() if the state has changed.
|
|
|
|
|
// Must not be called while there is a connectivity notification
|
|
|
|
|
// pending (i.e., between calling StartOrRenewConnectivityWatchLocked()
|
|
|
|
|
// and the resulting invocation of ProcessConnectivityChangeLocked()).
|
|
|
|
|
// pending (i.e., between calling StartConnectivityWatchLocked() or
|
|
|
|
|
// RenewConnectivityWatchLocked() and the resulting invocation of
|
|
|
|
|
// ProcessConnectivityChangeLocked()).
|
|
|
|
|
void CheckConnectivityStateLocked() { |
|
|
|
|
GPR_ASSERT(!connectivity_notification_pending_); |
|
|
|
|
grpc_error* error = GRPC_ERROR_NONE; |
|
|
|
@ -133,18 +134,22 @@ class SubchannelData { |
|
|
|
|
// being unreffed.
|
|
|
|
|
virtual void UnrefSubchannelLocked(const char* reason); |
|
|
|
|
|
|
|
|
|
// Starts or renewes watching the connectivity state of the subchannel.
|
|
|
|
|
// Starts watching the connectivity state of the subchannel.
|
|
|
|
|
// ProcessConnectivityChangeLocked() will be called when the
|
|
|
|
|
// connectivity state changes.
|
|
|
|
|
void StartOrRenewConnectivityWatchLocked(); |
|
|
|
|
void StartConnectivityWatchLocked(); |
|
|
|
|
|
|
|
|
|
// Renews watching the connectivity state of the subchannel.
|
|
|
|
|
void RenewConnectivityWatchLocked(); |
|
|
|
|
|
|
|
|
|
// Stops watching the connectivity state of the subchannel.
|
|
|
|
|
void StopConnectivityWatchLocked(); |
|
|
|
|
|
|
|
|
|
// Cancels watching the connectivity state of the subchannel.
|
|
|
|
|
// Must be called only while there is a connectivity notification
|
|
|
|
|
// pending (i.e., between calling StartOrRenewConnectivityWatchLocked()
|
|
|
|
|
// and the resulting invocation of ProcessConnectivityChangeLocked()).
|
|
|
|
|
// pending (i.e., between calling StartConnectivityWatchLocked() or
|
|
|
|
|
// RenewConnectivityWatchLocked() and the resulting invocation of
|
|
|
|
|
// ProcessConnectivityChangeLocked()).
|
|
|
|
|
// From within ProcessConnectivityChangeLocked(), use
|
|
|
|
|
// StopConnectivityWatchLocked() instead.
|
|
|
|
|
void CancelConnectivityWatchLocked(const char* reason); |
|
|
|
@ -162,12 +167,13 @@ class SubchannelData { |
|
|
|
|
|
|
|
|
|
virtual ~SubchannelData(); |
|
|
|
|
|
|
|
|
|
// After StartOrRenewConnectivityWatchLocked() is called, this method
|
|
|
|
|
// will be invoked when the subchannel's connectivity state changes.
|
|
|
|
|
// After StartConnectivityWatchLocked() or RenewConnectivityWatchLocked()
|
|
|
|
|
// is called, this method will be invoked when the subchannel's connectivity
|
|
|
|
|
// state changes.
|
|
|
|
|
// Implementations can use connectivity_state() to get the new
|
|
|
|
|
// connectivity state.
|
|
|
|
|
// Implementations must invoke either StopConnectivityWatch() or again
|
|
|
|
|
// call StartOrRenewConnectivityWatch() before returning.
|
|
|
|
|
// Implementations must invoke either RenewConnectivityWatchLocked() or
|
|
|
|
|
// StopConnectivityWatchLocked() before returning.
|
|
|
|
|
virtual void ProcessConnectivityChangeLocked(grpc_error* error) GRPC_ABSTRACT; |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
@ -252,6 +258,8 @@ class SubchannelList |
|
|
|
|
|
|
|
|
|
TraceFlag* tracer_; |
|
|
|
|
|
|
|
|
|
grpc_combiner* combiner_; |
|
|
|
|
|
|
|
|
|
// The list of subchannels.
|
|
|
|
|
SubchannelVector subchannels_; |
|
|
|
|
|
|
|
|
@ -313,21 +321,39 @@ void SubchannelData<SubchannelListType, SubchannelDataType>:: |
|
|
|
|
|
|
|
|
|
template <typename SubchannelListType, typename SubchannelDataType> |
|
|
|
|
void SubchannelData<SubchannelListType, |
|
|
|
|
SubchannelDataType>::StartOrRenewConnectivityWatchLocked() { |
|
|
|
|
SubchannelDataType>::StartConnectivityWatchLocked() { |
|
|
|
|
if (subchannel_list_->tracer()->enabled()) { |
|
|
|
|
gpr_log(GPR_DEBUG, |
|
|
|
|
"[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR |
|
|
|
|
" (subchannel %p): requesting connectivity change " |
|
|
|
|
" (subchannel %p): starting watch: requesting connectivity change " |
|
|
|
|
"notification (from %s)", |
|
|
|
|
subchannel_list_->tracer()->name(), subchannel_list_->policy(), |
|
|
|
|
subchannel_list_, Index(), subchannel_list_->num_subchannels(), |
|
|
|
|
subchannel_, |
|
|
|
|
grpc_connectivity_state_name(pending_connectivity_state_unsafe_)); |
|
|
|
|
} |
|
|
|
|
if (!connectivity_notification_pending_) { |
|
|
|
|
subchannel_list()->Ref(DEBUG_LOCATION, "connectivity_watch").release(); |
|
|
|
|
connectivity_notification_pending_ = true; |
|
|
|
|
GPR_ASSERT(!connectivity_notification_pending_); |
|
|
|
|
connectivity_notification_pending_ = true; |
|
|
|
|
subchannel_list()->Ref(DEBUG_LOCATION, "connectivity_watch").release(); |
|
|
|
|
grpc_subchannel_notify_on_state_change( |
|
|
|
|
subchannel_, subchannel_list_->policy()->interested_parties(), |
|
|
|
|
&pending_connectivity_state_unsafe_, &connectivity_changed_closure_); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <typename SubchannelListType, typename SubchannelDataType> |
|
|
|
|
void SubchannelData<SubchannelListType, |
|
|
|
|
SubchannelDataType>::RenewConnectivityWatchLocked() { |
|
|
|
|
if (subchannel_list_->tracer()->enabled()) { |
|
|
|
|
gpr_log(GPR_DEBUG, |
|
|
|
|
"[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR |
|
|
|
|
" (subchannel %p): renewing watch: requesting connectivity change " |
|
|
|
|
"notification (from %s)", |
|
|
|
|
subchannel_list_->tracer()->name(), subchannel_list_->policy(), |
|
|
|
|
subchannel_list_, Index(), subchannel_list_->num_subchannels(), |
|
|
|
|
subchannel_, |
|
|
|
|
grpc_connectivity_state_name(pending_connectivity_state_unsafe_)); |
|
|
|
|
} |
|
|
|
|
GPR_ASSERT(connectivity_notification_pending_); |
|
|
|
|
grpc_subchannel_notify_on_state_change( |
|
|
|
|
subchannel_, subchannel_list_->policy()->interested_parties(), |
|
|
|
|
&pending_connectivity_state_unsafe_, &connectivity_changed_closure_); |
|
|
|
@ -360,6 +386,7 @@ void SubchannelData<SubchannelListType, SubchannelDataType>:: |
|
|
|
|
subchannel_list_, Index(), subchannel_list_->num_subchannels(), |
|
|
|
|
subchannel_, reason); |
|
|
|
|
} |
|
|
|
|
GPR_ASSERT(connectivity_notification_pending_); |
|
|
|
|
grpc_subchannel_notify_on_state_change(subchannel_, nullptr, nullptr, |
|
|
|
|
&connectivity_changed_closure_); |
|
|
|
|
} |
|
|
|
@ -427,7 +454,7 @@ void SubchannelData<SubchannelListType, SubchannelDataType>:: |
|
|
|
|
// Get or release ref to connected subchannel.
|
|
|
|
|
if (!sd->UpdateConnectedSubchannelLocked()) { |
|
|
|
|
// We don't want to report this connectivity state, so renew the watch.
|
|
|
|
|
sd->StartOrRenewConnectivityWatchLocked(); |
|
|
|
|
sd->RenewConnectivityWatchLocked(); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
// Now that we're inside the combiner, copy the pending connectivity
|
|
|
|
@ -462,7 +489,8 @@ SubchannelList<SubchannelListType, SubchannelDataType>::SubchannelList( |
|
|
|
|
const grpc_channel_args& args) |
|
|
|
|
: InternallyRefCountedWithTracing<SubchannelListType>(tracer), |
|
|
|
|
policy_(policy), |
|
|
|
|
tracer_(tracer) { |
|
|
|
|
tracer_(tracer), |
|
|
|
|
combiner_(GRPC_COMBINER_REF(combiner, "subchannel_list")) { |
|
|
|
|
if (tracer_->enabled()) { |
|
|
|
|
gpr_log(GPR_DEBUG, |
|
|
|
|
"[%s %p] Creating subchannel list %p for %" PRIuPTR " subchannels", |
|
|
|
@ -523,6 +551,7 @@ SubchannelList<SubchannelListType, SubchannelDataType>::~SubchannelList() { |
|
|
|
|
gpr_log(GPR_DEBUG, "[%s %p] Destroying subchannel_list %p", tracer_->name(), |
|
|
|
|
policy_, this); |
|
|
|
|
} |
|
|
|
|
GRPC_COMBINER_UNREF(combiner_, "subchannel_list"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <typename SubchannelListType, typename SubchannelDataType> |
|
|
|
|