Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misc doc changes #39

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 26 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
/_build
/cover
/deps
/doc
# The directory Mix will write compiled artifacts to.
/_build/

# If you run "mix test --cover", coverage assets end up here.
/cover/

# The directory Mix downloads your dependencies sources to.
/deps/

# Where third-party dependencies like ExDoc output generated docs.
/doc/

# Ignore .fetch files in case you like to edit your project deps locally.
/.fetch

# If the VM crashes, it generates a dump, let's ignore it too.
erl_crash.dump

# Also ignore archive artifacts (built via "mix archive.build").
*.ez

# Ignore package tarball (built via "mix hex.build").
retry-*.tar

# Temporary files for e.g. tests
/tmp

# Misc
.idea
*.iml
.elixir_ls
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ matrix:
- elixir: '1.8'
otp_release: '21.1'
- elixir: '1.8'
otp_release: '22.0'
otp_release: '22.0'
- elixir: '1.9'
otp_release: '20.3'
- elixir: '1.9'
Expand Down
20 changes: 10 additions & 10 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
Copyright 2014 Safwan Kamarrudin
Copyright 2014 Safwan Kamarrudin

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
43 changes: 28 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
[![Build Status](https://travis-ci.org/safwank/ElixirRetry.svg?branch=master)](https://travis-ci.org/safwank/ElixirRetry)

# ElixirRetry

[![Build Status](https://travis-ci.org/safwank/ElixirRetry.svg?branch=master)](https://travis-ci.org/safwank/ElixirRetry)
[![Module Version](https://img.shields.io/hexpm/v/retry.svg)](https://hex.pm/packages/retry)
[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/retry/)
[![Total Download](https://img.shields.io/hexpm/dt/retry.svg)](https://hex.pm/packages/retry)
[![License](https://img.shields.io/hexpm/l/retry.svg)](https://github.com/safwank/ElixirRetry/blob/master/LICENSE)
[![Last Updated](https://img.shields.io/github/last-commit/safwank/ElixirRetry.svg)](https://github.com/safwank/ElixirRetry/commits/master)

Simple Elixir macros for linear retry, exponential backoff and wait with composable delays.

## Installation

Add `retry` to your list of dependencies in `mix.exs`:

```elixir
def deps do
[{:retry, "~> 0.14"}]
end
```

Ensure `retry` is started before your application:
Add `:retry` to your list of dependencies in `mix.exs`:

```elixir
def application do
[applications: [:retry]]
end
def deps do
[
{:retry, "~> 0.14"}
]
end
```

## Documentation
Expand Down Expand Up @@ -107,7 +106,7 @@ result = retry with: Stream.cycle([500]) do
after
result -> result
else
error -> error
error -> error
end
```

Expand Down Expand Up @@ -138,3 +137,17 @@ The `after` block evaluates only when the `do` block returns a truthy value.
On the other hand, the `else` block evaluates only when the `do` block remains falsy after timeout.

Pretty nifty for those pesky asynchronous tests and building more reliable systems in general!

## License

Copyright (c) 2014 Safwan Kamarrudin

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
46 changes: 25 additions & 21 deletions lib/retry.ex
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
defmodule Retry do
@moduledoc """
Provides a convenient interface for retrying behavior.

Provides a convenient interface to retrying behavior. All durations are
specified in milliseconds.
All durations are specified in milliseconds.

Examples
The first retry will exponentially increase the delay, fudging each delay up
to 10%, until the delay reaches 1 second and then give up after 10 seconds.

use Retry
import Stream
Expand All @@ -13,23 +14,27 @@ defmodule Retry do
# interact with external service
end

retry with: linear_backoff(10, 2) |> cap(1_000) |> take(10) do
# interact with external service
end
The second retry will linearly increase the retry by a factor of 2 from 10ms
giving up after 10 attempts.

retry with: cycle([500]) |> take(10) do
use Retry
import Stream

retry with: linear_backoff(10, 2) |> cap(1_000) |> take(10) do
# interact with external service
end

The first retry will exponentially increase the delay, fudging each delay up
to 10%, until the delay reaches 1 second and then give up after 10 seconds.

The second retry will linearly increase the retry by a factor of 2 from 10ms giving up after 10 attempts.

The third example shows how we can produce a delay stream using standard
`Stream` functionality. Any stream of integers may be used as the value of
`with:`.

use Retry
import Stream

retry with: cycle([500]) |> take(10) do
# interact with external service
end

"""

@default_retry_options [atoms: [:error], rescue_only: [RuntimeError]]
Expand All @@ -43,23 +48,23 @@ defmodule Retry do
end

@doc """

Retry a block of code delaying between each attempt the duration specified by
the next item in the `with` delay stream.

If the block returns any of the atoms specified in `atoms`, a retry will be attempted.
Other atoms or atom-result tuples will not be retried. If `atoms` is not specified,
it defaults to `[:error]`.

Similary, if the block raises any of the exceptions specified in `rescue_only`, a retry
Similarly, if the block raises any of the exceptions specified in `rescue_only`, a retry
will be attempted. Other exceptions will not be retried. If `rescue_only` is
not specified, it defaults to `[RuntimeError]`.

The `after` block evaluates only when the `do` block returns a valid value before timeout.

On the other hand, the `else` block evaluates only when the `do` block remains erroneous after timeout.
On the other hand, the `else` block evaluates only when the `do` block remains erroneous
after timeout.

Example
## Example

use Retry

Expand Down Expand Up @@ -118,14 +123,13 @@ defmodule Retry do
end

@doc """

Retry a block of code until `halt` is emitted delaying between each attempt
the duration specified by the next item in the `with` delay stream.

The return value for `block` is expected to be `{:cont, result}`, return
`{:halt, result}` to end the retry early.

Example
## Example

retry_while with: linear_backoff(500, 1) |> take(5) do
call_service
Expand All @@ -147,15 +151,15 @@ defmodule Retry do
end

@doc """

Wait for a block of code to be truthy delaying between each attempt
the duration specified by the next item in the delay stream.

The `after` block evaluates only when the `do` block returns a truthy value.

On the other hand, the `else` block evaluates only when the `do` block remains falsy after timeout.
On the other hand, the `else` block evaluates only when the `do` block remains
falsy after timeout.

Example
## Example

wait linear_backoff(500, 1) |> take(5) do
we_there_yet?
Expand Down
5 changes: 2 additions & 3 deletions lib/retry/annotation.ex
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
defmodule Retry.Annotation do
@moduledoc """
A @retry annotation that will retry the function according to the retry settings.

Examples
A `@retry` annotation that will retry the function according to the retry
settings.

use Retry.Annotation

Expand Down
25 changes: 8 additions & 17 deletions lib/retry/delay_streams.ex
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
defmodule Retry.DelayStreams do
@moduledoc """

This module provide a set of helper functions that produce delay streams for
use with `retry`.

"""

@doc """

Returns a stream of delays that increase exponentially.

Example
## Example

retry with: exponential_backoff do
# ...
Expand All @@ -25,11 +22,10 @@ defmodule Retry.DelayStreams do
end

@doc """

Returns a stream in which each element of `delays` is randomly adjusted to a number
between 1 and the original delay.

Example
## Example

retry with: exponential_backoff() |> jitter() do
# ...
Expand All @@ -46,10 +42,9 @@ defmodule Retry.DelayStreams do
end

@doc """

Returns a stream of delays that increase linearly.

Example
## Example

retry with: linear_backoff(50, 2) do
# ...
Expand All @@ -65,10 +60,9 @@ defmodule Retry.DelayStreams do
end

@doc """

Returns a constant stream of delays.

Example
## Example

retry with: constant_backoff(50) do
# ...
Expand All @@ -81,18 +75,17 @@ defmodule Retry.DelayStreams do
end

@doc """

Returns a stream in which each element of `delays` is randomly adjusted no
more than `proportion` of the delay.

Example
## Example

retry with: exponential_backoff() |> randomize do
# ...
end

Produces an exponentially increasing delay stream where each delay is randomly
adjusted to be within 10 percent of the original value
adjusted to be within 10 percent of the original value.

"""
@spec randomize(Enumerable.t(), float()) :: Enumerable.t()
Expand All @@ -109,11 +102,10 @@ defmodule Retry.DelayStreams do
end

@doc """

Returns a stream that is the same as `delays` except that the delays never
exceed `max`. This allow capping the delay between attempts to some max value.

Example
## Example

retry with: exponential_backoff() |> cap(10_000) do
# ...
Expand All @@ -135,7 +127,6 @@ defmodule Retry.DelayStreams do
end

@doc """

Returns a delay stream that is the same as `delays` except it limits the total
life span of the stream to `time_budget`. This calculation takes the execution
time of the block being retried into account.
Expand All @@ -147,7 +138,7 @@ defmodule Retry.DelayStreams do
Optionally, you can specify a minimum delay so the smallest value doesn't go
below the threshold.

Example
## Example

retry with: exponential_backoff() |> expiry(1_000) do
# ...
Expand Down
Loading