@@ -3,9 +3,7 @@ module RetryRequest
3
3
using Sockets, LoggingExtras, MbedTLS, OpenSSL
4
4
using .. IOExtras, .. Messages, .. Strings, .. ExceptionRequest, .. Exceptions
5
5
6
- export retrylayer
7
-
8
- FALSE (x... ) = false
6
+ export retrylayer, retry_check, isrecoverable
9
7
10
8
"""
11
9
retrylayer(handler) -> handler
@@ -21,13 +19,12 @@ e.g. `Sockets.DNSError`, `Base.EOFError` and `HTTP.StatusError`
21
19
(if status is `5xx`).
22
20
"""
23
21
function retrylayer (handler)
24
- return function (req:: Request ; retry:: Bool = true , retries:: Int = 4 ,
25
- retry_delays:: ExponentialBackOff = ExponentialBackOff (n = retries, factor= 3.0 ), retry_check= FALSE,
26
- retry_non_idempotent:: Bool = false , kw... )
27
- if ! retry || retries == 0
28
- # no retry
29
- return handler (req; kw... )
30
- end
22
+ return function (req:: Request ; retries:: Int = 4 , retry:: Bool = retries> 0 ,
23
+ retry_delays= ExponentialBackOff (n= retries, factor= 3.0 ), retry_check= retry_check,
24
+ retry_non_idempotent:: Bool = false , kw...
25
+ )
26
+ retry || return handler (req; kw... ) # no retry
27
+ retries = length (retry_delays)
31
28
req. context[:allow_retries ] = true
32
29
req. context[:retryattempt ] = 0
33
30
if retry_non_idempotent
@@ -39,16 +36,10 @@ function retrylayer(handler)
39
36
req_body_is_marked = true
40
37
mark (req. body)
41
38
end
42
- retryattempt = Ref (0 )
43
- retry_request = Base. retry (handler,
44
- delays= retry_delays,
45
- check= (s, ex) -> begin
46
- retryattempt[] += 1
47
- req. context[:retryattempt ] = retryattempt[]
48
- retry = retryable (req) || retryablebody (req) && _retry_check (s, ex, req, retry_check)
49
- if retryattempt[] == retries
50
- req. context[:retrylimitreached ] = true
51
- end
39
+ retry_request = Base. retry (handler, delays= retry_delays,
40
+ check = (s, ex) -> begin
41
+ req. context[:retrylimitreached ] = (req. context[:retryattempt ] += 1 ) > retries
42
+ retry = retryable (req) && _retry_check (s, ex, req, retry_check)
52
43
if retry
53
44
@debugv 1 " 🔄 Retry $ex : $(sprintcompact (req)) "
54
45
reset! (req. response)
@@ -72,6 +63,14 @@ function _retry_check(s, ex, req, check)
72
63
resp_body = get (req. context, :response_body , nothing )
73
64
return check (s, ex, req, resp_body != = nothing ? resp : nothing , resp_body)
74
65
end
66
+ retry_check (s, ex, x... ) = isrecoverable (ex)
67
+ isrecoverable (e) = false
68
+ isrecoverable (e:: Union{Base.EOFError, Base.IOError, MbedTLS.MbedException, OpenSSL.OpenSSLError} ) = true
69
+ isrecoverable (e:: ArgumentError ) = e. msg == " stream is closed or unusable"
70
+ isrecoverable (e:: Sockets.DNSError ) = true
71
+ isrecoverable (e:: ConnectError ) = true
72
+ isrecoverable (e:: RequestError ) = isrecoverable (e. error)
73
+ isrecoverable (e:: StatusError ) = retryable (e. status)
75
74
76
75
function no_retry_reason (ex, req)
77
76
buf = IOBuffer ()
0 commit comments