Skip to content

da440dil/go-re

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

go-re

CI Coverage Status Go Reference Go Report Card

Abstraction for retry strategies.

Example HTTP request

fn := func(ctx context.Context, url string) (string, error) {
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
	if err != nil {
		return "", err
	}
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		return "", err
	}
	defer res.Body.Close()

	body, err := io.ReadAll(res.Body)
	if err != nil {
		return "", err
	}
	if res.StatusCode != http.StatusOK {
		err = fmt.Errorf("status code != %d, %w", http.StatusOK, re.ErrRetryable)
	}
	return fmt.Sprintf("statusCode: %d, body: %s", res.StatusCode, body), err
}
// Retry function execution in case of an error after 10ms, 20ms, 30ms.
fn = re.Tryable(fn, slices.Values([]time.Duration{
	time.Millisecond * 10, time.Millisecond * 20, time.Millisecond * 30,
}))

x := 0
h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	statusCode := http.StatusOK
	if x > 2 || x%2 != 0 { // { 0 => 200, 1 => 418, 2 => 200, ... => 418 }
		statusCode = http.StatusTeapot
	}
	w.WriteHeader(statusCode)
	fmt.Fprintf(w, "{ x: %d }", x)
	x++
})
srv := httptest.NewServer(h)
defer srv.Close()

for range 3 {
	v, err := fn(context.Background(), srv.URL)
	fmt.Printf("%v, err: %v\n", v, err)
}

ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*50)
defer cancel()

v, err := fn(ctx, srv.URL)
fmt.Printf("%v, err: %v", v, err)
// Output:
// statusCode: 200, body: { x: 0 }, err: <nil>
// statusCode: 200, body: { x: 2 }, err: <nil>
// statusCode: 418, body: { x: 6 }, err: status code != 200, retryable
// statusCode: 418, body: { x: 9 }, err: context deadline exceeded

About

Abstraction for retry strategies

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages