-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement exponential backoffs for critical functions
- Loading branch information
Michael Guarino
committed
Aug 8, 2018
1 parent
35db823
commit fe4d588
Showing
8 changed files
with
124 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
defmodule ExlasticSearch.Retry.Decorator do | ||
@moduledoc """ | ||
Decorator for applying retry strategies to a function. Configure with | ||
``` | ||
config :exlasticsearch, :retry, strategy: MyStrategy, additional_opts | ||
``` | ||
""" | ||
use Decorator.Define, retry: 0 | ||
@config Application.get_env(:exlasticsearch, :retry, []) | ||
|
||
def retry(body, _ctx) do | ||
{strategy, config} = Keyword.pop(@config, :strategy, ExlasticSearch.Retry.ExponentialBackoff) | ||
quote do | ||
unquote(strategy).retry(fn -> unquote(body) end, unquote(config)) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
defmodule ExlasticSearch.Retry.ExponentialBackoff do | ||
@moduledoc """ | ||
Retry Strategy implementation utilizing exponential backoffs | ||
""" | ||
@behaviour ExlasticSearch.RetryStrategy | ||
|
||
def retry(fun, opts) do | ||
initial = Keyword.get(opts, :initial, 1) | ||
max = Keyword.get(opts, :max, 3) | ||
jitter = Keyword.get(opts, :jitter, 4) | ||
|
||
do_retry(fun, max, initial, jitter, 0) | ||
end | ||
|
||
defp do_retry(fun, max, _, _, max), do: fun.() | ||
defp do_retry(fun, max, initial, jitter, retry) do | ||
case fun.() do | ||
{:ok, result} -> {:ok, result} | ||
{:error, _} -> | ||
sleep(initial, retry, jitter) | ||
|> :timer.sleep() | ||
|
||
do_retry(fun, max, initial, jitter, retry + 1) | ||
end | ||
end | ||
|
||
defp sleep(initial, retry, jitter) do | ||
jitter = :rand.uniform(jitter) | ||
exp = :math.pow(2, retry) |> round() | ||
jitter + (initial * exp) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
defmodule ExlasticSearch.RetryStrategy do | ||
@moduledoc """ | ||
Behavior for retrying a 0-arity function according to some strategy | ||
""" | ||
@type response :: {:ok, any} | {:error, any} | ||
@type callable :: (-> {:ok, any} | {:error, any}) | ||
@callback retry(fnc :: callable, opts :: list) :: response | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
defmodule ExlasticSearch.RepoTest do | ||
use ExUnit.Case, async: true | ||
alias ExlasticSearch.{ | ||
Repo, | ||
TestModel | ||
} | ||
|
||
setup_all do | ||
Repo.create_index(TestModel) | ||
Repo.create_mapping(TestModel) | ||
:ok | ||
end | ||
|
||
describe "#index" do | ||
test "It will index an element in es" do | ||
model = %ExlasticSearch.TestModel{id: Ecto.UUID.generate()} | ||
{:ok, _} = Repo.index(model) | ||
|
||
assert exists?(model) | ||
end | ||
end | ||
|
||
describe "#bulk" do | ||
test "It will bulk index/delete from es" do | ||
model = %ExlasticSearch.TestModel{id: Ecto.UUID.generate()} | ||
{:ok, _} = Repo.bulk([{:index, model}]) | ||
|
||
assert exists?(model) | ||
end | ||
end | ||
|
||
defp exists?(model) do | ||
case Repo.get(model) do | ||
{:ok, %{found: true}} -> true | ||
_ -> false | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters