feat: track scoped storage incidents
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
package store
|
||||
|
||||
import "sync"
|
||||
|
||||
type ScopeState uint8
|
||||
|
||||
const (
|
||||
ScopeRecovering ScopeState = iota + 1
|
||||
ScopeReady
|
||||
ScopeDirtyReadable
|
||||
ScopeUnavailable
|
||||
)
|
||||
|
||||
type ScopeKey struct {
|
||||
Kind string
|
||||
ID string
|
||||
}
|
||||
|
||||
type ScopeHealth struct {
|
||||
mu sync.RWMutex
|
||||
required map[ScopeKey]bool
|
||||
states map[ScopeKey]ScopeState
|
||||
}
|
||||
|
||||
func NewScopeHealth(required []ScopeKey) *ScopeHealth {
|
||||
health := &ScopeHealth{required: make(map[ScopeKey]bool, len(required)), states: make(map[ScopeKey]ScopeState, len(required))}
|
||||
for _, scope := range required {
|
||||
health.required[scope] = true
|
||||
health.states[scope] = ScopeRecovering
|
||||
}
|
||||
return health
|
||||
}
|
||||
|
||||
func (health *ScopeHealth) Set(scope ScopeKey, state ScopeState) bool {
|
||||
if health == nil || scope.Kind == "" || state < ScopeRecovering || state > ScopeUnavailable {
|
||||
return false
|
||||
}
|
||||
health.mu.Lock()
|
||||
defer health.mu.Unlock()
|
||||
health.states[scope] = state
|
||||
return true
|
||||
}
|
||||
|
||||
func (health *ScopeHealth) State(scope ScopeKey) ScopeState {
|
||||
if health == nil {
|
||||
return ScopeUnavailable
|
||||
}
|
||||
health.mu.RLock()
|
||||
defer health.mu.RUnlock()
|
||||
state := health.states[scope]
|
||||
if state == 0 {
|
||||
return ScopeUnavailable
|
||||
}
|
||||
return state
|
||||
}
|
||||
|
||||
func (health *ScopeHealth) GloballyReady() bool {
|
||||
if health == nil {
|
||||
return false
|
||||
}
|
||||
health.mu.RLock()
|
||||
defer health.mu.RUnlock()
|
||||
for scope := range health.required {
|
||||
if health.states[scope] != ScopeReady {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (health *ScopeHealth) ReadAllowed(scope ScopeKey) bool {
|
||||
state := health.State(scope)
|
||||
return state == ScopeReady || state == ScopeDirtyReadable
|
||||
}
|
||||
|
||||
func (health *ScopeHealth) MutationAllowed(scope ScopeKey) bool {
|
||||
return health.State(scope) == ScopeReady
|
||||
}
|
||||
Reference in New Issue
Block a user