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>
This commit is contained in:
DenozordecandCursor committed 2026-11-02 17:23:59 +07:00
1 parent 924f111e48
commit f8e0520817
197 files changed
+18655 -1416

No files matched your search

+51
View File
@@ -0,0 +1,51 @@
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
}