Skip to content

Commit 50f9bcf

Browse files
biacarmichaelklishin
authored andcommitted
Adding retries to AWS API calls
Adding retries to AWS API calls
1 parent 11760f9 commit 50f9bcf

File tree

3 files changed

+34
-3
lines changed

3 files changed

+34
-3
lines changed

deps/rabbitmq_aws/include/rabbitmq_aws.hrl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@
4343

4444
-define(METADATA_TOKEN, "X-aws-ec2-metadata-token").
4545

46+
-define(LINEAR_BACK_OFF_MILLIS, 500).
47+
-define(MAX_RETRIES, 5).
48+
4649
-type access_key() :: nonempty_string().
4750
-type secret_access_key() :: nonempty_string().
4851
-type expiration() :: calendar:datetime() | undefined.

deps/rabbitmq_aws/src/rabbitmq_aws.erl

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -543,10 +543,22 @@ ensure_credentials_valid() ->
543543
%% @end
544544
api_get_request(Service, Path) ->
545545
rabbit_log:debug("Invoking AWS request {Service: ~p; Path: ~p}...", [Service, Path]),
546+
api_get_request_with_retries(Service, Path, ?MAX_RETRIES, ?LINEAR_BACK_OFF_MILLIS).
547+
548+
549+
-spec api_get_request_with_retries(string(), path(), integer(), integer()) -> result().
550+
%% @doc Invoke an API call to an AWS service with retries.
551+
%% @end
552+
api_get_request_with_retries(Service, Path, Retries, WaitTimeBetweenRetries) ->
546553
ensure_credentials_valid(),
547554
case get(Service, Path) of
548555
{ok, {_Headers, Payload}} -> rabbit_log:debug("AWS request: ~s~nResponse: ~p", [Path, Payload]),
549556
{ok, Payload};
550557
{error, {credentials, _}} -> {error, credentials};
551-
{error, Message, _} -> {error, Message}
558+
{error, Message, _} -> case Retries of
559+
0 -> {error, Message};
560+
_ -> rabbit_log:warning("Error occurred ~s~nWill retry AWS request, remaining retries: ~b", [Message, Retries]),
561+
timer:sleep(WaitTimeBetweenRetries),
562+
api_get_request_with_retries(Service, Path, Retries - 1, WaitTimeBetweenRetries)
563+
end
552564
end.

deps/rabbitmq_aws/test/src/rabbitmq_aws_tests.erl

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ api_get_request_test_() ->
479479
?assertEqual({error, credentials}, Result)
480480
end
481481
},
482-
{"AWS service API request failed - API error",
482+
{"AWS service API request failed - API error with persistent failure",
483483
fun() ->
484484
State = #state{access_key = "ExpiredKey",
485485
secret_access_key = "ExpiredAccessKey",
@@ -489,11 +489,27 @@ api_get_request_test_() ->
489489
{ok, Pid} = rabbitmq_aws:start_link(),
490490
rabbitmq_aws:set_region("us-east-1"),
491491
rabbitmq_aws:set_credentials(State),
492-
Result = rabbitmq_aws:api_get_request("AWS", "API"),
492+
Result = rabbitmq_aws:api_get_request_with_retries("AWS", "API", 3, 1),
493493
ok = gen_server:stop(Pid),
494494
?assertEqual({error, "invalid input"}, Result),
495495
meck:validate(httpc)
496496
end
497+
},
498+
{"AWS service API request succeeded after a transient error",
499+
fun() ->
500+
State = #state{access_key = "ExpiredKey",
501+
secret_access_key = "ExpiredAccessKey",
502+
region = "us-east-1",
503+
expiration = {{3016, 4, 1}, {12, 0, 0}}},
504+
meck:expect(httpc, request, 4, meck:seq([{error, "invalid input"}, {ok, {{"HTTP/1.0", 200, "OK"}, [{"content-type", "application/json"}], "{\"data\": \"value\"}"}}])),
505+
{ok, Pid} = rabbitmq_aws:start_link(),
506+
rabbitmq_aws:set_region("us-east-1"),
507+
rabbitmq_aws:set_credentials(State),
508+
Result = rabbitmq_aws:api_get_request_with_retries("AWS", "API", 3, 1),
509+
ok = gen_server:stop(Pid),
510+
?assertEqual({ok, [{"data","value"}]}, Result),
511+
meck:validate(httpc)
512+
end
497513
}
498514
]
499515
}.

0 commit comments

Comments
 (0)