Skip to content

Commit 3d3c04f

Browse files
committed
Add 2 attempts when deliverying webhooks to the server
1 parent e4e90f0 commit 3d3c04f

File tree

1 file changed

+40
-24
lines changed

1 file changed

+40
-24
lines changed

api/pkg/services/webhook_service.go

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"sync"
1212
"time"
1313

14+
"github.com/avast/retry-go"
1415
"github.com/pkg/errors"
1516

1617
"github.com/gofiber/fiber/v2"
@@ -210,37 +211,52 @@ func (service *WebhookService) sendNotification(ctx context.Context, event cloud
210211
ctx, span, ctxLogger := service.tracer.StartWithLogger(ctx, service.logger)
211212
defer span.End()
212213

213-
requestCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
214-
defer cancel()
214+
attempts := 0
215+
err := retry.Do(func() error {
216+
attempts++
215217

216-
request, err := service.createRequest(requestCtx, event, webhook)
217-
if err != nil {
218-
msg := fmt.Sprintf("cannot create [%s] event to webhook [%s] for user [%s]", event.Type(), webhook.URL, webhook.UserID)
219-
ctxLogger.Error(service.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg)))
220-
return
221-
}
218+
requestCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
219+
defer cancel()
222220

223-
response, err := service.client.Do(request)
224-
if err != nil {
225-
ctxLogger.Warn(stacktrace.Propagate(err, fmt.Sprintf("cannot send [%s] event to webhook [%s] for user [%s]", event.Type(), webhook.URL, webhook.UserID)))
226-
service.handleWebhookSendFailed(ctx, event, webhook, owner, err, nil)
227-
return
228-
}
221+
request, err := service.createRequest(requestCtx, event, webhook)
222+
if err != nil {
223+
msg := fmt.Sprintf("cannot create [%s] event to webhook [%s] for user [%s] after [%d] attempts", event.Type(), webhook.URL, webhook.UserID, attempts)
224+
return service.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg))
225+
}
229226

230-
defer func() {
231-
err = response.Body.Close()
227+
response, err := service.client.Do(request)
232228
if err != nil {
233-
ctxLogger.Error(stacktrace.Propagate(err, fmt.Sprintf("cannot close response body for [%s] event with ID [%s]", event.Type(), event.ID())))
229+
ctxLogger.Warn(stacktrace.Propagate(err, fmt.Sprintf("cannot send [%s] event to webhook [%s] for user [%s] after [%d] attempts", event.Type(), webhook.URL, webhook.UserID, attempts)))
230+
if attempts == 1 {
231+
return err
232+
}
233+
service.handleWebhookSendFailed(ctx, event, webhook, owner, err, nil)
234+
return nil
234235
}
235-
}()
236236

237-
if response.StatusCode >= 400 {
238-
ctxLogger.Info(fmt.Sprintf("cannot send [%s] event to webhook [%s] for user [%s] with response code [%d]", event.Type(), webhook.URL, webhook.UserID, response.StatusCode))
239-
service.handleWebhookSendFailed(ctx, event, webhook, owner, stacktrace.NewError(http.StatusText(response.StatusCode)), response)
240-
return
241-
}
237+
defer func() {
238+
err = response.Body.Close()
239+
if err != nil {
240+
ctxLogger.Error(stacktrace.Propagate(err, fmt.Sprintf("cannot close response body for [%s] event with ID [%s] after [%d] attempts", event.Type(), event.ID(), attempts)))
241+
}
242+
}()
243+
244+
if response.StatusCode >= 400 {
245+
ctxLogger.Info(fmt.Sprintf("cannot send [%s] event to webhook [%s] for user [%s] with response code [%d]", event.Type(), webhook.URL, webhook.UserID, response.StatusCode))
246+
if attempts == 1 {
247+
return stacktrace.NewError(http.StatusText(response.StatusCode))
248+
}
249+
service.handleWebhookSendFailed(ctx, event, webhook, owner, stacktrace.NewError(http.StatusText(response.StatusCode)), response)
250+
return nil
251+
}
242252

243-
ctxLogger.Info(fmt.Sprintf("sent webhook to url [%s] for event [%s] with ID [%s] and response code [%d]", webhook.URL, event.Type(), event.ID(), response.StatusCode))
253+
ctxLogger.Info(fmt.Sprintf("sent webhook to url [%s] for event [%s] with ID [%s] and response code [%d]", webhook.URL, event.Type(), event.ID(), response.StatusCode))
254+
return nil
255+
}, retry.Attempts(2))
256+
if err != nil {
257+
msg := fmt.Sprintf("cannot handle [%s] event to webhook [%s] for user [%s] after [%d] attempts", event.Type(), webhook.URL, webhook.UserID, attempts)
258+
ctxLogger.Error(service.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg)))
259+
}
244260
}
245261

246262
func (service *WebhookService) createRequest(ctx context.Context, event cloudevents.Event, webhook *entities.Webhook) (*http.Request, error) {

0 commit comments

Comments
 (0)