Current section

Files

Jump to
retry lib retry.ex
Raw

lib/retry.ex

defmodule Retry do
@doc false
defmacro __using__(_opts) do
quote do
import Retry
defmacro retry({ :in, _, [retries, sleep] }, do: block) do
quote do
run = fn(attempt, self) ->
if attempt <= unquote(retries) do
try do
case unquote(block) do
{:error, _} ->
:timer.sleep(unquote(sleep))
self.(attempt + 1, self)
result -> result
end
rescue
e in RuntimeError ->
:timer.sleep(unquote(sleep))
self.(attempt + 1, self)
end
else
unquote(block)
end
end
run.(1, run)
end
end
defmacro backoff(timeout, do: block) do
quote do
run = fn(attempt, self) ->
# http://dthain.blogspot.com.au/2009/02/exponential-backoff-in-distributed.html
sleep = :erlang.round((1 + :random.uniform) * 10 * :math.pow(2, attempt))
if sleep <= unquote(timeout) do
try do
case unquote(block) do
{:error, _} ->
:timer.sleep(sleep)
self.(attempt + 1, self)
result -> result
end
rescue
e in RuntimeError ->
:timer.sleep(sleep)
self.(attempt + 1, self)
end
else
unquote(block)
end
end
run.(1, run)
end
end
end
end
end