github.com/netdata/go.d.plugin@v0.58.1/agent/filestatus/manager.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package filestatus
     4  
     5  import (
     6  	"context"
     7  	"log/slog"
     8  	"os"
     9  	"time"
    10  
    11  	"github.com/netdata/go.d.plugin/agent/confgroup"
    12  	"github.com/netdata/go.d.plugin/logger"
    13  )
    14  
    15  func NewManager(path string) *Manager {
    16  	return &Manager{
    17  		Logger: logger.New().With(
    18  			slog.String("component", "filestatus manager"),
    19  		),
    20  		path:       path,
    21  		store:      &Store{},
    22  		flushEvery: time.Second * 5,
    23  		flushCh:    make(chan struct{}, 1),
    24  	}
    25  }
    26  
    27  type Manager struct {
    28  	*logger.Logger
    29  
    30  	path string
    31  
    32  	store *Store
    33  
    34  	flushEvery time.Duration
    35  	flushCh    chan struct{}
    36  }
    37  
    38  func (m *Manager) Run(ctx context.Context) {
    39  	m.Info("instance is started")
    40  	defer func() { m.Info("instance is stopped") }()
    41  
    42  	tk := time.NewTicker(m.flushEvery)
    43  	defer tk.Stop()
    44  	defer m.flush()
    45  
    46  	for {
    47  		select {
    48  		case <-ctx.Done():
    49  			return
    50  		case <-tk.C:
    51  			m.tryFlush()
    52  		}
    53  	}
    54  }
    55  
    56  func (m *Manager) Save(cfg confgroup.Config, status string) {
    57  	if v, ok := m.store.lookup(cfg); !ok || status != v {
    58  		m.store.add(cfg, status)
    59  		m.triggerFlush()
    60  	}
    61  }
    62  
    63  func (m *Manager) Remove(cfg confgroup.Config) {
    64  	if _, ok := m.store.lookup(cfg); ok {
    65  		m.store.remove(cfg)
    66  		m.triggerFlush()
    67  	}
    68  }
    69  
    70  func (m *Manager) triggerFlush() {
    71  	select {
    72  	case m.flushCh <- struct{}{}:
    73  	default:
    74  	}
    75  }
    76  
    77  func (m *Manager) tryFlush() {
    78  	select {
    79  	case <-m.flushCh:
    80  		m.flush()
    81  	default:
    82  	}
    83  }
    84  
    85  func (m *Manager) flush() {
    86  	bs, err := m.store.bytes()
    87  	if err != nil {
    88  		return
    89  	}
    90  
    91  	f, err := os.Create(m.path)
    92  	if err != nil {
    93  		return
    94  	}
    95  	defer func() { _ = f.Close() }()
    96  
    97  	_, _ = f.Write(bs)
    98  }