mirror of
https://github.com/krau/SaveAny-Bot.git
synced 2026-09-08 00:56:38 +08:00
fix: add timeouts and backoff to webhook delivery
This commit is contained in:
+23
-8
@@ -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)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user