// makeAPIServiceAvailableHealthzCheck returns a healthz check that returns healthy
// once all of the specified services have been observed to be available at least once.
516480
func makeAPIServiceAvailableHealthzCheck(name string, apiServices []*apiregistration.APIService, apiServiceInformer informers.APIServiceInformer) healthz.HealthzChecker {
	// Track the auto-registered API services that have not been observed to be available yet
	pendingServiceNamesLock := &sync.RWMutex{}
	pendingServiceNames := sets.NewString()
	for _, service := range apiServices {
		pendingServiceNames.Insert(service.Name)
	}

	// When an APIService in the list is seen as available, remove it from the pending list
	handleAPIServiceChange := func(service *apiregistration.APIService) {
		pendingServiceNamesLock.Lock()
		defer pendingServiceNamesLock.Unlock()
		if !pendingServiceNames.Has(service.Name) {
			return
		}
		if apiregistration.IsAPIServiceConditionTrue(service, apiregistration.Available) {
			pendingServiceNames.Delete(service.Name)
		}
	}

	// Watch add/update events for APIServices
	apiServiceInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
		AddFunc:    func(obj interface{}) { handleAPIServiceChange(obj.(*apiregistration.APIService)) },
		UpdateFunc: func(old, new interface{}) { handleAPIServiceChange(new.(*apiregistration.APIService)) },
	})

	// Don't return healthy until the pending list is empty
	return healthz.NamedCheck(name, func(r *http.Request) error {
		pendingServiceNamesLock.RLock()
		defer pendingServiceNamesLock.RUnlock()
		if pendingServiceNames.Len() > 0 {
			return fmt.Errorf("missing APIService: %v", pendingServiceNames.List())
		}
		return nil
	})
}
710302
func (c *Controller) storageHealthCheck() (chan struct{}, error) {
	gone := make(chan struct{})
	mounts, err := mount.GetMounts()
	if err != nil {
		return nil, err
	}
	nfsMountPoints := []string{}
	for _, minfo := range mounts {
		if strings.HasPrefix(minfo.Fstype, "nfs") {
			nfsMountPoints = append(nfsMountPoints, minfo.Mountpoint)
		}
	}
	if len(nfsMountPoints) > 0 {
		// Start polling
		go func() {
			for {
				for _, mp := range nfsMountPoints {
					if utils.IsNFSMountStale(mp) {
						close(gone)
						return
					}
				}
				<-time.After(5 * time.Second)
			}
		}()
	}
	return gone, nil
}
602791
func NeedsHealthCheck(service *api.Service) bool {
	if service.Spec.Type != api.ServiceTypeLoadBalancer {
		return false
	}
	return RequestsOnlyLocalTraffic(service)
}
307772
func GetServiceHealthCheckPathPort(service *v1.Service) (string, int32) {
	if !NeedsHealthCheck(service) {
		return "", 0
	}
	port := service.Spec.HealthCheckNodePort
	if port == 0 {
		return "", 0
	}
	return "/healthz", port
}
1140644
func (g *Cloud) ListHTTPHealthChecks() ([]*compute.HttpHealthCheck, error) {
	ctx, cancel := cloud.ContextWithCallTimeout()
	defer cancel()

	mc := newHealthcheckMetricContext("list_legacy")
	v, err := g.c.HttpHealthChecks().List(ctx, filter.None)
	return v, mc.Observe(err)
}
940505
func healthzServer(conn *grpc.ClientConn) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "text/plain")
		if s := conn.GetState(); s != connectivity.Ready {
			http.Error(w, fmt.Sprintf("grpc server is %s", s), http.StatusBadGateway)
			return
		}
		fmt.Fprintln(w, "ok")
	}
}
682879
func (c *Client) healthchecker() {
	c.mu.RLock()
	timeout := c.healthcheckTimeout
	interval := c.healthcheckInterval
	c.mu.RUnlock()

	ticker := time.NewTicker(interval)
	defer ticker.Stop()

	for {
		select {
		case <-c.healthcheckStop:
			// we are asked to stop, so we signal back that we're stopping now
			c.healthcheckStop <- true
			return
		case <-ticker.C:
			c.healthcheck(context.Background(), timeout, false)
		}
	}
}
1085135
func (t *toolbox) AddHealthCheck(hc HealthChecker) {
	t.healthCheckJobs = append(t.healthCheckJobs, &healthCheck{
		HealthChecker: hc,
	})
}
1177846
func (a *Client) GetEndpointIDHealthz(params *GetEndpointIDHealthzParams) (*GetEndpointIDHealthzOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewGetEndpointIDHealthzParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "GetEndpointIDHealthz",
		Method:             "GET",
		PathPattern:        "/endpoint/{id}/healthz",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &GetEndpointIDHealthzReader{formats: a.formats},
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*GetEndpointIDHealthzOK), nil

}
1129405
func ServeHealthCheck(mux *http.ServeMux, f func() error) {
	mux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
		if err := f(); err != nil {
			w.WriteHeader(http.StatusServiceUnavailable)
			log.Errorln(w, err)
		} else {
			fmt.Fprintln(w, "ok")
		}
	})
}
431112
func (prod *SimpleProducer) AddHealthCheckAt(path string, callback thealthcheck.CallbackFunc) {
	thealthcheck.AddEndpoint("/"+prod.GetID()+path, callback)
}
560313
func (s *LoadBalancerService) NewCreateLBHealthCheckPolicyParams(lbruleid string) *CreateLBHealthCheckPolicyParams {
	p := &CreateLBHealthCheckPolicyParams{}
	p.p = make(map[string]interface{})
	p.p["lbruleid"] = lbruleid
	return p
}
1338013
func supportsNodesHealthCheck(nodes []*v1.Node) bool {
	for _, node := range nodes {
		if !isAtLeastMinNodesHealthCheckVersion(node.Status.NodeInfo.KubeProxyVersion) {
			return false
		}
	}
	return true
}
1014645
func (router *SimpleRouter) AddHealthCheckAt(path string, callback thealthcheck.CallbackFunc) {
	thealthcheck.AddEndpoint("/"+router.GetID()+path, callback)
}
1333922
func (di *DriverInfo) MergeHealthCheck(other *DriverInfo) {
	di.Healthy = other.Healthy
	di.HealthDescription = other.HealthDescription
	di.UpdateTime = other.UpdateTime
}
1336191
func (a *availablePlugin) healthCheckFailed() {
	log.WithFields(log.Fields{
		"_module":     "control-aplugin",
		"block":       "check-health",
		"plugin_name": a,
	}).Warning("heartbeat missed")
	a.failedHealthChecks++
	if a.failedHealthChecks >= DefaultHealthCheckFailureLimit {
		log.WithFields(log.Fields{
			"_module":     "control-aplugin",
			"block":       "check-health",
			"plugin_name": a,
		}).Warning("heartbeat failed")
		pde := &control_event.DeadAvailablePluginEvent{
			Name:    a.name,
			Version: a.version,
			Type:    int(a.pluginType),
			Key:     a.key,
			Id:      a.ID(),
			String:  a.String(),
		}
		defer a.emitter.Emit(pde)
	}
	hcfe := &control_event.HealthCheckFailedEvent{
		Name:    a.name,
		Version: a.version,
		Type:    int(a.pluginType),
	}
	defer a.emitter.Emit(hcfe)
}
439250
func validateHealthCheck(hc *api.HealthConfig) error {
	if hc == nil {
		return nil
	}

	if hc.Interval != nil {
		interval, err := gogotypes.DurationFromProto(hc.Interval)
		if err != nil {
			return err
		}
		if interval != 0 && interval < minimumDuration {
			return status.Errorf(codes.InvalidArgument, "ContainerSpec: Interval in HealthConfig cannot be less than %s", minimumDuration)
		}
	}

	if hc.Timeout != nil {
		timeout, err := gogotypes.DurationFromProto(hc.Timeout)
		if err != nil {
			return err
		}
		if timeout != 0 && timeout < minimumDuration {
			return status.Errorf(codes.InvalidArgument, "ContainerSpec: Timeout in HealthConfig cannot be less than %s", minimumDuration)
		}
	}

	if hc.StartPeriod != nil {
		sp, err := gogotypes.DurationFromProto(hc.StartPeriod)
		if err != nil {
			return err
		}
		if sp != 0 && sp < minimumDuration {
			return status.Errorf(codes.InvalidArgument, "ContainerSpec: StartPeriod in HealthConfig cannot be less than %s", minimumDuration)
		}
	}

	if hc.Retries < 0 {
		return status.Errorf(codes.InvalidArgument, "ContainerSpec: Retries in HealthConfig cannot be negative")
	}

	return nil
}