Created
September 11, 2023 16:32
-
-
Save thrawn01/991c1e45d374643ab0aba69a238ea924 to your computer and use it in GitHub Desktop.
retry package which can be used with clients that implement `duh`
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package duh | |
import ( | |
"context" | |
"testing" | |
"time" | |
) | |
type DoThingRequest struct{} | |
type DoThingResponse struct{} | |
type Client struct{} | |
func (c *Client) DoThing(ctx context.Context, r *DoThingRequest, resp *DoThingResponse) error { | |
return nil | |
} | |
func NewClient() *Client { | |
return &Client{} | |
} | |
func TestClient(t *testing.T) { | |
c := NewClient() | |
var resp DoThingResponse | |
ctx, cancel := context.WithCancel(context.Background()) | |
defer cancel() | |
// --- Retryable errors are --- | |
// 409 - Conflict | |
// 429 - Too Many Requests (Will calculate the appropriate interval to retry based on the response) | |
// 500 - Internal Error (Hopefully this is a temporary error, and the server will recover) | |
// 502,503,504 - Infrastructure errors which hopefully will resolve on retry. | |
// `retry.Twice` is the policy that governs when to retry. | |
// The `retry.Twice` policy will retry 'twice' if the server responded with one of the following retryable errors | |
// The `retry.Twice` uses the default back off policy | |
err := retry.On(ctx, retry.Twice, func(ctx context.Context, attempt int) error { | |
return c.DoThing(ctx, &DoThingRequest{}, &resp) | |
}) | |
// The `retry.UntilSuccess` policy will retry on retryable errors until success, using the default back off policy. | |
err = retry.On(ctx, retry.UntilSuccess, func(ctx context.Context, attempt int) error { | |
return c.DoThing(ctx, &DoThingRequest{}, &resp) | |
}) | |
// The `retry.OnConflict` policy will retry only on 409 conflict or until success, using the default back off policy. | |
err = retry.On(ctx, retry.OnConflict, func(ctx context.Context, attempt int) error { | |
return c.DoThing(ctx, &DoThingRequest{}, &resp) | |
}) | |
customPolicy := retry.Policy{ | |
Interval: retry.BackOff{ | |
Min: time.Millisecond, | |
Max: time.Millisecond * 100, | |
Factor: 2, | |
}, | |
OnCodes: []int64{409, 429, 502, 503, 504}, | |
Attempts: 5, | |
} | |
// Users can define a custom retry policy to suit their needs | |
err = retry.On(customPolicy, func(ctx context.Context, attempt int) error { | |
return c.DoThing(ctx, &DoThingRequest{}, &resp) | |
}) | |
customPolicy = retry.Policy{ | |
// No Backoff, just sleep in-between retries | |
Interval: retry.Sleep(time.Second), | |
On: []int64{409, 429, 502, 503, 504}, | |
// Attempts of 0 indicate infinite retries | |
Attempts: 0, | |
} | |
err = retry.On(customPolicy, func(ctx context.Context, attempt int) error { | |
return c.DoThing(ctx, &DoThingRequest{}, &resp) | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment