Files
DenozordecandCursor f8e0520817 feat(httpapi): harden control plane and speed up prefix refresh
Очередь job получила lease и fencing, телеметрия и прогресс deploy сохраняются, ревизия пишет manifest входов. Обновление префиксов не переписывает неизменённый снимок, большие наборы идут через COPY, а устаревшая ревизия не попадает в deploy. Бандл ноды кэшируется, prune и постановка job больше не держат горячий путь.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-11-02 17:23:59 +07:00

52 lines
1.3 KiB
Go

package store
import (
"context"
"os"
"strings"
"time"
)
const defaultSnapshotTimeout = 2 * time.Minute
// SnapshotWriteBudget keeps a caller deadline. When ctx has none, it applies
// EVOBGP_SNAPSHOT_TIMEOUT (default 2 minutes). installed is true when this
// function created the deadline; callers use that to set statement_timeout.
func SnapshotWriteBudget(ctx context.Context) (context.Context, context.CancelFunc, bool) {
if ctx == nil {
ctx = context.Background()
}
if _, ok := ctx.Deadline(); ok {
return ctx, func() {}, false
}
ctx, cancel := context.WithTimeout(ctx, snapshotTimeout())
return ctx, cancel, true
}
// SnapshotStatementTimeout is the PostgreSQL statement_timeout that matches
// SnapshotWriteBudget. A caller deadline wins; otherwise the env default applies.
func SnapshotStatementTimeout(ctx context.Context) time.Duration {
if ctx != nil {
if dl, ok := ctx.Deadline(); ok {
d := time.Until(dl)
if d < time.Millisecond {
return time.Millisecond
}
return d
}
}
return snapshotTimeout()
}
func snapshotTimeout() time.Duration {
s := strings.TrimSpace(os.Getenv("EVOBGP_SNAPSHOT_TIMEOUT"))
if s == "" {
return defaultSnapshotTimeout
}
d, err := time.ParseDuration(s)
if err != nil || d <= 0 {
return defaultSnapshotTimeout
}
return d
}