Files
EvoBGP/internal/jobs/context.go
T
DenozordecandCursor be3d73f374 perf: quick wins for pipeline, jobs, httpapi and web ops
- CDN snapshot: batch merge после parallel fetch, без race на persist
- ListRevisionPrefixes: лёгкая проверка revision вместо GetRevision
- Jobs: timeout/cancel context для pipeline и deploy
- HTTP server timeouts; кэш birdc для GET /peers
- ListModules: batch DoH profiles одним запросом
- Web: tab-scoped load на /operations, debounce job search, меньше over-fetch на dashboard

Co-authored-by: Cursor <[email protected]>
2026-05-21 10:42:13 +07:00

78 lines
2.0 KiB
Go

package jobs
import (
"context"
"os"
"strconv"
"time"
)
const (
defaultJobTimeoutModuleRefresh = 10 * time.Minute
defaultJobTimeoutTenantRefresh = 15 * time.Minute
defaultJobTimeoutDeployApply = 5 * time.Minute
defaultJobTimeoutPeerReconcile = 10 * time.Minute
defaultJobTimeoutRollback = 5 * time.Minute
defaultJobTimeoutBirdReload = 2 * time.Minute
)
func jobTimeout(kind string) time.Duration {
envKey := map[string]string{
KindModuleRefresh: "EVOBGP_JOB_TIMEOUT_MODULE_REFRESH",
KindTenantRefresh: "EVOBGP_JOB_TIMEOUT_TENANT_REFRESH",
KindDeployApply: "EVOBGP_JOB_TIMEOUT_DEPLOY_APPLY",
KindPeerReconcile: "EVOBGP_JOB_TIMEOUT_PEER_RECONCILE",
KindRevisionRollback: "EVOBGP_JOB_TIMEOUT_ROLLBACK",
KindBirdReload: "EVOBGP_JOB_TIMEOUT_BIRD_RELOAD",
}[kind]
if envKey != "" {
if d, err := time.ParseDuration(os.Getenv(envKey)); err == nil && d > 0 {
return d
}
}
switch kind {
case KindModuleRefresh:
return defaultJobTimeoutModuleRefresh
case KindTenantRefresh:
return defaultJobTimeoutTenantRefresh
case KindDeployApply:
return defaultJobTimeoutDeployApply
case KindPeerReconcile:
return defaultJobTimeoutPeerReconcile
case KindRevisionRollback:
return defaultJobTimeoutRollback
case KindBirdReload:
return defaultJobTimeoutBirdReload
default:
if n, err := strconv.Atoi(os.Getenv("EVOBGP_JOB_TIMEOUT_SEC")); err == nil && n > 0 {
return time.Duration(n) * time.Second
}
return defaultJobTimeoutModuleRefresh
}
}
// workContext returns a timeout context that also cancels when the job is cancelled.
func (j *Job) workContext() (context.Context, context.CancelFunc) {
if j == nil {
return context.Background(), func() {}
}
timeout := jobTimeout(j.Kind)
ctx, cancel := context.WithTimeout(context.Background(), timeout)
go func() {
ticker := time.NewTicker(500 * time.Millisecond)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
if j.IsCancelRequested() {
cancel()
return
}
}
}
}()
return ctx, cancel
}