Skip to content

Commit

Permalink
Updates for retry changes in 0.6. (#368)
Browse files Browse the repository at this point in the history
* Updates for retry changes in 0.6.

* Added retry info to README.
  • Loading branch information
rofinn authored and ararslan committed Sep 12, 2017
1 parent 084118e commit 9561962
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ Currently, the `@compat` macro supports the following syntaxes:

* There are versions of `InexactError`, `DomainError`, and `OverflowError` that take the same arguments as introduced in Julia 0.7-DEV ([#20005], [#22751], [#22761]).

* `retry` for the more flexible `retry` method introduced in 0.6 which includes support for kwargs ([#19331], [#21419]).

## Renamed functions


Expand Down
57 changes: 57 additions & 0 deletions src/Compat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,65 @@ macro compat(ex...)
esc(_compat(ex[1]))
end


export @compat

if VERSION < v"0.6.0-dev.2042"
immutable ExponentialBackOff
n::Int
first_delay::Float64
max_delay::Float64
factor::Float64
jitter::Float64

function ExponentialBackOff(n, first_delay, max_delay, factor, jitter)
all(x->x>=0, (n, first_delay, max_delay, factor, jitter)) || error("all inputs must be non-negative")
new(n, first_delay, max_delay, factor, jitter)
end
end

"""
ExponentialBackOff(; n=1, first_delay=0.05, max_delay=10.0, factor=5.0, jitter=0.1)
A [`Float64`](@ref) iterator of length `n` whose elements exponentially increase at a
rate in the interval `factor` * (1 ± `jitter`). The first element is
`first_delay` and all elements are clamped to `max_delay`.
"""
ExponentialBackOff(; n=1, first_delay=0.05, max_delay=10.0, factor=5.0, jitter=0.1) =
ExponentialBackOff(n, first_delay, max_delay, factor, jitter)
Base.start(ebo::ExponentialBackOff) = (ebo.n, min(ebo.first_delay, ebo.max_delay))
function Base.next(ebo::ExponentialBackOff, state)
next_n = state[1]-1
curr_delay = state[2]
next_delay = min(ebo.max_delay, state[2] * ebo.factor * (1.0 - ebo.jitter + (rand() * 2.0 * ebo.jitter)))
(curr_delay, (next_n, next_delay))
end
Base.done(ebo::ExponentialBackOff, state) = state[1]<1
Base.length(ebo::ExponentialBackOff) = ebo.n

function retry(f::Function; delays=ExponentialBackOff(), check=nothing)
(args...; kwargs...) -> begin
state = start(delays)
while true
try
return f(args...; kwargs...)
catch e
done(delays, state) && rethrow(e)
if check !== nothing
state, retry_or_not = check(state, e)
retry_or_not || rethrow(e)
end
end
(delay, state) = next(delays, state)
sleep(delay)
end
end
end
else
import Base.ExponentialBackOff
import Base.retry
end

import Base: redirect_stdin, redirect_stdout, redirect_stderr
if VERSION < v"0.6.0-dev.374"
for (F,S) in ((:redirect_stdin, :STDIN), (:redirect_stdout, :STDOUT), (:redirect_stderr, :STDERR))
Expand Down
47 changes: 47 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,53 @@ cd(dirwalk) do
end
rm(dirwalk, recursive=true)

let
# Subset of tests copied from base test/error.jl
function foo_error(c, n)
c[1] += 1
if c[1] <= n
error("foo")
end
return 7
end

# Success on first attempt
c = [0]
@test Compat.retry(foo_error)(c, 0) == 7
@test c[1] == 1

# Success on second attempt
c = [0]
@test Compat.retry(foo_error)(c,1) == 7
@test c[1] == 2

# 2 failed retry attempts, so exception is raised
c = [0]
ex = try
Compat.retry(foo_error, delays=Compat.ExponentialBackOff(n=2))(c, 3)
catch e
e
end

c = [0]
ex = try
Compat.retry(
foo_error,
check=(s,e)->(s, try e.http_status_code == "503" end != true)
)(c, 2)
catch e
e
end
@test typeof(ex) == ErrorException
@test ex.msg == "foo"
@test c[1] == 2

# Functions with keyword arguments
foo_kwargs(x; y=5) = x + y
@test Compat.retry(foo_kwargs)(3) == 8
@test Compat.retry(foo_kwargs)(3; y=4) == 7
end

for os in [:apple, :bsd, :linux, :unix, :windows]
from_base = if VERSION >= v"0.7.0-DEV.914"
Expr(:., Expr(:., :Base, Base.Meta.quot(:Sys)), Base.Meta.quot(Symbol("is", os)))
Expand Down

0 comments on commit 9561962

Please sign in to comment.