-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 ) ).