Skip to content

Commit

Permalink
xds enter fallback mode as long as no child policy is ready
Browse files Browse the repository at this point in the history
  • Loading branch information
AspirinSJL committed May 19, 2019
1 parent 50e16f6 commit 98461b0
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 7 deletions.
13 changes: 6 additions & 7 deletions src/core/ext/filters/client_channel/lb_policy/xds/xds.cc
Original file line number Diff line number Diff line change
Expand Up @@ -493,9 +493,8 @@ class XdsLb : public LoadBalancingPolicy {
// 1. The fallback timer fires, we enter fallback mode.
// 2. Before the fallback timer fires, the LB channel becomes
// TRANSIENT_FAILURE or the LB call fails, we enter fallback mode.
// 3. Before the fallback timer fires, we receive a response from the
// balancer, we cancel the fallback timer and use the response to update the
// locality map.
// 3. Before the fallback timer fires, if any child policy in the locality map
// becomes READY, we cancel the fallback timer.
bool fallback_at_startup_checks_pending_ = false;
// Timeout in milliseconds for before using fallback backend addresses.
// 0 means not using fallback.
Expand Down Expand Up @@ -1197,9 +1196,6 @@ void XdsLb::BalancerChannelState::BalancerCallState::
xds_grpclb_destroy_serverlist(
xdslb_policy->locality_serverlist_[0]->serverlist);
} else {
// This is the first serverlist we've received, don't enter fallback
// mode.
xdslb_policy->MaybeCancelFallbackAtStartupChecks();
// Initialize locality serverlist, currently the list only handles
// one child.
xdslb_policy->locality_serverlist_.emplace_back(
Expand Down Expand Up @@ -2046,7 +2042,10 @@ void XdsLb::LocalityMap::LocalityEntry::Helper::UpdateState(
return;
}
// At this point, child_ must be the current child policy.
if (state == GRPC_CHANNEL_READY) entry_->parent_->MaybeExitFallbackMode();
if (state == GRPC_CHANNEL_READY) {
entry_->parent_->MaybeCancelFallbackAtStartupChecks();
entry_->parent_->MaybeExitFallbackMode();
}
// If we are in fallback mode, ignore update request from the child policy.
if (entry_->parent_->fallback_policy_ != nullptr) return;
GPR_ASSERT(entry_->parent_->lb_chand_ != nullptr);
Expand Down
16 changes: 16 additions & 0 deletions test/cpp/end2end/xds_end2end_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,22 @@ TEST_F(SingleBalancerTest, FallbackEarlyWhenBalancerCallFails) {
/* wait_for_ready */ false);
}

TEST_F(SingleBalancerTest, FallbackIfResponseReceivedButChildNotReady) {
const int kFallbackTimeoutMs = 500 * grpc_test_slowdown_factor();
ResetStub(kFallbackTimeoutMs);
SetNextResolution({backends_[0]->port_}, kDefaultServiceConfig_.c_str());
SetNextResolutionForLbChannelAllBalancers();
// Send a serverlist that only contains an unreachable backend before fallback
// timeout.
ScheduleResponseForBalancer(0,
BalancerServiceImpl::BuildResponseForBackends(
{grpc_pick_unused_port_or_die()}, {}),
0);
// Because no child policy is ready before fallback timeout, we enter fallback
// mode.
WaitForBackend(0);
}

TEST_F(SingleBalancerTest, FallbackModeIsExitedWhenBalancerSaysToDropAllCalls) {
// Return an unreachable balancer and one fallback backend.
SetNextResolution({backends_[0]->port_}, kDefaultServiceConfig_.c_str());
Expand Down

0 comments on commit 98461b0

Please sign in to comment.