@@ -3,12 +3,14 @@ package zcnbridge
33import (
44 "encoding/json"
55 "fmt"
6- coreClient "github.com/0chain/gosdk/core/client"
76 "io"
87 "math"
98 "net/http"
109 "strings"
1110 "sync"
11+ "time"
12+
13+ coreClient "github.com/0chain/gosdk/core/client"
1214
1315 "github.com/0chain/gosdk/core/common"
1416 "github.com/0chain/gosdk/zcnbridge/errors"
@@ -41,6 +43,14 @@ type (
4143 eventsChannelType chan []JobResult
4244)
4345
46+ const (
47+ // Represents max amount of retries, when timeout status was received
48+ maxCallbackRetries = 5
49+
50+ // Represents callback retry delay for http calls, when timeout status was received
51+ callbackRetryDelay = time .Second * 5
52+ )
53+
4454var (
4555 client * http.Client
4656)
@@ -282,7 +292,7 @@ func queryAuthorizer(au *AuthorizerNode, request *requestHandler, responseChanne
282292 }
283293 req .URL .RawQuery = q .Encode ()
284294 Logger .Info (req .URL .String ())
285- resp , body := readResponse (client .Do (req ))
295+ resp , body := readResponse (func () ( * http. Response , error ) { return client .Do (req ) } )
286296 resp .AuthorizerID = au .ID
287297
288298 if resp .error != nil {
@@ -313,22 +323,66 @@ func queryAuthorizer(au *AuthorizerNode, request *requestHandler, responseChanne
313323 responseChannel <- resp
314324}
315325
316- func readResponse (response * http.Response , err error ) (res * authorizerResponse , body []byte ) {
326+ func readResponse (responseCallback func () ( * http.Response , error ) ) (res * authorizerResponse , body []byte ) {
317327 res = & authorizerResponse {}
318- if err != nil {
319- err = errors .Wrap ("authorizer_post_process" , "failed to call the authorizer" , err )
320- Logger .Error ("request response error" , zap .Error (err ))
321- }
322328
323- if response == nil {
324- res .error = err
325- Logger .Error ("response is empty" , zap .Error (err ))
326- return res , nil
329+ var (
330+ retryTicker * time.Ticker
331+ retryCounter int
332+
333+ response * http.Response
334+ err error
335+ )
336+
337+ for {
338+ if retryTicker != nil {
339+ select {
340+ case <- retryTicker .C :
341+ default :
342+ }
343+ }
344+
345+ response , err = responseCallback ()
346+ if response == nil {
347+ res .error = err
348+ Logger .Error ("response is empty" , zap .Error (err ))
349+ return res , nil
350+ }
351+
352+ if err != nil {
353+ err = errors .Wrap ("authorizer_post_process" , "failed to call the authorizer" , err )
354+ Logger .Error ("request response error" , zap .Error (err ))
355+ }
356+
357+ if response .StatusCode == 408 {
358+ if retryTicker == nil {
359+ retryTicker = time .NewTicker (callbackRetryDelay )
360+ }
361+
362+ if retryCounter >= maxCallbackRetries {
363+ err = errors .Wrap ("authorizer_post_process" , fmt .Sprintf ("error %d" , response .StatusCode ), err )
364+ Logger .Error ("request response status" , zap .Error (err ))
365+
366+ break
367+ }
368+
369+ retryCounter ++
370+
371+ continue
372+ }
373+
374+ if response .StatusCode >= 400 {
375+ err = errors .Wrap ("authorizer_post_process" , fmt .Sprintf ("error %d" , response .StatusCode ), err )
376+ Logger .Error ("request response status" , zap .Error (err ))
377+
378+ break
379+ }
380+
381+ break
327382 }
328383
329- if response .StatusCode >= 400 {
330- err = errors .Wrap ("authorizer_post_process" , fmt .Sprintf ("error %d" , response .StatusCode ), err )
331- Logger .Error ("request response status" , zap .Error (err ))
384+ if retryTicker != nil {
385+ retryTicker .Stop ()
332386 }
333387
334388 body , er := io .ReadAll (response .Body )
0 commit comments