52 lines
1.1 KiB
Go
52 lines
1.1 KiB
Go
package health
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"sync"
|
||
|
|
"time"
|
||
|
|
)
|
||
|
|
|
||
|
|
type CheckFunc func(context.Context) error
|
||
|
|
|
||
|
|
type Checker struct {
|
||
|
|
timeout time.Duration
|
||
|
|
checks map[string]CheckFunc
|
||
|
|
}
|
||
|
|
|
||
|
|
type Result struct {
|
||
|
|
Status string `json:"status"`
|
||
|
|
Checks map[string]string `json:"checks"`
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewChecker(timeout time.Duration, checks map[string]CheckFunc) *Checker {
|
||
|
|
return &Checker{timeout: timeout, checks: checks}
|
||
|
|
}
|
||
|
|
|
||
|
|
func (c *Checker) Ready(ctx context.Context) Result {
|
||
|
|
result := Result{Status: "ready", Checks: make(map[string]string, len(c.checks))}
|
||
|
|
var mutex sync.Mutex
|
||
|
|
var waitGroup sync.WaitGroup
|
||
|
|
|
||
|
|
for name, check := range c.checks {
|
||
|
|
name, check := name, check
|
||
|
|
waitGroup.Add(1)
|
||
|
|
go func() {
|
||
|
|
defer waitGroup.Done()
|
||
|
|
checkContext, cancel := context.WithTimeout(ctx, c.timeout)
|
||
|
|
defer cancel()
|
||
|
|
status := "up"
|
||
|
|
if err := check(checkContext); err != nil {
|
||
|
|
status = "down"
|
||
|
|
}
|
||
|
|
mutex.Lock()
|
||
|
|
result.Checks[name] = status
|
||
|
|
if status == "down" {
|
||
|
|
result.Status = "not_ready"
|
||
|
|
}
|
||
|
|
mutex.Unlock()
|
||
|
|
}()
|
||
|
|
}
|
||
|
|
waitGroup.Wait()
|
||
|
|
return result
|
||
|
|
}
|