diff --git a/src/Retry.jl b/src/Retry.jl index 3c90da5..cfe1385 100644 --- a/src/Retry.jl +++ b/src/Retry.jl @@ -1,6 +1,11 @@ module Retry -export @repeat, @protected +__precompile__(true) + +export @repeat, @protected, efield, ecode + +efield(x, f, default=nothing) = f in fieldnames(x) ? getfield(x, f) : default +ecode(x) = efield(x, :code) include("repeat_try.jl") include("protected_try.jl") diff --git a/src/protected_try.jl b/src/protected_try.jl index 340fe1b..7dd5a93 100644 --- a/src/protected_try.jl +++ b/src/protected_try.jl @@ -62,7 +62,6 @@ macro protected(try_expr::Expr) if_expr = check_macro_if(expr) (condition, action) = if_expr.args - if_expr.args[1] = :(try $condition catch false end) # Clear exception variable at end of "@ignore if..." block... push!(action.args, :($exception = nothing)) diff --git a/src/repeat_try.jl b/src/repeat_try.jl index 84a92f5..c67fbc6 100644 --- a/src/repeat_try.jl +++ b/src/repeat_try.jl @@ -126,7 +126,9 @@ end function esc_args!(expr::Expr) for (i, arg) in enumerate(expr.args) - expr.args[i] = esc(arg) + if isa(arg, Symbol) || arg.head != :line + expr.args[i] = esc(arg) + end end end @@ -140,11 +142,8 @@ macro repeat(max, try_expr::Expr) esc_args!(try_expr) try_expr.args[3] = catch_block - # Check for nothing exception at start of catch block... - unshift!(catch_block.args, :($exception == nothing && rethrow($exception))) - - # Rethrow at end of catch block... - push!(catch_block.args, :($exception == nothing || rethrow($exception))) + max = esc(max) + exception = esc(exception) for (i, expr) in enumerate(catch_block.args) @@ -159,25 +158,24 @@ macro repeat(max, try_expr::Expr) if_expr = check_macro_if(expr) (condition, action) = if_expr.args - if_expr.args[1] = :(try $(esc(condition)) catch e false end) + if_expr.args[1] = esc(condition) + esc_args!(action) # Clear exception variable at end of "@ignore if..." block... if handler == "@ignore" - push!(action.args, :($exception = nothing)) + push!(action.args, :(ignore = true)) end - esc_args!(action) - # Loop to try again at end of "@retry if..." block... if handler == "@retry" - push!(action.args, :(if i < $(esc(max)) continue end)) + push!(action.args, :(if i < $max continue end)) end # Add exponentially increasing delay with random jitter, # and loop to try again at end of "@delay_retry if..." block... if handler == "@delay_retry" push!(action.args, quote - if i < $(esc(max)) + if i < $max sleep(delay * (0.8 + (0.4 * rand()))) delay *= 10 continue @@ -187,17 +185,24 @@ macro repeat(max, try_expr::Expr) # Replace @ignore/@retry macro call with modified if expression... catch_block.args[i] = if_expr - else + elseif expr.head != :line catch_block.args[i] = esc(expr) end end + # Check for nothing exception at start of catch block... + insert!(catch_block.args, 2, :($exception == nothing && rethrow())) + unshift!(catch_block.args, :(ignore = false)) + + # Rethrow at end of catch block... + push!(catch_block.args, :(ignore || rethrow($exception))) + # Build retry expression... quote delay = 0.05 result = false - for i in 1:$(esc(max)) + for i in 1:$max result = $try_expr break end @@ -207,7 +212,6 @@ macro repeat(max, try_expr::Expr) end - #==============================================================================# # End of file. #==============================================================================# diff --git a/test/runtests.jl b/test/runtests.jl index 8680f14..e0fc688 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -29,7 +29,7 @@ end @test_throws TestException @protected try throw(TestException(7)) catch e - @ignore if e.code == "Nothing to see here" end + @ignore if ecode(e) == "Nothing to see here" end end @@ -38,7 +38,7 @@ end @test @protected try throw(TestException(7)) catch e - @ignore if e.code == 7 end + @ignore if ecode(e) == 7 end end @@ -58,7 +58,7 @@ count = 0 global count += 1 throw(TestException(7)) catch e - @retry if e.code == 7 end + @retry if ecode(e) == 7 end end @test count == 4 @@ -70,7 +70,7 @@ count = 0 global count += 1 throw(TestException(5)) catch e - @retry if e.code == 7 end + @retry if ecode(e) == 7 end end @test count == 1 @@ -82,7 +82,7 @@ count = 0 global count += 1 throw(TestException(7)) catch e - @ignore if e.code == 7 end + @ignore if ecode(e) == 7 end end @test count == 1 @@ -102,7 +102,7 @@ i = -1 count += 1 throw(TestException(7)) catch e - @delay_retry if e.code == 7 end + @delay_retry if ecode(e) == 7 end end @test count == 3 @@ -118,8 +118,8 @@ count = 0 global count += 1 throw(TestException(count)) catch e - @retry if e.code < 3 end - @ignore if e.code == 3 end + @retry if ecode(e) < 3 end + @ignore if ecode(e) == 3 end end @test count == 2 @@ -131,8 +131,8 @@ count = 0 global count += 1 throw(TestException(count)) catch e - @retry if e.code < 3 end - @ignore if e.code == 3 end + @retry if ecode(e) < 3 end + @ignore if ecode(e) == 3 end end @test count == 3 @@ -144,8 +144,8 @@ count = 0 global count += 1 throw(TestException(count)) catch e - @retry if e.code < 3 end - @ignore if e.code == 3 end + @retry if ecode(e) < 3 end + @ignore if ecode(e) == 3 end end @test count == 3