lib/retry_on_stale.ex
defmodule RetryOnStale do
def retry_on_stale(fun, opts) do
max_attempts = Keyword.fetch!(opts, :max_attempts)
delay_ms = Keyword.fetch!(opts, :delay_ms)
do_retry_on_stale(fun, max_attempts, delay_ms, 1)
end
defp do_retry_on_stale(fun, max_attempts, delay_ms, attempt) do
try do
fun.(attempt)
rescue
e in Ecto.StaleEntryError ->
if attempt < max_attempts do
:timer.sleep(delay_ms)
do_retry_on_stale(fun, max_attempts, delay_ms, attempt + 1)
else
reraise e, __STACKTRACE__
end
end
end
end