Current section

Files

Jump to
persevero src persevero.erl
Raw

src/persevero.erl

-module(persevero).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([all_errors/1, custom_backoff/2, no_backoff/0, constant_backoff/1, linear_backoff/2, exponential_backoff/2, apply_constant/2, apply_jitter/2, apply_multiplier/2, apply_cap/2, execute_with_wait/5, execute/4]).
-export_type([error/1, retry_data/2]).
-type error(HPM) :: {retries_exhausted, list(HPM)} | {unallowed_error, HPM}.
-type retry_data(HPN, HPO) :: {retry_data,
{ok, HPN} | {error, error(HPO)},
list(integer())}.
-file("/Users/josephlyons/Projects/Personal/gleam/persevero/src/persevero.gleam", 29).
-spec all_errors(any()) -> boolean().
all_errors(_) ->
true.
-file("/Users/josephlyons/Projects/Personal/gleam/persevero/src/persevero.gleam", 34).
-spec custom_backoff(integer(), fun((integer()) -> integer())) -> gleam@yielder:yielder(integer()).
custom_backoff(Wait_time, Next_wait_time) ->
gleam@yielder:unfold(
Wait_time,
fun(Acc) -> {next, Acc, Next_wait_time(Acc)} end
).
-file("/Users/josephlyons/Projects/Personal/gleam/persevero/src/persevero.gleam", 42).
-spec no_backoff() -> gleam@yielder:yielder(integer()).
no_backoff() ->
custom_backoff(0, fun(_) -> 0 end).
-file("/Users/josephlyons/Projects/Personal/gleam/persevero/src/persevero.gleam", 48).
-spec constant_backoff(integer()) -> gleam@yielder:yielder(integer()).
constant_backoff(Wait_time) ->
custom_backoff(Wait_time, fun(Previous) -> Previous + 0 end).
-file("/Users/josephlyons/Projects/Personal/gleam/persevero/src/persevero.gleam", 56).
-spec linear_backoff(integer(), integer()) -> gleam@yielder:yielder(integer()).
linear_backoff(Wait_time, Step) ->
custom_backoff(Wait_time, fun(Previous) -> Previous + Step end).
-file("/Users/josephlyons/Projects/Personal/gleam/persevero/src/persevero.gleam", 64).
-spec exponential_backoff(integer(), integer()) -> gleam@yielder:yielder(integer()).
exponential_backoff(Wait_time, Factor) ->
custom_backoff(Wait_time, fun(Previous) -> Previous * Factor end).
-file("/Users/josephlyons/Projects/Personal/gleam/persevero/src/persevero.gleam", 85).
-spec apply_constant(gleam@yielder:yielder(integer()), integer()) -> gleam@yielder:yielder(integer()).
apply_constant(Wait_stream, Adjustment) ->
_pipe = Wait_stream,
gleam@yielder:map(
_pipe,
fun(_capture) -> gleam@int:add(_capture, Adjustment) end
).
-file("/Users/josephlyons/Projects/Personal/gleam/persevero/src/persevero.gleam", 74).
-spec apply_jitter(gleam@yielder:yielder(integer()), integer()) -> gleam@yielder:yielder(integer()).
apply_jitter(Wait_stream, Upper_bound) ->
apply_constant(Wait_stream, gleam@int:random(Upper_bound) + 1).
-file("/Users/josephlyons/Projects/Personal/gleam/persevero/src/persevero.gleam", 93).
-spec apply_multiplier(gleam@yielder:yielder(integer()), integer()) -> gleam@yielder:yielder(integer()).
apply_multiplier(Wait_stream, Factor) ->
_pipe = Wait_stream,
gleam@yielder:map(
_pipe,
fun(_capture) -> gleam@int:multiply(_capture, Factor) end
).
-file("/Users/josephlyons/Projects/Personal/gleam/persevero/src/persevero.gleam", 101).
-spec apply_cap(gleam@yielder:yielder(integer()), integer()) -> gleam@yielder:yielder(integer()).
apply_cap(Wait_stream, Max_wait_time) ->
_pipe = Wait_stream,
gleam@yielder:map(
_pipe,
fun(_capture) -> gleam@int:min(_capture, Max_wait_time) end
).
-file("/Users/josephlyons/Projects/Personal/gleam/persevero/src/persevero.gleam", 161).
-spec do_execute(
gleam@yielder:yielder(integer()),
fun((HQX) -> boolean()),
integer(),
fun((integer()) -> {ok, HQY} | {error, HQX}),
fun((integer()) -> nil),
list(integer()),
list(HQX),
integer()
) -> retry_data(HQY, HQX).
do_execute(
Wait_stream,
Allow,
Max_attempts,
Operation,
Wait_function,
Wait_time_acc,
Errors_acc,
Attempt_number
) ->
case begin
_pipe = Wait_stream,
gleam@yielder:step(_pipe)
end of
{next, Wait_time, Wait_stream@1} ->
Wait_function(Wait_time),
Wait_time_acc@1 = [Wait_time | Wait_time_acc],
case Operation(Attempt_number) of
{ok, Result} ->
{retry_data,
{ok, Result},
begin
_pipe@1 = Wait_time_acc@1,
lists:reverse(_pipe@1)
end};
{error, Error} ->
case Allow(Error) of
true ->
do_execute(
Wait_stream@1,
Allow,
Max_attempts,
Operation,
Wait_function,
Wait_time_acc@1,
[Error | Errors_acc],
Attempt_number + 1
);
false ->
{retry_data,
{error, {unallowed_error, Error}},
begin
_pipe@2 = Wait_time_acc@1,
lists:reverse(_pipe@2)
end}
end
end;
done ->
{retry_data,
{error,
{retries_exhausted,
begin
_pipe@3 = Errors_acc,
lists:reverse(_pipe@3)
end}},
begin
_pipe@4 = Wait_time_acc,
lists:reverse(_pipe@4)
end}
end.
-file("/Users/josephlyons/Projects/Personal/gleam/persevero/src/persevero.gleam", 131).
-spec execute_with_wait(
gleam@yielder:yielder(integer()),
fun((HQQ) -> boolean()),
integer(),
fun((integer()) -> {ok, HQR} | {error, HQQ}),
fun((integer()) -> nil)
) -> retry_data(HQR, HQQ).
execute_with_wait(Wait_stream, Allow, Max_attempts, Operation, Wait_function) ->
case Max_attempts =< 0 of
true ->
{retry_data, {error, {retries_exhausted, []}}, []};
false ->
Wait_stream@1 = begin
_pipe = Wait_stream,
gleam@yielder:take(_pipe, Max_attempts - 1)
end,
Wait_stream@2 = begin
_pipe@1 = gleam@yielder:from_list([0]),
_pipe@2 = gleam@yielder:append(_pipe@1, Wait_stream@1),
gleam@yielder:map(
_pipe@2,
fun(_capture) -> gleam@int:max(_capture, 0) end
)
end,
do_execute(
Wait_stream@2,
Allow,
Max_attempts,
Operation,
Wait_function,
[],
[],
0
)
end.
-file("/Users/josephlyons/Projects/Personal/gleam/persevero/src/persevero.gleam", 115).
-spec execute(
gleam@yielder:yielder(integer()),
fun((HQJ) -> boolean()),
integer(),
fun(() -> {ok, HQK} | {error, HQJ})
) -> {ok, HQK} | {error, error(HQJ)}.
execute(Wait_stream, Allow, Max_attempts, Operation) ->
erlang:element(
2,
execute_with_wait(
Wait_stream,
Allow,
Max_attempts,
fun(_) -> Operation() end,
fun gleam_erlang_ffi:sleep/1
)
).