Current section

Files

Jump to
erlang_adk src adk_retry.erl
Raw

src/adk_retry.erl

%% @doc adk_retry - Retry mechanism with exponential backoff.
-module(adk_retry).
-export([execute/2, execute/4]).
-type retry_opts() :: #{
max_attempts => pos_integer(),
initial_delay => pos_integer(),
max_delay => pos_integer(),
backoff_factor => float()
}.
%% @doc Execute a function with default retry options.
-spec execute(Fun :: fun(() -> {ok, term()} | {error, term()}), retry_opts()) -> {ok, term()} | {error, term()}.
execute(Fun, Opts) ->
MaxAttempts = maps:get(max_attempts, Opts, 3),
InitialDelay = maps:get(initial_delay, Opts, 1000),
execute(Fun, MaxAttempts, InitialDelay, Opts).
execute(Fun, 1, _Delay, _Opts) ->
%% Last attempt
Fun();
execute(Fun, AttemptsLeft, Delay, Opts) ->
case Fun() of
{ok, Result} -> {ok, Result};
{error, _Reason} ->
timer:sleep(Delay),
NextDelay = erlang:min(
maps:get(max_delay, Opts, 10000),
erlang:round(Delay * maps:get(backoff_factor, Opts, 2.0))
),
execute(Fun, AttemptsLeft - 1, NextDelay, Opts)
end.