Skip to content

Commit

Permalink
Avoid retrying rate limited events
Browse files Browse the repository at this point in the history
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
  • Loading branch information
stefanprodan committed Apr 19, 2021
1 parent 0867f3f commit 1b0792b
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 2 deletions.
9 changes: 9 additions & 0 deletions runtime/events/recorder.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ limitations under the License.
package events

import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/url"
"os"
"time"
Expand Down Expand Up @@ -49,6 +51,7 @@ func NewRecorder(webhook, reportingController string) (*Recorder, error) {

httpClient := retryablehttp.NewClient()
httpClient.HTTPClient.Timeout = 5 * time.Second
httpClient.CheckRetry = retryablehttp.ErrorPropagatedRetryPolicy
httpClient.Logger = nil

return &Recorder{
Expand Down Expand Up @@ -120,6 +123,12 @@ func (r *Recorder) Eventf(
return fmt.Errorf("failed to marshal object into json, error: %w", err)
}

// avoid retrying rate limited requests
if res, _ := r.Client.HTTPClient.Post(r.Webhook, "application/json", bytes.NewReader(body)); res != nil &&
(res.StatusCode == http.StatusTooManyRequests || res.StatusCode == http.StatusAccepted) {
return nil
}

if _, err := r.Client.Post(r.Webhook, "application/json", body); err != nil {
return err
}
Expand Down
30 changes: 28 additions & 2 deletions runtime/events/recorder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package events

import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
Expand Down Expand Up @@ -86,5 +85,32 @@ func TestEventRecorder_Eventf_Retry(t *testing.T) {
}

err = eventRecorder.EventErrorf(obj, nil, "sync", "sync %s", obj.Name)
require.EqualError(t, err, fmt.Sprintf("POST %s giving up after 3 attempt(s)", ts.URL))
require.Error(t, err)
}

func TestEventRecorder_Eventf_RateLimited(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
b, err := ioutil.ReadAll(r.Body)
require.NoError(t, err)

var payload Event
err = json.Unmarshal(b, &payload)
require.NoError(t, err)

w.WriteHeader(http.StatusTooManyRequests)
}))
defer ts.Close()

eventRecorder, err := NewRecorder(ts.URL, "test-controller")
require.NoError(t, err)
eventRecorder.Client.RetryMax = 2

obj := corev1.ObjectReference{
Kind: "GitRepository",
Namespace: "gitops-system",
Name: "webapp",
}

err = eventRecorder.EventInfof(obj, nil, "sync", "sync %s", obj.Name)
require.NoError(t, err)
}

0 comments on commit 1b0792b

Please sign in to comment.