github.com/go-playground/pkg/v5@v5.29.1/_examples/net/http/retrier/main.go (about) 1 package main 2 3 import ( 4 "context" 5 "fmt" 6 "net/http" 7 "net/http/httptest" 8 "time" 9 10 appext "github.com/go-playground/pkg/v5/app" 11 errorsext "github.com/go-playground/pkg/v5/errors" 12 httpext "github.com/go-playground/pkg/v5/net/http" 13 . "github.com/go-playground/pkg/v5/values/result" 14 ) 15 16 // customize as desired to meet your needs including custom retryable status codes, errors etc. 17 var retrier = httpext.NewRetryer() 18 19 func main() { 20 ctx := appext.Context().Build() 21 22 type Test struct { 23 Date time.Time 24 } 25 var count int 26 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 27 if count < 2 { 28 count++ 29 http.Error(w, http.StatusText(http.StatusTooManyRequests), http.StatusTooManyRequests) 30 return 31 } 32 _ = httpext.JSON(w, http.StatusOK, Test{Date: time.Now().UTC()}) 33 })) 34 defer server.Close() 35 36 // fetch response 37 fn := func(ctx context.Context) Result[*http.Request, error] { 38 req, err := http.NewRequestWithContext(ctx, http.MethodGet, server.URL, nil) 39 if err != nil { 40 return Err[*http.Request, error](err) 41 } 42 return Ok[*http.Request, error](req) 43 } 44 45 var result Test 46 err := retrier.Do(ctx, fn, &result, http.StatusOK) 47 if err != nil { 48 panic(err) 49 } 50 fmt.Printf("Response: %+v\n", result) 51 52 // `Retrier` configuration is copy and so the base `Retrier` can be used and even customized for one-off requests. 53 // eg for this request we change the max attempts from the default configuration. 54 err = retrier.MaxAttempts(errorsext.MaxAttempts, 2).Do(ctx, fn, &result, http.StatusOK) 55 if err != nil { 56 panic(err) 57 } 58 fmt.Printf("Response: %+v\n", result) 59 }