From 9b65ba069feae381f36c7b198041c9ef1166d175 Mon Sep 17 00:00:00 2001 From: Lukasz Raczylo Date: Wed, 8 Jun 2022 19:07:26 +0100 Subject: [PATCH] Change retry library to something more useful. --- go.mod | 3 ++- go.sum | 4 ++++ query.go | 62 ++++++++++++++++++++++++++------------------------------ 3 files changed, 35 insertions(+), 34 deletions(-) diff --git a/go.mod b/go.mod index 03b9578..335a7be 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/lukaszraczylo/pandati v0.0.15 github.com/rs/zerolog v1.27.0 + github.com/sethvargo/go-retry v0.2.3 github.com/stretchr/testify v1.7.1 golang.org/x/net v0.0.0-20220607020251-c690dde0001d ) @@ -25,7 +26,7 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect github.com/wI2L/jsondiff v0.2.0 // indirect - golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect + golang.org/x/sys v0.0.0-20220608164250-635b8c9b7f68 // indirect golang.org/x/text v0.3.7 // indirect gopkg.in/yaml.v3 v3.0.0 // indirect ) diff --git a/go.sum b/go.sum index 76a5f0c..2900876 100644 --- a/go.sum +++ b/go.sum @@ -35,6 +35,8 @@ github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc= github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc= github.com/rs/zerolog v1.27.0 h1:1T7qCieN22GVc8S4Q2yuexzBb1EqjbgjSH9RohbMjKs= github.com/rs/zerolog v1.27.0/go.mod h1:7frBqO0oezxmnO7GF86FY++uy8I0Tk/If5ni1G9Qc0U= +github.com/sethvargo/go-retry v0.2.3 h1:oYlgvIvsju3jNbottWABtbnoLC+GDtLdBHxKWxQm/iU= +github.com/sethvargo/go-retry v0.2.3/go.mod h1:1afjQuvh7s4gflMObvjLPaWgluLLyhA1wmVZ6KLpICw= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= @@ -73,6 +75,8 @@ golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220608164250-635b8c9b7f68 h1:z8Hj/bl9cOV2grsOpEaQFUaly0JWN3i97mo3jXKJNp0= +golang.org/x/sys v0.0.0-20220608164250-635b8c9b7f68/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= diff --git a/query.go b/query.go index 9ca2f62..8e3e043 100644 --- a/query.go +++ b/query.go @@ -2,6 +2,7 @@ package gql import ( "bytes" + "context" "crypto/md5" "errors" "fmt" @@ -10,8 +11,8 @@ import ( "net/http" "time" - retry "github.com/avast/retry-go" "github.com/lukaszraczylo/pandati" + retry "github.com/sethvargo/go-retry" ) type requestBase struct { @@ -41,6 +42,7 @@ func (g *GraphQL) queryBuilder(queryContent string, queryVariables interface{}) } func (g *GraphQL) Query(queryContent string, queryVariables interface{}, queryHeaders map[string]interface{}) (responseContent string, err error) { + ctx := context.Background() g.Log.Debug("Query details", map[string]interface{}{"_query": queryContent, "_variables": queryVariables}) query, err := g.queryBuilder(queryContent, queryVariables) if err != nil { @@ -72,41 +74,35 @@ func (g *GraphQL) Query(queryContent string, queryVariables interface{}, queryHe var httpResponse *http.Response - err = retry.Do( - func() error { - httpResponse, err = g.HttpClient.Do(httpRequest) - if err != nil { - g.Log.Error("Unable to send the query", map[string]interface{}{"_error": err.Error()}) - return err - } - if httpResponse.StatusCode <= 200 && httpResponse.StatusCode >= 204 { - return errors.New(fmt.Sprintf("%v", httpResponse.StatusCode)) - } + backoff := retry.NewExponential(time.Duration(g.RetriesDelay)) + backoff = retry.WithMaxRetries(uint64(g.RetriesNumber), backoff) - defer io.Copy(ioutil.Discard, httpResponse.Body) - defer httpResponse.Body.Close() + retry.Do(ctx, backoff, func(ctx context.Context) error { + httpResponse, err = g.HttpClient.Do(httpRequest) + if err != nil { + g.Log.Error("Unable to send the query", map[string]interface{}{"_error": err.Error()}) + return err + } + if httpResponse.StatusCode <= 200 && httpResponse.StatusCode >= 204 { + return retry.RetryableError(errors.New(fmt.Sprintf("%v", httpResponse.StatusCode))) + } - body, err = ioutil.ReadAll(httpResponse.Body) - if err != nil { - g.Log.Critical("Unable to read the response", map[string]interface{}{"_error": err.Error()}) - return errors.New(fmt.Sprintf("body parsing %v", httpResponse.StatusCode)) - } + defer io.Copy(ioutil.Discard, httpResponse.Body) + defer httpResponse.Body.Close() - err = json.Unmarshal(body, &queryResult) - if err != nil { - g.Log.Error("Unable to unmarshal the query", map[string]interface{}{"_error": err.Error()}) - return errors.New(fmt.Sprintf("body unmarshal %v", httpResponse.StatusCode)) - } - return nil - }, - retry.Attempts(uint(g.RetriesNumber)), - retry.OnRetry( - func(n uint, err error) { - g.Log.Debug("Retrying the query", map[string]interface{}{"_attempt": n, "_error": err.Error()}) - time.Sleep(time.Duration(g.RetriesDelay) * time.Millisecond) - }, - ), - ) + body, err = ioutil.ReadAll(httpResponse.Body) + if err != nil { + g.Log.Critical("Unable to read the response", map[string]interface{}{"_error": err.Error()}) + return retry.RetryableError(errors.New(fmt.Sprintf("body parsing %v", httpResponse.StatusCode))) + } + + err = json.Unmarshal(body, &queryResult) + if err != nil { + g.Log.Error("Unable to unmarshal the query", map[string]interface{}{"_error": err.Error()}) + return retry.RetryableError(errors.New(fmt.Sprintf("body unmarshal %v", httpResponse.StatusCode))) + } + return nil + }) if !pandati.IsZero(queryResult.Errors) || err != nil { g.Log.Error("Query returned error", map[string]interface{}{"_query": queryContent, "_variables": queryVariables, "_error": fmt.Sprintf("%v", queryResult.Errors), "_response_code": httpResponse.StatusCode})