87 lines
2.3 KiB
Go
87 lines
2.3 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 `json:"id"`
|
|
Version string `json:"version"`
|
|
State ReleaseState `json:"state"`
|
|
LastKnownGood bool `json:"last_known_good"`
|
|
}
|
|
type Observation struct {
|
|
ReleaseID string `json:"release_id"`
|
|
Ready bool `json:"ready"`
|
|
Reason string `json:"reason"`
|
|
ObservedAtUnixMillis int64 `json:"observed_at_unix_millis"`
|
|
}
|
|
type Lifeboat struct {
|
|
Current Release `json:"current"`
|
|
LastKnownGood Release `json:"last_known_good"`
|
|
Observations []Observation `json:"observations"`
|
|
TrafficMode TrafficMode `json:"traffic_mode"`
|
|
StableUpstream string `json:"stable_upstream"`
|
|
CandidateUpstream string `json:"candidate_upstream"`
|
|
}
|
|
|
|
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
|
|
}
|