diff --git a/go.mod b/go.mod index 57b691f..626d674 100644 --- a/go.mod +++ b/go.mod @@ -11,5 +11,5 @@ require ( github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/smartystreets/goconvey v1.6.4 // indirect github.com/stretchr/objx v0.3.0 // indirect - github.com/stretchr/testify v1.3.0 + github.com/stretchr/testify v1.7.0 ) diff --git a/go.sum b/go.sum index 953d375..3d126bb 100644 --- a/go.sum +++ b/go.sum @@ -29,8 +29,14 @@ github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As= github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/hystrix/hystrix_client.go b/hystrix/hystrix_client.go index 563aa7c..6533d9a 100644 --- a/hystrix/hystrix_client.go +++ b/hystrix/hystrix_client.go @@ -205,6 +205,9 @@ func (hhc *Client) Do(request *http.Request) (*http.Response, error) { }, hhc.fallbackFunc) if err != nil { + if errors.Is(err, hystrix.ErrTimeout) { + return nil, err + } backoffTime := hhc.retrier.NextInterval(i) time.Sleep(backoffTime) continue diff --git a/hystrix/hystrix_client_test.go b/hystrix/hystrix_client_test.go index b90d084..edffdff 100644 --- a/hystrix/hystrix_client_test.go +++ b/hystrix/hystrix_client_test.go @@ -9,6 +9,7 @@ import ( "testing" "time" + "github.com/afex/hystrix-go/hystrix" "github.com/gojek/heimdall/v7" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -377,6 +378,42 @@ func TestHystrixHTTPClientRetriesPostOnFailure(t *testing.T) { assert.JSONEq(t, `{ "response": "something went wrong" }`, respBody(t, response)) } +func TestHystrixTimeout(t *testing.T) { + client := NewClient( + WithHTTPTimeout(50*time.Millisecond), + WithCommandName("some_command_name"), + WithHystrixTimeout(10*time.Millisecond), + WithMaxConcurrentRequests(100), + WithErrorPercentThreshold(10), + WithSleepWindow(100), + WithRequestVolumeThreshold(20), + ) + + dummyHandler := func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, http.MethodGet, r.Method) + assert.Equal(t, "application/json", r.Header.Get("Content-Type")) + assert.Equal(t, "en", r.Header.Get("Accept-Language")) + + time.Sleep(20 * time.Millisecond) + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte(`{ "response": "ok" }`)) + } + + server := httptest.NewServer(http.HandlerFunc(dummyHandler)) + defer server.Close() + + req, err := http.NewRequest(http.MethodGet, server.URL, nil) + require.NoError(t, err) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("Accept-Language", "en") + + response, err := client.Do(req) + require.Error(t, err, "expected error at GET request due to hystrix timeout") + + assert.Nil(t, response) + assert.ErrorIs(t, err, hystrix.ErrTimeout, "missing hystrix timeout error") +} + func BenchmarkHystrixHTTPClientRetriesPostOnFailure(b *testing.B) { backoffInterval := 1 * time.Millisecond maximumJitterInterval := 1 * time.Millisecond