mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
feat(coderd): add DERP healthcheck (#6936)
This commit is contained in:
@ -33,6 +33,7 @@ import (
|
||||
"tailscale.com/derp/derphttp"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/util/singleflight"
|
||||
|
||||
"cdr.dev/slog"
|
||||
"github.com/coder/coder/buildinfo"
|
||||
@ -46,6 +47,7 @@ import (
|
||||
"github.com/coder/coder/coderd/database/dbtype"
|
||||
"github.com/coder/coder/coderd/gitauth"
|
||||
"github.com/coder/coder/coderd/gitsshkey"
|
||||
"github.com/coder/coder/coderd/healthcheck"
|
||||
"github.com/coder/coder/coderd/httpapi"
|
||||
"github.com/coder/coder/coderd/httpmw"
|
||||
"github.com/coder/coder/coderd/metricscache"
|
||||
@ -123,7 +125,10 @@ type Options struct {
|
||||
TemplateScheduleStore schedule.TemplateScheduleStore
|
||||
// AppSigningKey denotes the symmetric key to use for signing app tickets.
|
||||
// The key must be 64 bytes long.
|
||||
AppSigningKey []byte
|
||||
AppSigningKey []byte
|
||||
HealthcheckFunc func(ctx context.Context) (*healthcheck.Report, error)
|
||||
HealthcheckTimeout time.Duration
|
||||
HealthcheckRefresh time.Duration
|
||||
|
||||
// APIRateLimit is the minutely throughput rate limit per user or ip.
|
||||
// Setting a rate limit <0 will disable the rate limiter across the entire
|
||||
@ -235,6 +240,19 @@ func New(options *Options) *API {
|
||||
if len(options.AppSigningKey) != 64 {
|
||||
panic("coderd: AppSigningKey must be 64 bytes long")
|
||||
}
|
||||
if options.HealthcheckFunc == nil {
|
||||
options.HealthcheckFunc = func(ctx context.Context) (*healthcheck.Report, error) {
|
||||
return healthcheck.Run(ctx, &healthcheck.ReportOptions{
|
||||
DERPMap: options.DERPMap.Clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
if options.HealthcheckTimeout == 0 {
|
||||
options.HealthcheckTimeout = 30 * time.Second
|
||||
}
|
||||
if options.HealthcheckRefresh == 0 {
|
||||
options.HealthcheckRefresh = 10 * time.Minute
|
||||
}
|
||||
|
||||
siteCacheDir := options.CacheDir
|
||||
if siteCacheDir != "" {
|
||||
@ -293,6 +311,7 @@ func New(options *Options) *API {
|
||||
Auditor: atomic.Pointer[audit.Auditor]{},
|
||||
TemplateScheduleStore: atomic.Pointer[schedule.TemplateScheduleStore]{},
|
||||
Experiments: experiments,
|
||||
healthCheckGroup: &singleflight.Group[string, *healthcheck.Report]{},
|
||||
}
|
||||
if options.UpdateCheckOptions != nil {
|
||||
api.updateChecker = updatecheck.New(
|
||||
@ -718,6 +737,7 @@ func New(options *Options) *API {
|
||||
)
|
||||
|
||||
r.Get("/coordinator", api.debugCoordinator)
|
||||
r.Get("/health", api.debugDeploymentHealth)
|
||||
})
|
||||
})
|
||||
|
||||
@ -773,6 +793,8 @@ type API struct {
|
||||
// Experiments contains the list of experiments currently enabled.
|
||||
// This is used to gate features that are not yet ready for production.
|
||||
Experiments codersdk.Experiments
|
||||
|
||||
healthCheckGroup *singleflight.Group[string, *healthcheck.Report]
|
||||
}
|
||||
|
||||
// Close waits for all WebSocket connections to drain before returning.
|
||||
|
Reference in New Issue
Block a user