Packages
oidcc
3.7.1
3.7.2
3.7.1
3.7.0
3.6.0
3.5.2
3.5.1
3.5.0
retired
3.4.0
3.3.0
3.2.6
3.2.5
3.2.4
3.2.3
3.2.2
3.2.1
3.2.0
3.2.0-beta.3
3.2.0-beta.2
retired
3.2.0-beta.1
retired
3.1.2
3.1.2-beta.1
retired
3.1.1
retired
3.1.0
retired
3.1.0-beta.2
retired
3.1.0-beta.1
retired
3.0.2
3.0.1
retired
3.0.0
retired
3.0.0-rc.6
retired
3.0.0-rc.5
retired
3.0.0-rc.4
retired
3.0.0-rc.3
retired
3.0.0-rc.2
retired
3.0.0-rc.1
retired
3.0.0-alpha.5
retired
3.0.0-alpha.4
retired
3.0.0-alpha.3
retired
3.0.0-alpha.2
retired
3.0.0-alpha.1
retired
2.0.0-alpha.2
retired
2.0.0-alpha.1
retired
1.8.1
retired
1.8.0
retired
1.7.0
retired
1.6.0
retired
1.5.1
retired
1.5.0
retired
1.4.0
retired
1.3.0
retired
1.2.1
retired
1.2.0
retired
1.1.0
retired
1.0.1
retired
1.0.0
retired
OpenID Connect client library for the BEAM.
Current section
Files
Jump to
Current section
Files
src/oidcc_backoff.erl
%% SPDX-FileCopyrightText: 2023 Erlang Ecosystem Foundation
%% SPDX-License-Identifier: Apache-2.0
-module(oidcc_backoff).
-include("internal/doc.hrl").
?MODULEDOC("""
Backoff Handling
Based on [`db_connection`](https://github.com/elixir-ecto/db_connection/blob/8ef1f2ea54922873590b8939f2dad6b031c5b49c/lib/db_connection/backoff.ex#L24)
""").
?MODULEDOC(#{since => <<"3.2.0">>}).
-export_type([type/0]).
-export_type([min/0]).
-export_type([max/0]).
-export_type([state/0]).
-export([handle_retry/4]).
?DOC(#{since => <<"3.2.0">>}).
-type type() :: stop | exponential | random | random_exponential.
?DOC(#{since => <<"3.2.0">>}).
-type min() :: pos_integer().
?DOC(#{since => <<"3.2.0">>}).
-type max() :: pos_integer().
?DOC(#{since => <<"3.2.0">>}).
-opaque state() :: pos_integer() | {pos_integer(), pos_integer()}.
?DOC(false).
-spec handle_retry(Type, Min, Max, State) -> stop | {Wait, State} when
Type :: type(), Min :: min(), Max :: max(), State :: undefined | state(), Wait :: pos_integer().
handle_retry(Type, Min, Max, State) when Min > 0, Max > 0, Max >= Min ->
priv_handle_retry(Type, Min, Max, State).
-spec priv_handle_retry(Type, Min, Max, State) -> stop | {Wait, State} when
Type :: type(), Min :: min(), Max :: max(), State :: undefined | state(), Wait :: pos_integer().
priv_handle_retry(stop, _Min, _Max, undefined) ->
stop;
priv_handle_retry(random, Min, Max, State) ->
{rand(Min, Max), State};
priv_handle_retry(exponential, Min, _Max, undefined) ->
{Min, Min};
priv_handle_retry(exponential, _Min, Max, State) ->
Wait = min(State * 2, Max),
{Wait, Wait};
priv_handle_retry(random_exponential, Min, Max, undefined) ->
Lower = max(Min, Max div 3),
priv_handle_retry(random_exponential, Min, Max, {Lower, Lower});
priv_handle_retry(random_exponential, _Min, Max, {Prev, Lower}) ->
NextMin = min(Prev, Lower),
NextMax = min(Prev * 3, Max),
Next = rand(NextMin, NextMax),
priv_handle_retry(random, NextMin, NextMax, {Next, Lower}).
rand(Min, Max) -> rand:uniform(Max - Min + 1) + Min - 1.