| 
					
				 | 
			
			
				@@ -47,12 +47,14 @@ HealthCheckClient::HealthCheckClient( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const char* service_name, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     RefCountedPtr<ConnectedSubchannel> connected_subchannel, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     grpc_pollset_set* interested_parties, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    RefCountedPtr<channelz::SubchannelNode> channelz_node) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    RefCountedPtr<channelz::SubchannelNode> channelz_node, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    RefCountedPtr<ConnectivityStateWatcherInterface> watcher) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     : InternallyRefCounted<HealthCheckClient>(&grpc_health_check_client_trace), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       service_name_(service_name), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       connected_subchannel_(std::move(connected_subchannel)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       interested_parties_(interested_parties), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       channelz_node_(std::move(channelz_node)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      watcher_(std::move(watcher)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       retry_backoff_( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           BackOff::Options() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               .set_initial_backoff( 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -73,43 +75,21 @@ HealthCheckClient::~HealthCheckClient() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (GRPC_TRACE_FLAG_ENABLED(grpc_health_check_client_trace)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     gpr_log(GPR_INFO, "destroying HealthCheckClient %p", this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  GRPC_ERROR_UNREF(error_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-void HealthCheckClient::NotifyOnHealthChange(grpc_connectivity_state* state, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                             grpc_closure* closure) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  MutexLock lock(&mu_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  GPR_ASSERT(notify_state_ == nullptr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (*state != state_) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    *state = state_; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    GRPC_CLOSURE_SCHED(closure, GRPC_ERROR_REF(error_)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  notify_state_ = state; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  on_health_changed_ = closure; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void HealthCheckClient::SetHealthStatus(grpc_connectivity_state state, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                        grpc_error* error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                        const char* reason) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   MutexLock lock(&mu_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  SetHealthStatusLocked(state, error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SetHealthStatusLocked(state, reason); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void HealthCheckClient::SetHealthStatusLocked(grpc_connectivity_state state, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                              grpc_error* error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                              const char* reason) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (GRPC_TRACE_FLAG_ENABLED(grpc_health_check_client_trace)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    gpr_log(GPR_INFO, "HealthCheckClient %p: setting state=%d error=%s", this, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            state, grpc_error_string(error)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (notify_state_ != nullptr && *notify_state_ != state) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    *notify_state_ = state; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    notify_state_ = nullptr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    GRPC_CLOSURE_SCHED(on_health_changed_, GRPC_ERROR_REF(error)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    on_health_changed_ = nullptr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    gpr_log(GPR_INFO, "HealthCheckClient %p: setting state=%s reason=%s", this, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ConnectivityStateName(state), reason); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  state_ = state; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  GRPC_ERROR_UNREF(error_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  error_ = error; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (watcher_ != nullptr) watcher_->Notify(state); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void HealthCheckClient::Orphan() { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -118,13 +98,8 @@ void HealthCheckClient::Orphan() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     MutexLock lock(&mu_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (on_health_changed_ != nullptr) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      *notify_state_ = GRPC_CHANNEL_SHUTDOWN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      notify_state_ = nullptr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      GRPC_CLOSURE_SCHED(on_health_changed_, GRPC_ERROR_NONE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      on_health_changed_ = nullptr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     shutting_down_ = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    watcher_.reset(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     call_state_.reset(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (retry_timer_callback_pending_) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       grpc_timer_cancel(&retry_timer_); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -141,7 +116,7 @@ void HealthCheckClient::StartCall() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void HealthCheckClient::StartCallLocked() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (shutting_down_) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   GPR_ASSERT(call_state_ == nullptr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  SetHealthStatusLocked(GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SetHealthStatusLocked(GRPC_CHANNEL_CONNECTING, "starting health watch"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   call_state_ = MakeOrphanable<CallState>(Ref(), interested_parties_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (GRPC_TRACE_FLAG_ENABLED(grpc_health_check_client_trace)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     gpr_log(GPR_INFO, "HealthCheckClient %p: created CallState %p", this, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -152,10 +127,8 @@ void HealthCheckClient::StartCallLocked() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void HealthCheckClient::StartRetryTimer() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   MutexLock lock(&mu_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  SetHealthStatusLocked( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      GRPC_CHANNEL_TRANSIENT_FAILURE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      GRPC_ERROR_CREATE_FROM_STATIC_STRING( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          "health check call failed; will retry after backoff")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SetHealthStatusLocked(GRPC_CHANNEL_TRANSIENT_FAILURE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        "health check call failed; will retry after backoff"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_millis next_try = retry_backoff_.NextAttemptTime(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (GRPC_TRACE_FLAG_ENABLED(grpc_health_check_client_trace)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     gpr_log(GPR_INFO, "HealthCheckClient %p: health check call lost...", this); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -489,10 +462,10 @@ void HealthCheckClient::CallState::DoneReadingRecvMessage(grpc_error* error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const bool healthy = DecodeResponse(&recv_message_buffer_, &error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const grpc_connectivity_state state = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       healthy ? GRPC_CHANNEL_READY : GRPC_CHANNEL_TRANSIENT_FAILURE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (error == GRPC_ERROR_NONE && !healthy) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("backend unhealthy"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  health_check_client_->SetHealthStatus(state, error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const char* reason = error == GRPC_ERROR_NONE && !healthy 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                           ? "backend unhealthy" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                           : grpc_error_string(error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  health_check_client_->SetHealthStatus(state, reason); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   seen_response_.Store(true, MemoryOrder::RELEASE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_slice_buffer_destroy_internal(&recv_message_buffer_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // Start another recv_message batch. 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -603,7 +576,7 @@ void HealthCheckClient::CallState::RecvTrailingMetadataReady( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           grpc_slice_from_static_string(kErrorMessage)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     self->health_check_client_->SetHealthStatus(GRPC_CHANNEL_READY, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                                GRPC_ERROR_NONE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                                kErrorMessage); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     retry = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   self->CallEnded(retry); 
			 |