Files
ai-gateway-go/internal/platform/health/checker.go
T
superidou 5759c1862e AI Gateway Go 0.10.0 源码快照 + 旗舰版需求规划报告
M0-M7 已完成:核心网关(身份/RBAC/TOTP/OIDC/SAML/Provider/配额/路由/内容策略/审计/定价)+ 资源市场(MCP/Skills/数字员工)。
含 22 个 PostgreSQL 迁移、管理端/门户端前端源码、OpenAPI 契约、部署 compose。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-12 11:45:54 +08:00

86 lines
1.9 KiB
Go

package health
import (
"context"
"sync"
"time"
)
type Probe func(context.Context) error
type Dependency struct {
Name string
Required bool
Probe Probe
}
type Result struct {
Status string `json:"status"`
Required bool `json:"required"`
LatencyMS float64 `json:"latency_ms"`
Error string `json:"error,omitempty"`
}
type Report struct {
Ready bool `json:"ready"`
Status string `json:"status"`
Components map[string]Result `json:"components"`
}
type Checker struct {
Timeout time.Duration
Dependencies []Dependency
}
func (c Checker) Readiness(ctx context.Context) Report {
report := Report{Ready: true, Status: "ok", Components: make(map[string]Result, len(c.Dependencies))}
type namedResult struct {
name string
result Result
}
results := make(chan namedResult, len(c.Dependencies))
var wg sync.WaitGroup
for _, dependency := range c.Dependencies {
dependency := dependency
wg.Add(1)
go func() {
defer wg.Done()
result := Result{Status: "ok", Required: dependency.Required}
if dependency.Probe == nil {
result.Status = "not_configured"
results <- namedResult{dependency.Name, result}
return
}
probeCtx, cancel := context.WithTimeout(ctx, c.Timeout)
defer cancel()
started := time.Now()
err := dependency.Probe(probeCtx)
result.LatencyMS = float64(time.Since(started).Microseconds()) / 1000
if err != nil {
result.Status = "unavailable"
result.Error = err.Error()
}
results <- namedResult{dependency.Name, result}
}()
}
go func() {
wg.Wait()
close(results)
}()
for item := range results {
report.Components[item.name] = item.result
if item.result.Required && item.result.Status != "ok" {
report.Ready = false
}
if !item.result.Required && item.result.Status == "unavailable" && report.Status == "ok" {
report.Status = "degraded"
}
}
if !report.Ready {
report.Status = "unavailable"
}
return report
}