fix: non-blocking loader with retry backoff, 30s timeout
CI / Vet, test, build (push) Successful in 2m11s
CI / Build and push image (push) Successful in 44s

This commit is contained in:
Admin Bot
2026-08-26 15:55:57 -07:00
parent fbc197b471
commit e4c2d3cfd0
2 changed files with 19 additions and 21 deletions
+2 -5
View File
@@ -52,12 +52,9 @@ func main() {
if l, err := serviceadapter.NewLoader(registry, "api"); err != nil {
log.Printf("ServiceAdapter loader disabled: %v", err)
} else {
if err := l.Start(30 * time.Second); err != nil {
log.Printf("ServiceAdapter loader failed: %v", err)
} else {
l.Start(30 * time.Second)
loader = l
log.Printf("ServiceAdapter loader started")
}
log.Printf("ServiceAdapter loader started (background)")
}
router := server.NewRouter(healthChecker, dispatcher, temporalHandler, upstreamHandler)
+13 -12
View File
@@ -54,7 +54,7 @@ func NewLoader(registry *Registry, namespace string) (*Loader, error) {
token: string(tokenBytes),
baseURL: "https://kubernetes.default.svc",
client: &http.Client{
Timeout: 10 * time.Second,
Timeout: 30 * time.Second,
Transport: &http.Transport{
TLSClientConfig: &tls.Config{RootCAs: pool},
},
@@ -63,19 +63,22 @@ func NewLoader(registry *Registry, namespace string) (*Loader, error) {
}, nil
}
// Start loads ServiceAdapters immediately, then polls every interval.
func (l *Loader) Start(interval time.Duration) error {
// Start begins loading ServiceAdapters in the background. Non-blocking.
// Retries on failure so the gateway can start serving immediately.
func (l *Loader) Start(interval time.Duration) {
go func() {
// Initial load with retries (API server may be slow on startup)
for attempt := 1; ; attempt++ {
if err := l.load(); err != nil {
// Retry once after 2s — handles transient "storage reinitializing" (429)
log.Printf("serviceadapter loader: first attempt failed (%v), retrying in 2s", err)
time.Sleep(2 * time.Second)
if err := l.load(); err != nil {
return fmt.Errorf("serviceadapter loader: %w", err)
backoff := time.Duration(min(attempt*5, 30)) * time.Second
log.Printf("serviceadapter loader: attempt %d failed (%v), retry in %s", attempt, err, backoff)
time.Sleep(backoff)
continue
}
break
}
// Background poll for changes
go func() {
// Poll for changes
ticker := time.NewTicker(interval)
defer ticker.Stop()
for {
@@ -89,8 +92,6 @@ func (l *Loader) Start(interval time.Duration) error {
}
}
}()
return nil
}
// Stop stops the background poll.