xds: Put channel in TRANSIENT_FAILURE when CDS resource is removed.

pull/22926/head
Mark D. Roth 5 years ago
parent 729af3a43d
commit 0db28f7eaf
  1. 11
      src/core/ext/filters/client_channel/lb_policy/xds/cds.cc
  2. 11
      src/core/ext/filters/client_channel/lb_policy/xds/eds.cc
  3. 11
      test/cpp/end2end/xds_end2end_test.cc

@ -215,14 +215,10 @@ void CdsLb::ClusterWatcher::OnError(grpc_error* error) {
} }
void CdsLb::ClusterWatcher::OnResourceDoesNotExist() { void CdsLb::ClusterWatcher::OnResourceDoesNotExist() {
gpr_log(GPR_ERROR, "[cdslb %p] CDS resource for %s does not exist", gpr_log(GPR_ERROR,
"[cdslb %p] CDS resource for %s does not exist -- reporting "
"TRANSIENT_FAILURE",
parent_.get(), parent_->config_->cluster().c_str()); parent_.get(), parent_->config_->cluster().c_str());
// Go into TRANSIENT_FAILURE if we have not yet created the child
// policy (i.e., we have not yet received data from xds). Otherwise,
// we keep running with the data we had previously.
// TODO(roth): Once traffic splitting is implemented, this should be
// fixed to report TRANSIENT_FAILURE unconditionally.
if (parent_->child_policy_ == nullptr) {
parent_->channel_control_helper()->UpdateState( parent_->channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_CHANNEL_TRANSIENT_FAILURE,
absl::make_unique<TransientFailurePicker>( absl::make_unique<TransientFailurePicker>(
@ -231,7 +227,6 @@ void CdsLb::ClusterWatcher::OnResourceDoesNotExist() {
"\" does not exist") "\" does not exist")
.c_str()))); .c_str())));
} }
}
// //
// CdsLb::Helper // CdsLb::Helper

@ -342,21 +342,16 @@ class EdsLb::EndpointWatcher : public XdsClient::EndpointWatcherInterface {
} }
void OnResourceDoesNotExist() override { void OnResourceDoesNotExist() override {
gpr_log(GPR_ERROR, "[edslb %p] EDS resource does not exist", gpr_log(
GPR_ERROR,
"[edslb %p] EDS resource does not exist -- reporting TRANSIENT_FAILURE",
eds_policy_.get()); eds_policy_.get());
// Go into TRANSIENT_FAILURE if we have not yet created the child
// policy (i.e., we have not yet received data from xds). Otherwise,
// we keep running with the data we had previously.
// TODO(roth): Once traffic splitting is implemented, this should be
// fixed to report TRANSIENT_FAILURE unconditionally.
if (eds_policy_->child_policy_ == nullptr) {
eds_policy_->channel_control_helper()->UpdateState( eds_policy_->channel_control_helper()->UpdateState(
GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_CHANNEL_TRANSIENT_FAILURE,
absl::make_unique<TransientFailurePicker>( absl::make_unique<TransientFailurePicker>(
GRPC_ERROR_CREATE_FROM_STATIC_STRING( GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"EDS resource does not exist"))); "EDS resource does not exist")));
} }
}
private: private:
RefCountedPtr<EdsLb> eds_policy_; RefCountedPtr<EdsLb> eds_policy_;

@ -1908,7 +1908,7 @@ TEST_P(XdsResolverOnlyTest, ListenerRemoved) {
AdsServiceImpl::BuildEdsResource(args)); AdsServiceImpl::BuildEdsResource(args));
// We need to wait for all backends to come online. // We need to wait for all backends to come online.
WaitForAllBackends(); WaitForAllBackends();
// Unset CDS resource. // Unset LDS resource.
balancers_[0]->ads_service()->UnsetResource(kLdsTypeUrl, balancers_[0]->ads_service()->UnsetResource(kLdsTypeUrl,
kDefaultResourceName); kDefaultResourceName);
// Wait for RPCs to start failing. // Wait for RPCs to start failing.
@ -1921,7 +1921,7 @@ TEST_P(XdsResolverOnlyTest, ListenerRemoved) {
AdsServiceImpl::ResponseState::ACKED); AdsServiceImpl::ResponseState::ACKED);
} }
// Tests that things keep workng if the cluster resource disappears. // Tests that we go into TRANSIENT_FAILURE if the Cluster disappears.
TEST_P(XdsResolverOnlyTest, ClusterRemoved) { TEST_P(XdsResolverOnlyTest, ClusterRemoved) {
SetNextResolution({}); SetNextResolution({});
SetNextResolutionForLbChannelAllBalancers(); SetNextResolutionForLbChannelAllBalancers();
@ -1935,8 +1935,11 @@ TEST_P(XdsResolverOnlyTest, ClusterRemoved) {
// Unset CDS resource. // Unset CDS resource.
balancers_[0]->ads_service()->UnsetResource(kCdsTypeUrl, balancers_[0]->ads_service()->UnsetResource(kCdsTypeUrl,
kDefaultResourceName); kDefaultResourceName);
// Make sure RPCs are still succeeding. // Wait for RPCs to start failing.
CheckRpcSendOk(100 * num_backends_); do {
} while (SendRpc(RpcOptions(), nullptr).ok());
// Make sure RPCs are still failing.
CheckRpcSendFailure(1000);
// Make sure we ACK'ed the update. // Make sure we ACK'ed the update.
EXPECT_EQ(balancers_[0]->ads_service()->cds_response_state().state, EXPECT_EQ(balancers_[0]->ads_service()->cds_response_state().state,
AdsServiceImpl::ResponseState::ACKED); AdsServiceImpl::ResponseState::ACKED);

Loading…
Cancel
Save