github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/observability/probe/prober.go (about)

     1  // Copyright 2022 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package probe
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  )
     9  
    10  // LivenessProber is an interface for probing targets that implement liveness
    11  // probe support.
    12  type LivenessProber interface {
    13  	// LivenessProbe returns the Prober to use for Liveness probes.
    14  	LivenessProbe() Prober
    15  }
    16  
    17  // Prober represents something that can be probed and return a true or false
    18  // statement about it's success or optionally error if it's not able to
    19  // assertain a probes success.
    20  type Prober interface {
    21  	// Probe this thing and return true or false as to it's success.
    22  	// Alternatively an error can be raise when making this decision in which
    23  	// case the probe should be considered a failed with extra context through
    24  	// the error.
    25  	Probe() (bool, error)
    26  }
    27  
    28  // ProberProvider is implemented by entities that wish to controbute probes to
    29  // the overall applications probe support.
    30  type ProbeProvider interface {
    31  	SupportedProbes() SupportedProbes
    32  }
    33  
    34  type probeProvider struct {
    35  	Probes SupportedProbes
    36  }
    37  
    38  // ProbeType is an alias type to describe the type of probe in question.
    39  type ProbeType string
    40  
    41  // SupportedProbes provides a map of supported probes to the caller referenced
    42  // on ProbeType.
    43  type SupportedProbes map[ProbeType]Prober
    44  
    45  const (
    46  	// ProbeLiveness represents a liveness probe
    47  	ProbeLiveness = ProbeType("liveness")
    48  
    49  	// ProbeLiveness represents a readiness probe
    50  	ProbeReadiness = ProbeType("readiness")
    51  
    52  	// ProbeLiveness represents a startup probe
    53  	ProbeStartup = ProbeType("startup")
    54  )
    55  
    56  // ProberFn is a convenience wrapper to transform a function into a Prober
    57  // interface
    58  type ProberFn func() (bool, error)
    59  
    60  var (
    61  	// Failure is a convenience wrapper probe that always evaluates to failure.
    62  	Failure Prober = ProberFn(func() (bool, error) {
    63  		return false, nil
    64  	})
    65  
    66  	// NotImplemented is a convenience wrapper for supplying a probe that
    67  	// indiciates to it's caller that it's not implemented. Resulting error
    68  	// should hold true with errors.IsNotImplemented(err)
    69  	NotImplemented Prober = ProberFn(func() (bool, error) {
    70  		return false, errors.NotImplementedf("probe not implemented")
    71  	})
    72  
    73  	// Success is a convenience wrapper probe that always evaluates to success.
    74  	Success Prober = ProberFn(func() (bool, error) {
    75  		return true, nil
    76  	})
    77  )
    78  
    79  // LivenessProvider is a utility function for returning a ProbeProvider for the
    80  // provided liveness probe.
    81  func LivenessProvider(probe Prober) ProbeProvider {
    82  	return Provider(SupportedProbes{
    83  		ProbeLiveness: probe,
    84  	})
    85  }
    86  
    87  // ReadinessProvider is a utility function for returning a ProbeProvider for the
    88  // provided readiness probe.
    89  func ReadinessProvider(probe Prober) ProbeProvider {
    90  	return Provider(SupportedProbes{
    91  		ProbeReadiness: probe,
    92  	})
    93  }
    94  
    95  // Probe implements Prober interface
    96  func (p ProberFn) Probe() (bool, error) {
    97  	return p()
    98  }
    99  
   100  // Provider is a utility function for returning a ProbeProvider based on the
   101  // SupportedProbes passed in.
   102  func Provider(supported SupportedProbes) ProbeProvider {
   103  	return &probeProvider{
   104  		Probes: supported,
   105  	}
   106  }
   107  
   108  // Supports indicates if the supplied ProbeType is in the map of supported
   109  // probe types.
   110  func (s SupportedProbes) Supports(t ProbeType) bool {
   111  	_, has := s[t]
   112  	return has
   113  }
   114  
   115  // SupportedProbes implements ProbeProvider interface.
   116  func (p *probeProvider) SupportedProbes() SupportedProbes {
   117  	return p.Probes
   118  }