93 lines
2.0 KiB
Go
93 lines
2.0 KiB
Go
package model
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/derailed/k9s/internal"
|
|
"github.com/derailed/k9s/internal/client"
|
|
"github.com/derailed/k9s/internal/dao"
|
|
"github.com/derailed/k9s/internal/health"
|
|
)
|
|
|
|
// PulseListener represents a health model listener.
|
|
type PulseListener interface {
|
|
// PulseChanged notifies the model data changed.
|
|
PulseChanged(*health.Check)
|
|
|
|
// PulseFailed notifies the health check failed.
|
|
PulseFailed(error)
|
|
|
|
// MetricsChanged update metrics time series.
|
|
MetricsChanged(dao.TimeSeries)
|
|
}
|
|
|
|
// Pulse tracks multiple resources health.
|
|
type Pulse struct {
|
|
gvr *client.GVR
|
|
namespace string
|
|
listeners []PulseListener
|
|
health *PulseHealth
|
|
}
|
|
|
|
// NewPulse returns a new pulse.
|
|
func NewPulse(gvr *client.GVR) *Pulse {
|
|
return &Pulse{
|
|
gvr: gvr,
|
|
}
|
|
}
|
|
|
|
type HealthChan chan HealthPoint
|
|
|
|
// Watch monitors pulses.
|
|
func (p *Pulse) Watch(ctx context.Context) (HealthChan, dao.MetricsChan, error) {
|
|
f, ok := ctx.Value(internal.KeyFactory).(dao.Factory)
|
|
if !ok {
|
|
return nil, nil, fmt.Errorf("expected Factory in context but got %T", ctx.Value(internal.KeyFactory))
|
|
}
|
|
if p.health == nil {
|
|
p.health = NewPulseHealth(f)
|
|
}
|
|
|
|
healthChan := p.health.Watch(ctx, p.namespace)
|
|
metricsChan := dao.DialRecorder(f.Client()).Watch(ctx, p.namespace)
|
|
|
|
return healthChan, metricsChan, nil
|
|
}
|
|
|
|
// Refresh update the model now.
|
|
func (*Pulse) Refresh(context.Context) {}
|
|
|
|
// GetNamespace returns the model namespace.
|
|
func (p *Pulse) GetNamespace() string {
|
|
return p.namespace
|
|
}
|
|
|
|
// SetNamespace sets up model namespace.
|
|
func (p *Pulse) SetNamespace(ns string) {
|
|
if client.IsAllNamespaces(ns) {
|
|
ns = client.BlankNamespace
|
|
}
|
|
p.namespace = ns
|
|
}
|
|
|
|
// AddListener adds a listener.
|
|
func (p *Pulse) AddListener(l PulseListener) {
|
|
p.listeners = append(p.listeners, l)
|
|
}
|
|
|
|
// RemoveListener delete a listener.
|
|
func (p *Pulse) RemoveListener(l PulseListener) {
|
|
victim := -1
|
|
for i, lis := range p.listeners {
|
|
if lis == l {
|
|
victim = i
|
|
break
|
|
}
|
|
}
|
|
|
|
if victim >= 0 {
|
|
p.listeners = append(p.listeners[:victim], p.listeners[victim+1:]...)
|
|
}
|
|
}
|