aboutsummaryrefslogtreecommitdiffstats
path: root/src/gun.erl
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2019-07-27 16:42:00 +0200
committerLoïc Hoguin <[email protected]>2019-07-27 16:42:00 +0200
commit50ff97bf82cd146cb289e5b9fbd864bbcc9c30d9 (patch)
tree5c2afd3d9a1c96868dbfc3cc0456422607d68f94 /src/gun.erl
parent02fed8a1422c9ca6f33127509eebd244f0a74d3f (diff)
downloadgun-50ff97bf82cd146cb289e5b9fbd864bbcc9c30d9.tar.gz
gun-50ff97bf82cd146cb289e5b9fbd864bbcc9c30d9.tar.bz2
gun-50ff97bf82cd146cb289e5b9fbd864bbcc9c30d9.zip
Add the retry_fun option for different backoff strategies
Diffstat (limited to 'src/gun.erl')
-rw-r--r--src/gun.erl20
1 files changed, 17 insertions, 3 deletions
diff --git a/src/gun.erl b/src/gun.erl
index bb275f5..74866ec 100644
--- a/src/gun.erl
+++ b/src/gun.erl
@@ -116,6 +116,8 @@
http2_opts => http2_opts(),
protocols => [http | http2],
retry => non_neg_integer(),
+ retry_fun => fun((non_neg_integer(), opts())
+ -> #{retries => non_neg_integer(), timeout => pos_integer()}),
retry_timeout => pos_integer(),
supervise => boolean(),
tcp_opts => [gen_tcp:connect_option()],
@@ -279,6 +281,8 @@ check_options([Opt = {protocols, L}|Opts]) when is_list(L) ->
end;
check_options([{retry, R}|Opts]) when is_integer(R), R >= 0 ->
check_options(Opts);
+check_options([{retry_fun, F}|Opts]) when is_function(F, 2) ->
+ check_options(Opts);
check_options([{retry_timeout, T}|Opts]) when is_integer(T), T >= 0 ->
check_options(Opts);
check_options([{supervise, B}|Opts]) when B =:= true; B =:= false ->
@@ -770,15 +774,25 @@ default_transport(_) -> tcp.
%% @todo This is where we would implement the backoff mechanism presumably.
not_connected(_, {retries, 0, Reason}, State) ->
{stop, {shutdown, Reason}, State};
-not_connected(_, {retries, Retries, _}, State=#state{opts=Opts}) ->
- Timeout = maps:get(retry_timeout, Opts, 5000),
+not_connected(_, {retries, Retries0, _}, State=#state{opts=Opts}) ->
+ Fun = maps:get(retry_fun, Opts, fun default_retry_fun/2),
+ #{
+ timeout := Timeout,
+ retries := Retries
+ } = Fun(Retries0, Opts),
{next_state, domain_lookup, State,
- {state_timeout, Timeout, {retries, Retries - 1, not_connected}}};
+ {state_timeout, Timeout, {retries, Retries, not_connected}}};
not_connected({call, From}, {stream_info, _}, _) ->
{keep_state_and_data, {reply, From, {error, not_connected}}};
not_connected(Type, Event, State) ->
handle_common(Type, Event, ?FUNCTION_NAME, State).
+default_retry_fun(Retries, Opts) ->
+ #{
+ retries => Retries - 1,
+ timeout => maps:get(retry_timeout, Opts, 5000)
+ }.
+
domain_lookup(_, {retries, Retries, _}, State=#state{host=Host, port=Port, opts=Opts,
event_handler=EvHandler, event_handler_state=EvHandlerState0}) ->
TransOpts = maps:get(tcp_opts, Opts, []),