Files

79 lines
1.6 KiB
Go

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
}