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 }