91 lines
2.2 KiB
Go
91 lines
2.2 KiB
Go
package queue
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type HealthReporter struct {
|
|
mu sync.RWMutex
|
|
startedAt time.Time
|
|
lastPollAt time.Time
|
|
lastSuccessAt time.Time
|
|
lastFailureAt time.Time
|
|
lastError string
|
|
consecutivePollFailures int
|
|
errorThreshold int
|
|
draining bool
|
|
}
|
|
|
|
type HealthSnapshot struct {
|
|
Status string `json:"status"`
|
|
StartedAt time.Time `json:"started_at"`
|
|
LastPollAt time.Time `json:"last_poll_at,omitempty"`
|
|
LastSuccessAt time.Time `json:"last_success_at,omitempty"`
|
|
LastFailureAt time.Time `json:"last_failure_at,omitempty"`
|
|
LastError string `json:"last_error,omitempty"`
|
|
ConsecutivePollFailure int `json:"consecutive_poll_failures"`
|
|
Draining bool `json:"draining"`
|
|
}
|
|
|
|
func NewHealthReporter(errorThreshold int) *HealthReporter {
|
|
if errorThreshold <= 0 {
|
|
errorThreshold = 3
|
|
}
|
|
now := time.Now().UTC()
|
|
return &HealthReporter{
|
|
startedAt: now,
|
|
lastPollAt: now,
|
|
errorThreshold: errorThreshold,
|
|
}
|
|
}
|
|
|
|
func (r *HealthReporter) MarkPollSuccess() {
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
now := time.Now().UTC()
|
|
r.lastPollAt = now
|
|
r.lastSuccessAt = now
|
|
r.consecutivePollFailures = 0
|
|
r.lastError = ""
|
|
}
|
|
|
|
func (r *HealthReporter) MarkPollFailure(err error) {
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
now := time.Now().UTC()
|
|
r.lastPollAt = now
|
|
r.lastFailureAt = now
|
|
r.consecutivePollFailures++
|
|
if err != nil {
|
|
r.lastError = err.Error()
|
|
}
|
|
}
|
|
|
|
func (r *HealthReporter) MarkDraining() {
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
r.draining = true
|
|
}
|
|
|
|
func (r *HealthReporter) Snapshot() HealthSnapshot {
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
status := "ok"
|
|
if r.draining {
|
|
status = "draining"
|
|
} else if r.consecutivePollFailures >= r.errorThreshold {
|
|
status = "degraded"
|
|
}
|
|
return HealthSnapshot{
|
|
Status: status,
|
|
StartedAt: r.startedAt,
|
|
LastPollAt: r.lastPollAt,
|
|
LastSuccessAt: r.lastSuccessAt,
|
|
LastFailureAt: r.lastFailureAt,
|
|
LastError: r.lastError,
|
|
ConsecutivePollFailure: r.consecutivePollFailures,
|
|
Draining: r.draining,
|
|
}
|
|
}
|