mirror of
https://github.com/coder/coder.git
synced 2026-06-03 21:18:24 +00:00
4d5a7b2d56
Currently, importing `codersdk` just to interact with the API requires importing tailscale, which causes builds to fail unless manually using our fork.
65 lines
1.5 KiB
Go
65 lines
1.5 KiB
Go
package healthcheck
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"golang.org/x/exp/slices"
|
|
|
|
"github.com/coder/coder/v2/coderd/database"
|
|
"github.com/coder/coder/v2/coderd/healthcheck/health"
|
|
"github.com/coder/coder/v2/codersdk/healthsdk"
|
|
)
|
|
|
|
const (
|
|
DatabaseDefaultThreshold = 15 * time.Millisecond
|
|
)
|
|
|
|
type DatabaseReport healthsdk.DatabaseReport
|
|
|
|
type DatabaseReportOptions struct {
|
|
DB database.Store
|
|
Threshold time.Duration
|
|
|
|
Dismissed bool
|
|
}
|
|
|
|
func (r *DatabaseReport) Run(ctx context.Context, opts *DatabaseReportOptions) {
|
|
r.Warnings = []health.Message{}
|
|
r.Severity = health.SeverityOK
|
|
r.Dismissed = opts.Dismissed
|
|
|
|
r.ThresholdMS = opts.Threshold.Milliseconds()
|
|
if r.ThresholdMS == 0 {
|
|
r.ThresholdMS = DatabaseDefaultThreshold.Milliseconds()
|
|
}
|
|
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
|
defer cancel()
|
|
|
|
pingCount := 5
|
|
pings := make([]time.Duration, 0, pingCount)
|
|
// Ping 5 times and average the latency.
|
|
for i := 0; i < pingCount; i++ {
|
|
pong, err := opts.DB.Ping(ctx)
|
|
if err != nil {
|
|
r.Error = health.Errorf(health.CodeDatabasePingFailed, "ping database: %s", err)
|
|
r.Severity = health.SeverityError
|
|
|
|
return
|
|
}
|
|
pings = append(pings, pong)
|
|
}
|
|
slices.Sort(pings)
|
|
|
|
// Take the median ping.
|
|
latency := pings[pingCount/2]
|
|
r.Latency = latency.String()
|
|
r.LatencyMS = latency.Milliseconds()
|
|
if r.LatencyMS >= r.ThresholdMS {
|
|
r.Severity = health.SeverityWarning
|
|
r.Warnings = append(r.Warnings, health.Messagef(health.CodeDatabasePingSlow, "median database ping above threshold"))
|
|
}
|
|
r.Healthy = true
|
|
r.Reachable = true
|
|
}
|