blob: 30dac3b476a5900569a5ac1a22babc20ec6e1aa6 [file] [log] [blame]
Tim Windelschmidt6d33a432025-02-04 14:34:25 +01001// Copyright The Monogon Project Authors.
2// SPDX-License-Identifier: Apache-2.0
3
Serge Bazanskicf864da2024-07-31 11:23:34 +00004package supervisor
5
6import (
7 "sync"
8 "time"
9)
10
11// Metrics is an interface from the supervisor to any kind of metrics-collecting
12// component.
13type Metrics interface {
14 // NotifyNodeState is called whenever a given runnable at a given DN changes
15 // state. Called synchronously from the supervisor's processor loop, so must not
16 // block, but is also guaranteed to only be called from a single goroutine.
17 NotifyNodeState(dn string, state NodeState)
18}
19
20// metricsFanout is used internally to fan out a single Metrics interface (which
21// it implements) onto multiple subordinate Metrics interfaces (as provided by
22// the user via WithMetrics).
23type metricsFanout struct {
24 sub []Metrics
25}
26
27func (m *metricsFanout) NotifyNodeState(dn string, state NodeState) {
28 for _, sub := range m.sub {
29 sub.NotifyNodeState(dn, state)
30 }
31}
32
33// InMemoryMetrics is a simple Metrics implementation that keeps an in-memory
34// mirror of the state of all DNs in the supervisor. The zero value for
35// InMemoryMetrics is ready to use.
36type InMemoryMetrics struct {
37 mu sync.RWMutex
38 dns map[string]DNState
39}
40
41// DNState is the state of a supervisor runnable, recorded alongside a timestamp
42// of when the State changed.
43type DNState struct {
44 // State is the current state of the runnable.
45 State NodeState
46 // Transition is the time at which the runnable reached its State.
47 Transition time.Time
48}
49
50func (m *InMemoryMetrics) NotifyNodeState(dn string, state NodeState) {
51 m.mu.Lock()
52 defer m.mu.Unlock()
53 if m.dns == nil {
54 m.dns = make(map[string]DNState)
55 }
56 m.dns[dn] = DNState{
57 State: state,
58 Transition: time.Now(),
59 }
60}
61
62// DNs returns a copy (snapshot in time) of the recorded DN states, in a map from
63// DN to DNState. The returned value can be mutated.
64func (m *InMemoryMetrics) DNs() map[string]DNState {
65 m.mu.RLock()
66 defer m.mu.RUnlock()
67
68 res := make(map[string]DNState)
69 for k, v := range m.dns {
70 res[k] = v
71 }
72 return res
73}