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  }