github.com/cilium/cilium@v1.16.2/pkg/hubble/relay/server/health.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package server
     5  
     6  import (
     7  	"google.golang.org/grpc/health"
     8  	healthpb "google.golang.org/grpc/health/grpc_health_v1"
     9  
    10  	v1 "github.com/cilium/cilium/pkg/hubble/api/v1"
    11  	"github.com/cilium/cilium/pkg/hubble/relay/pool"
    12  	"github.com/cilium/cilium/pkg/inctimer"
    13  	"github.com/cilium/cilium/pkg/time"
    14  )
    15  
    16  type peerStatusReporter interface {
    17  	Status() pool.Status
    18  }
    19  type healthServer struct {
    20  	svc *health.Server
    21  	pm  peerStatusReporter
    22  
    23  	probeInterval time.Duration
    24  	stopChan      chan struct{}
    25  }
    26  
    27  // newHealthServer creates a new health server that monitors health
    28  // using the provided status reporter
    29  func newHealthServer(pm peerStatusReporter, probeInterval time.Duration) *healthServer {
    30  	svc := health.NewServer()
    31  	svc.SetServingStatus("", healthpb.HealthCheckResponse_NOT_SERVING)
    32  	svc.SetServingStatus(v1.ObserverServiceName, healthpb.HealthCheckResponse_NOT_SERVING)
    33  	hs := &healthServer{
    34  		svc:           svc,
    35  		pm:            pm,
    36  		probeInterval: probeInterval,
    37  		stopChan:      make(chan struct{}),
    38  	}
    39  	return hs
    40  }
    41  
    42  // start starts the health server.
    43  func (hs healthServer) start() {
    44  	check := func() {
    45  		st := hs.pm.Status()
    46  		if st.PeerServiceConnected && st.AvailablePeers > 0 {
    47  			hs.svc.SetServingStatus("", healthpb.HealthCheckResponse_SERVING)
    48  			hs.svc.SetServingStatus(v1.ObserverServiceName, healthpb.HealthCheckResponse_SERVING)
    49  		} else {
    50  			hs.svc.SetServingStatus("", healthpb.HealthCheckResponse_NOT_SERVING)
    51  			hs.svc.SetServingStatus(v1.ObserverServiceName, healthpb.HealthCheckResponse_NOT_SERVING)
    52  		}
    53  	}
    54  	go func() {
    55  		connTimer, connTimerDone := inctimer.New()
    56  		defer connTimerDone()
    57  		check()
    58  		for {
    59  			select {
    60  			case <-hs.stopChan:
    61  				return
    62  			case <-connTimer.After(hs.probeInterval):
    63  				check()
    64  			}
    65  		}
    66  	}()
    67  }
    68  
    69  // stop stops the health server.
    70  func (hs healthServer) stop() {
    71  	close(hs.stopChan)
    72  }