fix: add timeouts and backoff to webhook delivery

This commit is contained in:
krau
2026-08-16 20:28:39 +08:00
parent 48e739f06d
commit 0d49ae94af
+23 -8
View File
@@ -37,6 +37,9 @@ func SendWebhook(ctx context.Context, payload *WebhookPayload) {
} else { } else {
logger = log.Default().With("task_id", payload.TaskID) logger = log.Default().With("task_id", payload.TaskID)
} }
if ctx == nil {
ctx = context.Background()
}
payloadBytes, err := json.Marshal(payload) payloadBytes, err := json.Marshal(payload)
if err != nil { if err != nil {
@@ -44,10 +47,15 @@ func SendWebhook(ctx context.Context, payload *WebhookPayload) {
return return
} }
// 重试 3 次 // 重试 3 次, 指数退避 (100ms/400ms/1.6s)
for i := range 3 { const maxAttempts = 3
req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, webhookURL, bytes.NewBuffer(payloadBytes)) const requestTimeout = 30 * time.Second
backoff := 100 * time.Millisecond
for i := range maxAttempts {
reqCtx, cancel := context.WithTimeout(ctx, requestTimeout)
req, err := http.NewRequestWithContext(reqCtx, http.MethodPost, webhookURL, bytes.NewBuffer(payloadBytes))
if err != nil { if err != nil {
cancel()
logger.Errorf("Failed to create webhook request: %v", err) logger.Errorf("Failed to create webhook request: %v", err)
return return
} }
@@ -56,9 +64,13 @@ func SendWebhook(ctx context.Context, payload *WebhookPayload) {
req.Header.Set("User-Agent", "SaveAny-Bot/1.0") req.Header.Set("User-Agent", "SaveAny-Bot/1.0")
resp, err := webhookClient.Do(req) resp, err := webhookClient.Do(req)
cancel()
if err != nil { if err != nil {
logger.Warnf("Webhook request failed (attempt %d/3): %v", i+1, err) logger.Warnf("Webhook request failed (attempt %d/%d): %v", i+1, maxAttempts, err)
time.Sleep(time.Second * time.Duration(i+1)) if i < maxAttempts-1 {
time.Sleep(backoff)
}
backoff *= 4
continue continue
} }
resp.Body.Close() resp.Body.Close()
@@ -68,11 +80,14 @@ func SendWebhook(ctx context.Context, payload *WebhookPayload) {
return return
} }
logger.Warnf("Webhook returned non-2xx status (attempt %d/3): %d", i+1, resp.StatusCode) logger.Warnf("Webhook returned non-2xx status (attempt %d/%d): %d", i+1, maxAttempts, resp.StatusCode)
time.Sleep(time.Second * time.Duration(i+1)) if i < maxAttempts-1 {
time.Sleep(backoff)
}
backoff *= 4
} }
logger.Errorf("Failed to send webhook after 3 attempts") logger.Errorf("Failed to send webhook after %d attempts", maxAttempts)
}() }()
} }