Path: blob/main/component/prometheus/operator/common/component.go
5295 views
package common12import (3"context"4"sync"5"time"67"github.com/go-kit/log/level"8"github.com/grafana/agent/component"9"github.com/grafana/agent/component/prometheus/operator"10)1112type Component struct {13mut sync.Mutex14config *operator.Arguments15manager *crdManager1617onUpdate chan struct{}18opts component.Options19healthMut sync.RWMutex20health component.Health2122kind string23}2425func New(o component.Options, args component.Arguments, kind string) (*Component, error) {26c := &Component{27opts: o,28onUpdate: make(chan struct{}, 1),29kind: kind,30}31return c, c.Update(args)32}3334func (c *Component) CurrentHealth() component.Health {35c.healthMut.RLock()36defer c.healthMut.RUnlock()37return c.health38}3940// Run implements component.Component.41func (c *Component) Run(ctx context.Context) error {42// innerCtx gets passed to things we create, so we can restart everything anytime we get an update.43// Ideally, this component has very little dynamic config, and won't have frequent updates.44var innerCtx context.Context45// cancel is the func we use to trigger a stop to all downstream processors we create46var cancel func()47defer func() {48if cancel != nil {49cancel()50}51}()5253c.reportHealth(nil)54errChan := make(chan error, 1)55for {56select {57case <-ctx.Done():58if cancel != nil {59cancel()60}61return nil62case err := <-errChan:63c.reportHealth(err)64case <-c.onUpdate:65if cancel != nil {66cancel()67}68innerCtx, cancel = context.WithCancel(ctx)69c.mut.Lock()70componentCfg := c.config71manager := newCrdManager(c.opts, c.opts.Logger, componentCfg, c.kind)72c.manager = manager73c.mut.Unlock()74go func() {75if err := manager.Run(innerCtx); err != nil {76level.Error(c.opts.Logger).Log("msg", "error running crd manager", "err", err)77errChan <- err78}79}()80}81}82}8384// Update implements component.Component.85func (c *Component) Update(args component.Arguments) error {86// TODO(jcreixell): Initialize manager here so we can return errors back early to the caller.87// See https://github.com/grafana/agent/pull/2688#discussion_r115238442588c.mut.Lock()89cfg := args.(operator.Arguments)90c.config = &cfg91c.mut.Unlock()92select {93case c.onUpdate <- struct{}{}:94default:95}96return nil97}9899// DebugInfo returns debug information for this component.100func (c *Component) DebugInfo() interface{} {101return c.manager.DebugInfo()102}103104func (c *Component) reportHealth(err error) {105c.healthMut.Lock()106defer c.healthMut.Unlock()107108if err != nil {109c.health = component.Health{110Health: component.HealthTypeUnhealthy,111Message: err.Error(),112UpdateTime: time.Now(),113}114return115} else {116c.health = component.Health{117Health: component.HealthTypeHealthy,118UpdateTime: time.Now(),119}120}121}122123124