From ec7ca5a648a8a7b85e33f93575b69c738888907e Mon Sep 17 00:00:00 2001 From: "Kian-Meng, Ang" Date: Wed, 3 Feb 2021 09:41:02 +0800 Subject: [PATCH] Misc doc changes List of changes: - Fix spdx license id - Add source reference - Fix markdown - Use and set latest ex_doc - Add license section - Badges and more badges! - Update gitignore - Revise documentation - Move logger app to extra_applications --- .gitignore | 31 ++++++++++++++++++++----- .travis.yml | 2 +- LICENSE | 20 ++++++++--------- README.md | 43 ++++++++++++++++++++++------------- lib/retry.ex | 46 +++++++++++++++++++++----------------- lib/retry/annotation.ex | 5 ++--- lib/retry/delay_streams.ex | 25 +++++++-------------- mix.exs | 35 ++++++++++++++++++++--------- mix.lock | 6 ++--- 9 files changed, 128 insertions(+), 85 deletions(-) diff --git a/.gitignore b/.gitignore index 8671e4b..f27465b 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/.travis.yml b/.travis.yml index 94b1583..a40a64c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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' diff --git a/LICENSE b/LICENSE index 6c4e3bc..8c83c81 100644 --- a/LICENSE +++ b/LICENSE @@ -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. diff --git a/README.md b/README.md index 79354c2..b175e2a 100644 --- a/README.md +++ b/README.md @@ -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 @@ -107,7 +106,7 @@ result = retry with: Stream.cycle([500]) do after result -> result else - error -> error + error -> error end ``` @@ -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. diff --git a/lib/retry.ex b/lib/retry.ex index 9973f07..42423f1 100644 --- a/lib/retry.ex +++ b/lib/retry.ex @@ -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 @@ -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]] @@ -43,7 +48,6 @@ 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. @@ -51,15 +55,16 @@ defmodule Retry do 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 @@ -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 @@ -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? diff --git a/lib/retry/annotation.ex b/lib/retry/annotation.ex index 6fd6d65..ead7721 100644 --- a/lib/retry/annotation.ex +++ b/lib/retry/annotation.ex @@ -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 diff --git a/lib/retry/delay_streams.ex b/lib/retry/delay_streams.ex index adf07de..8415e83 100644 --- a/lib/retry/delay_streams.ex +++ b/lib/retry/delay_streams.ex @@ -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 # ... @@ -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 # ... @@ -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 # ... @@ -65,10 +60,9 @@ defmodule Retry.DelayStreams do end @doc """ - Returns a constant stream of delays. - Example + ## Example retry with: constant_backoff(50) do # ... @@ -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() @@ -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 # ... @@ -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. @@ -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 # ... diff --git a/mix.exs b/mix.exs index 9b61c51..f2be667 100644 --- a/mix.exs +++ b/mix.exs @@ -1,19 +1,24 @@ defmodule Retry.Mixfile do use Mix.Project + @source_url "https://github.com/safwank/ElixirRetry" + @version "0.14.1" + def project do [ app: :retry, name: "retry", - description: - "Simple Elixir macros for linear retry, exponential backoff and wait with composable delays.", - version: "0.14.1", + description: """ + Simple Elixir macros for linear retry, exponential backoff, and wait + with composable delays. + """, + version: @version, elixir: "~> 1.8", - source_url: "https://github.com/safwank/ElixirRetry", build_embedded: Mix.env() == :prod, start_permanent: Mix.env() == :prod, - deps: deps(), package: package(), + deps: deps(), + docs: docs(), test_coverage: [tool: ExCoveralls], preferred_cli_env: [ credo: :test, @@ -28,7 +33,9 @@ defmodule Retry.Mixfile do end def application do - [applications: [:logger]] + [ + extra_applications: [:logger] + ] end defp deps do @@ -36,16 +43,24 @@ defmodule Retry.Mixfile do {:credo, "~> 1.4.0", only: :test}, {:excoveralls, "~> 0.13.0", only: :test}, {:dialyxir, "~> 1.0.0", only: [:dev, :test]}, - {:ex_doc, "~> 0.21.0", only: :dev}, - {:earmark, "~> 1.4.0", only: :dev} + {:ex_doc, ">= 0.0.0", only: :dev, runtime: false}, ] end defp package do [ maintainers: ["Safwan Kamarrudin"], - licenses: ["Apache 2.0"], - links: %{github: "https://github.com/safwank/ElixirRetry"} + licenses: ["Apache-2.0"], + links: %{GitHub: @source_url} + ] + end + + defp docs do + [ + extras: ["README.md"], + source_url: @source_url, + source_ref: "v#{@version}", + main: "readme" ] end end diff --git a/mix.lock b/mix.lock index ed6a54e..fc141e0 100644 --- a/mix.lock +++ b/mix.lock @@ -4,9 +4,9 @@ "credo": {:hex, :credo, "1.4.1", "16392f1edd2cdb1de9fe4004f5ab0ae612c92e230433968eab00aafd976282fc", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "155f8a2989ad77504de5d8291fa0d41320fdcaa6a1030472e9967f285f8c7692"}, "dialyxir": {:hex, :dialyxir, "1.0.0", "6a1fa629f7881a9f5aaf3a78f094b2a51a0357c843871b8bc98824e7342d00a5", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "aeb06588145fac14ca08d8061a142d52753dbc2cf7f0d00fc1013f53f8654654"}, "earmark": {:hex, :earmark, "1.4.10", "bddce5e8ea37712a5bfb01541be8ba57d3b171d3fa4f80a0be9bcf1db417bcaf", [:mix], [{:earmark_parser, ">= 1.4.10", [hex: :earmark_parser, repo: "hexpm", optional: false]}], "hexpm", "12dbfa80810478e521d3ffb941ad9fbfcbbd7debe94e1341b4c4a1b2411c1c27"}, - "earmark_parser": {:hex, :earmark_parser, "1.4.10", "6603d7a603b9c18d3d20db69921527f82ef09990885ed7525003c7fe7dc86c56", [:mix], [], "hexpm", "8e2d5370b732385db2c9b22215c3f59c84ac7dda7ed7e544d7c459496ae519c0"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.12", "b245e875ec0a311a342320da0551da407d9d2b65d98f7a9597ae078615af3449", [:mix], [], "hexpm", "711e2cc4d64abb7d566d43f54b78f7dc129308a63bc103fbd88550d2174b3160"}, "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, - "ex_doc": {:hex, :ex_doc, "0.21.3", "857ec876b35a587c5d9148a2512e952e24c24345552259464b98bfbb883c7b42", [:mix], [{:earmark, "~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "0db1ee8d1547ab4877c5b5dffc6604ef9454e189928d5ba8967d4a58a801f161"}, + "ex_doc": {:hex, :ex_doc, "0.23.0", "a069bc9b0bf8efe323ecde8c0d62afc13d308b1fa3d228b65bca5cf8703a529d", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "f5e2c4702468b2fd11b10d39416ddadd2fcdd173ba2a0285ebd92c39827a5a16"}, "excoveralls": {:hex, :excoveralls, "0.13.2", "5ca05099750c086f144fcf75842c363fc15d7d9c6faa7ad323d010294ced685e", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "1e7ed75c158808a5a8f019d3ad63a5efe482994f2f8336c0a8c77d2f0ab152ce"}, "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"}, "hackney": {:hex, :hackney, "1.16.0", "5096ac8e823e3a441477b2d187e30dd3fff1a82991a806b2003845ce72ce2d84", [:rebar3], [{:certifi, "2.5.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.1", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.0", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.6", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "3bf0bebbd5d3092a3543b783bf065165fa5d3ad4b899b836810e513064134e18"}, @@ -14,7 +14,7 @@ "jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"}, "jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm"}, "makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"}, - "makeup_elixir": {:hex, :makeup_elixir, "0.15.0", "98312c9f0d3730fde4049985a1105da5155bfe5c11e47bdc7406d88e01e4219b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "75ffa34ab1056b7e24844c90bfc62aaf6f3a37a15faa76b07bc5eba27e4a8b4a"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.15.1", "b5888c880d17d1cc3e598f05cdb5b5a91b7b17ac4eaf5f297cb697663a1094dd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "db68c173234b07ab2a07f645a5acdc117b9f99d69ebf521821d89690ae6c6ec8"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, "nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"},