Skip to content

Instantly share code, notes, and snippets.

@bokner
Last active August 29, 2015 14:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bokner/b46f89c76d078b83ecf9 to your computer and use it in GitHub Desktop.
Save bokner/b46f89c76d078b83ecf9 to your computer and use it in GitHub Desktop.
Function call with attempts of recovery on failure
%% @author bokner
%% @doc Implementation of function call with recovery
-module(recovery_test).
%% ====================================================================
%% API functions
%% ====================================================================
-export([test/1]).
-define(RECOVERY_ATTEMPT_KEY, attempts).
random_failure(N) ->
<<A:32, B:32, C:32>> = crypto:rand_bytes(12),
random:seed({A,B,C}),
case random:uniform(N) of
N ->
success;
M ->
case N div 2 of
M ->
io:format("Exiting"),
exit(failure);
_ ->
failure
end
end.
%% ====================================================================
%% Internal functions
%% ====================================================================
handle_error(Fun, MaxAttempts) ->
Attempt = case erase(?RECOVERY_ATTEMPT_KEY) of
undefined -> 2;
A when A >= MaxAttempts -> exit(failed_with_recovery);
A -> A + 1
end,
io:format("Failure~nAttempt ~p of ~p...~n", [Attempt, MaxAttempts]),
put(?RECOVERY_ATTEMPT_KEY, Attempt),
Fun().
test(N) ->
try random_failure(N) of
success ->
io:format("Success after ~p attempts", [case get(?RECOVERY_ATTEMPT_KEY) of
undefined -> 1;
A -> A
end]);
failure ->
handle_error(fun() ->
test(N)
end, 3)
catch Error:Reason ->
handle_error(fun() ->
test(N)
end, 3)
after
erase(?RECOVERY_ATTEMPT_KEY)
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment