87 lines
2.0 KiB
Go
87 lines
2.0 KiB
Go
package supervisor
|
|
|
|
type ReleaseState string
|
|
|
|
const (
|
|
ReleaseCandidate ReleaseState = "CANDIDATE"
|
|
ReleaseHealthy ReleaseState = "HEALTHY"
|
|
ReleaseFailed ReleaseState = "FAILED"
|
|
ReleaseRolledBack ReleaseState = "ROLLED_BACK"
|
|
)
|
|
|
|
type TrafficMode string
|
|
|
|
const (
|
|
TrafficStable TrafficMode = "STABLE"
|
|
TrafficCanaryHeader TrafficMode = "CANARY_HEADER"
|
|
TrafficCandidate TrafficMode = "CANDIDATE"
|
|
)
|
|
|
|
type Release struct {
|
|
ID string
|
|
Version string
|
|
State ReleaseState
|
|
LastKnownGood bool
|
|
}
|
|
type Observation struct {
|
|
ReleaseID string
|
|
Ready bool
|
|
Reason string
|
|
ObservedAtUnixMillis int64
|
|
}
|
|
type Lifeboat struct {
|
|
Current Release
|
|
LastKnownGood Release
|
|
Observations []Observation
|
|
TrafficMode TrafficMode
|
|
StableUpstream string
|
|
CandidateUpstream string
|
|
}
|
|
|
|
func (l *Lifeboat) Start(candidate Release) bool {
|
|
if candidate.ID == "" || candidate.Version == "" {
|
|
return false
|
|
}
|
|
candidate.State = ReleaseCandidate
|
|
l.Current = candidate
|
|
return true
|
|
}
|
|
func (l *Lifeboat) Record(o Observation) bool {
|
|
if o.ReleaseID == "" {
|
|
return false
|
|
}
|
|
l.Observations = append(l.Observations, o)
|
|
if o.ReleaseID != l.Current.ID {
|
|
return true
|
|
}
|
|
if o.Ready {
|
|
l.Current.State = ReleaseHealthy
|
|
l.Current.LastKnownGood = true
|
|
l.LastKnownGood = l.Current
|
|
} else {
|
|
l.Current.State = ReleaseFailed
|
|
}
|
|
return true
|
|
}
|
|
func (l *Lifeboat) Rollback() bool {
|
|
if l.LastKnownGood.ID == "" {
|
|
return false
|
|
}
|
|
l.Current = l.LastKnownGood
|
|
l.Current.State = ReleaseRolledBack
|
|
return true
|
|
}
|
|
|
|
func (l *Lifeboat) SetTraffic(mode TrafficMode, stableUpstream, candidateUpstream string) bool {
|
|
if mode != TrafficStable && mode != TrafficCanaryHeader && mode != TrafficCandidate {
|
|
return false
|
|
}
|
|
if stableUpstream == "" || (mode != TrafficStable && candidateUpstream == "") {
|
|
return false
|
|
}
|
|
l.TrafficMode = mode
|
|
l.StableUpstream = stableUpstream
|
|
l.CandidateUpstream = candidateUpstream
|
|
return true
|
|
}
|