kubeprobes/probe_function.go
Piotr Icikowski 9dd25ff024
All checks were successful
ci/woodpecker/pr/test Pipeline was successful
feat(probes)!: rewrite probes logic with named probes
- `ProbeFunction` is now an interface for easier use
- `ProbeFunction`s can be auto-updated with specified update interval
- `StatefulProbes` changed into `ManualProbes` and implement `ProbeFunction` interface
- `ManualProbes` allows for marking probe as unhealthy with custom cause
- handlers now return JSON response with failed probes
- handler's response can be set to verbose via `Kubeprobes` option or via `?v` request param

BREAKING CHANGE: type definitions were replaced with more robust implementation.
2024-03-03 00:00:57 +01:00

82 lines
1.5 KiB
Go

package kubeprobes
import (
"sync"
"time"
)
// ProbeFunction is a wrapper for a function that determines whether
// the given metric may be marked as correctly functioning.
// It not, the error should be returned.
type ProbeFunction interface {
name() string
status() error
}
type probeFunction struct {
probeName string
probeFunc func() error
refreshInterval time.Duration
mux sync.RWMutex
err error
}
// NewProbeFunction returns new instance of [ProbeFunction].
//
// If update interval is less or equal zero then probe is updated only
// on its creation and remains in the same state forever.
func NewProbeFunction(
name string,
fn func() error,
updateInterval time.Duration,
) (ProbeFunction, error) {
if name == "" {
return nil, errProbeNameEmpty
}
pf := &probeFunction{
probeName: name,
probeFunc: fn,
refreshInterval: updateInterval,
mux: sync.RWMutex{},
}
defer pf.autoUpdate()
return pf, nil
}
// name implements ProbeFunction.
func (pf *probeFunction) name() string {
return pf.probeName
}
// status implements ProbeFunction.
func (pf *probeFunction) status() error {
pf.mux.RLock()
defer pf.mux.RUnlock()
return pf.err
}
func (pf *probeFunction) update() {
err := pf.probeFunc()
pf.mux.Lock()
pf.err = err
pf.mux.Unlock()
}
func (pf *probeFunction) autoUpdate() {
pf.update()
if pf.refreshInterval <= 0 {
return
}
go func() {
ticker := time.NewTicker(pf.refreshInterval)
for {
<-ticker.C
pf.update()
}
}()
}