(c Config, oldState database.WorkspaceAgentMonitorState, states []State)
| 89 | } |
| 90 | |
| 91 | func NextState(c Config, oldState database.WorkspaceAgentMonitorState, states []State) database.WorkspaceAgentMonitorState { |
| 92 | // If there are enough consecutive NOK states, we should be in an |
| 93 | // alert state. |
| 94 | consecutiveNOKs := slice.CountConsecutive(StateNOK, states...) |
| 95 | if percent(consecutiveNOKs, len(states)) >= c.Alert.ConsecutiveNOKsPercent { |
| 96 | return database.WorkspaceAgentMonitorStateNOK |
| 97 | } |
| 98 | |
| 99 | // We do not explicitly handle StateUnknown because it could have |
| 100 | // been either StateOK or StateNOK if collection didn't fail. As |
| 101 | // it could be either, our best bet is to ignore it. |
| 102 | nokCount, okCount := 0, 0 |
| 103 | for _, state := range states { |
| 104 | switch state { |
| 105 | case StateOK: |
| 106 | okCount++ |
| 107 | case StateNOK: |
| 108 | nokCount++ |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | // If there are enough NOK datapoints, we should be in an alert state. |
| 113 | if percent(nokCount, len(states)) >= c.Alert.MinimumNOKsPercent { |
| 114 | return database.WorkspaceAgentMonitorStateNOK |
| 115 | } |
| 116 | |
| 117 | // If all datapoints are OK, we should be in an OK state |
| 118 | if okCount == len(states) { |
| 119 | return database.WorkspaceAgentMonitorStateOK |
| 120 | } |
| 121 | |
| 122 | // Otherwise we stay in the same state as last. |
| 123 | return oldState |
| 124 | } |
| 125 | |
| 126 | func percent[T int](numerator, denominator T) int { |
| 127 | percent := float64(numerator*100) / float64(denominator) |
no test coverage detected