diff --git a/.formatter.exs b/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/.gitignore b/.gitignore index 95d2b85..baa8df3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,31 @@ -/_build -/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"). +honeydew-*.tar + +# Temporary files, for example, from tests. +/tmp/ + +# Misc. /Mnesia.* .DS_Store -.elixir_ls \ No newline at end of file +.elixir_ls diff --git a/CHANGELOG.md b/CHANGELOG.md index 848d63a..b4b95c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,16 +1,23 @@ -## 1.4.5 (2019-9-17) +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 1.4.5 (2019-09-17) ### Enhancements * Return {:error, reason} tuple for Honeydew.start_queue/2 + start_workers/3. Thanks @hauleth! -## 1.4.4 (2019-8-1) +## 1.4.4 (2019-08-01) ### Bug Fixes * Job results are now correctly passed to Success Modes -## 1.4.3 (2019-6-10) +## 1.4.3 (2019-06-10) ### Enhancements @@ -20,20 +27,20 @@ * No longer assumes that ecto tables have a single primary key named `id` -## 1.4.2 (2019-6-7) +## 1.4.2 (2019-06-07) ### Bug Fixes * Don't ignore mnesia table options provided by the user. Thanks @X4lldux! -## 1.4.1 (2019-5-9) +## 1.4.1 (2019-05-09) ### Enhancements * Job execution filtering for Ecto Poll Queue with `:run_if` option, taking a boolean SQL fragment * Adding `:timeout` option to `Honeydew.status/2` -## 1.4.0 (2019-4-8) +## 1.4.0 (2019-04-08) ### Enhancements * __Delayed Jobs__ @@ -44,16 +51,16 @@ Queue Support: - `Mnesia` - + Fully supported, uses the system's montonic clock. It's recommended to use [Multi Time Warp Mode](http://erlang.org/doc/apps/erts/time_correction.html#multi-time-warp-mode), to prevent the monotonic clock from freezing for extended periods during a time correction, with `--erl "+C multi_time_warp"`. - `EctoPollQueue` - + Unsupported, since the Ecto queue doesn't use `async/3`. However, delayed retries are supported. - + It's technically feasible to delay Ecto jobs. As Honeydew wants nothing to do with your model's insertion transaction (to limit its impact on your application), its job ordering is handled by default values in the migration. In order to delay Ecto jobs, you'll need to manually add a number of milliseconds to the `DEFAULT` value of honeydew's lock field in your insertion transaction. - + - `ErlangQueue` - + Unsupported, pending a move to a priority queue. See "Breaking Changes" below to use delayed jobs with an in-memory queue. * __Exponential Retry (backoff)__ @@ -67,7 +74,7 @@ The `Retry` failure mode is now far more customizable, you can provide your own function to determine if, and when, you want to retry the job (by returning either `{:cont, state, delay_secs}` or `:halt`). - + See the [Exponential Retry Implementation](https://github.com/koudelka/honeydew/blob/master/lib/honeydew/failure_mode/exponential_retry.ex) and [docs](https://hexdocs.pm/honeydew/1.4.0/Honeydew.FailureMode.Retry.html) @@ -80,7 +87,7 @@ * [Mnesia] The arguments for the Mnesia queue have been simplified, you no longer need to explicitly provide a separate list of nodes, simply provide the standard mnesia persistence arguments: `:ram_copies`, `:disc_copies` and `:disc_only_copies`. - + See the [Mnesia Example](https://github.com/koudelka/honeydew/blob/master/examples/mnesia.exs) * [ErlangQueue] The in-memory ErlangQueue is no longer the default queue, since it doesn't currently @@ -88,17 +95,17 @@ your queue, with the `:queue` argument. Instead, the default queue is now an Mnesia queue using `:ram_copies` and the `:ets` access mode. -## 1.3.0 (2019-2-13) +## 1.3.0 (2019-02-13) ### Enhancements * Ecto 3 support -## 1.2.7 (2019-1-8) +## 1.2.7 (2019-01-08) ### Enhancements * Adding table prefixes to Ecto Poll Queue (thanks @jfornoff!) -## 1.2.6 (2018-9-19) +## 1.2.6 (2018-09-19) ### Enhancements * Honeydew crash log statements now include the following metadata @@ -106,34 +113,34 @@ can be used for building a LoggerBackend that could forward failures to an error logger integration like Honeybadger or Bugsnag. -## 1.2.5 (2018-8-24) +## 1.2.5 (2018-08-24) ### Bug fixes * Don't restart workers when linked process terminates normally -## 1.2.4 (2018-8-23) +## 1.2.4 (2018-08-23) ### Bug fixes * Catch thrown signals on user's init/1 -## 1.2.3 (2018-8-23) +## 1.2.3 (2018-08-23) ### Bug fixes * Gracefully restart workers when an unhandled message is received. -## 1.2.2 (2018-8-23) +## 1.2.2 (2018-08-23) ### Bug fixes * Catch thrown signals from user's job code -## 1.2.1 (2018-8-20) +## 1.2.1 (2018-08-20) ### Bug fixes * Stop ignoring `init_retry_secs` worker option * Fixed `Honeydew.worker_opts` typespecs. * Fixed `Honeydew.start_workers` specs. -## 1.2.0 (2018-8-17) +## 1.2.0 (2018-08-17) Honeydew now supervises your queues and workers for you, you no longer need to add them to your supervision trees. @@ -153,7 +160,7 @@ add them to your supervision trees. * Workers can now use the `failed_init/0` callback in combination with `Honeydew.reinitialize_worker` to re-init workers if their init fails. * Many other things I'm forgetting... - + ## ? ### Breaking Changes diff --git a/LICENSE b/LICENSE.md similarity index 97% rename from LICENSE rename to LICENSE.md index 321d292..194b1b0 100644 --- a/LICENSE +++ b/LICENSE.md @@ -1,4 +1,4 @@ -The MIT License (MIT) +# The MIT License (MIT) Copyright (c) 2014 Michael Shapiro diff --git a/README.md b/README.md index 3e06cc5..645202b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,12 @@ Honeydew 💪🏻🍈 ======== + [![Build Status](https://travis-ci.org/koudelka/honeydew.svg?branch=master)](https://travis-ci.org/koudelka/honeydew) -[![Hex pm](https://img.shields.io/hexpm/v/honeydew.svg?style=flat)](https://hex.pm/packages/honeydew) +[![Module Version](https://img.shields.io/hexpm/v/honeydew.svg)](https://hex.pm/packages/honeydew) +[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/honeydew/) +[![Total Download](https://img.shields.io/hexpm/dt/honeydew.svg)](https://hex.pm/packages/honeydew) +[![License](https://img.shields.io/hexpm/l/honeydew.svg)](https://github.com/koudelka/honeydew/blob/master/LICENSE.md) +[![Last Updated](https://img.shields.io/github/last-commit/koudelka/honeydew.svg)](https://github.com/koudelka/honeydew/commits/master) Honeydew (["Honey, do!"](http://en.wiktionary.org/wiki/honey_do_list)) is a pluggable job queue and worker pool for Elixir, focused on at-least-once execution. @@ -25,14 +30,14 @@ __Isolation__ - Optionally stores immutable state loaned to each worker (a database connection, for example). - [Initialized Worker](https://github.com/koudelka/honeydew/tree/master/examples/initialized_worker) -__Strong Job Custody__ +__Strong Job Custody__ - Jobs don't leave the queue until either they succeed, are explicitly abandoned or are moved to another queue. - Workers are issued only one job at a time, no batching. - If a worker crashes while processing a job, the job is reset and a "failure mode" (e.g. abandon, move, retry) is executed. (The default failure mode [is to abandon the job](https://hexdocs.pm/honeydew/Honeydew.html#start_queue/2).) - [Job Lifecycle](https://github.com/koudelka/honeydew/blob/master/README/job_lifecycle.md) __Clusterable Components__ - - Queues, workers and your enqueuing processes can exist anywhere in the BEAM cluster. + - Queues, workers and your enqueuing processes can exist anywhere in the BEAM cluster. - [Global Queues](https://github.com/koudelka/honeydew/tree/master/examples/global) __Plugability__ @@ -54,7 +59,7 @@ __Easy API__ - [Hex Docs](https://hexdocs.pm/honeydew/Honeydew.html) -### Ecto Queue +### Ecto Queue The Ecto Queue is designed to painlessly turn your Ecto schema into a queue, using your repo as the backing store. @@ -112,10 +117,17 @@ end - Cancel jobs with `Honeydew.cancel/2` -### README -The rest of the README is broken out into slightly more digestible [sections](https://github.com/koudelka/honeydew/tree/master/README). +### GUIDES +The rest of the README is broken out into slightly more digestible [sections](https://github.com/koudelka/honeydew/tree/master/guides). Also, check out the README files included with each of the [examples](https://github.com/koudelka/honeydew/tree/master/examples). ### CHANGELOG It's worth keeping abreast with the [CHANGELOG](https://github.com/koudelka/honeydew/blob/master/CHANGELOG.md) + +## Copyright and License + +Copyright (c) 2014 Michael Shapiro + +This work is free. You can redistribute it and/or modify it under the +terms of the MIT License. See the [LICENSE.md](./LICENSE.md) file for more details. diff --git a/config/docs.exs b/config/docs.exs new file mode 100644 index 0000000..e69de29 diff --git a/README/api.md b/guides/api.md similarity index 100% rename from README/api.md rename to guides/api.md diff --git a/README/caveats.md b/guides/caveats.md similarity index 100% rename from README/caveats.md rename to guides/caveats.md diff --git a/README/dispatchers.md b/guides/dispatchers.md similarity index 100% rename from README/dispatchers.md rename to guides/dispatchers.md diff --git a/README/job_lifecycle.md b/guides/job_lifecycle.md similarity index 100% rename from README/job_lifecycle.md rename to guides/job_lifecycle.md diff --git a/README/queues.md b/guides/queues.md similarity index 100% rename from README/queues.md rename to guides/queues.md diff --git a/README/success_and_failure_modes.md b/guides/success_and_failure_modes.md similarity index 100% rename from README/success_and_failure_modes.md rename to guides/success_and_failure_modes.md diff --git a/README/workers.md b/guides/workers.md similarity index 100% rename from README/workers.md rename to guides/workers.md diff --git a/mix.exs b/mix.exs index 3b3fdae..0aac24a 100644 --- a/mix.exs +++ b/mix.exs @@ -1,62 +1,86 @@ defmodule Honeydew.Mixfile do use Mix.Project + @source_url "https://github.com/koudelka/honeydew" @version "1.5.0" def project do - [app: :honeydew, - version: @version, - elixir: "~> 1.12.0", - start_permanent: Mix.env() == :prod, - docs: docs(), - deps: deps(), - package: package(), - elixirc_paths: elixirc_paths(Mix.env), - description: "Pluggable local/clusterable job queue focused on safety.", - dialyzer: [ - plt_add_apps: [:mnesia, :ex_unit], - flags: [ - :unmatched_returns, - :error_handling, - :race_conditions, - :no_opaque - ] - ] + [ + app: :honeydew, + version: @version, + elixir: "~> 1.12.0", + start_permanent: Mix.env() == :prod, + docs: docs(), + deps: deps(), + package: package(), + elixirc_paths: elixirc_paths(Mix.env()), + dialyzer: [ + plt_add_apps: [:mnesia, :ex_unit], + flags: [ + :unmatched_returns, + :error_handling, + :race_conditions, + :no_opaque + ] + ], + preferred_cli_env: [ + docs: :docs, + "hex.publish": :docs + ] ] end defp elixirc_paths(:test), do: ["lib", "test/support"] - defp elixirc_paths(_), do: ["lib"] + defp elixirc_paths(_), do: ["lib"] - # Configuration for the OTP application - # - # Type `mix help compile.app` for more information def application do - [extra_applications: [:logger], - included_applications: [:mnesia], - mod: {Honeydew.Application, []}] + [ + extra_applications: [:logger], + included_applications: [:mnesia], + mod: {Honeydew.Application, []} + ] end defp deps do [ {:ecto, "~> 3.0", optional: true, only: [:dev, :prod]}, - {:ex_doc, ">= 0.0.0", only: :dev}, - {:dialyxir, "~> 1.0", only: [:dev, :test], runtime: false}, + {:ex_doc, ">= 0.0.0", only: :docs, runtime: false}, + {:dialyxir, "~> 1.0", only: [:dev, :test], runtime: false} # {:eflame, git: "git@github.com:slfritchie/eflame", only: :dev}, ] end defp package do - [maintainers: ["Michael Shapiro"], - licenses: ["MIT"], - links: %{"GitHub": "https://github.com/koudelka/honeydew"}] + [ + description: "Pluggable local/clusterable job queue focused on safety.", + maintainers: ["Michael Shapiro"], + licenses: ["MIT"], + links: %{ + Changelog: "https://hexdocs.pm/honeydew/changelog.html", + GitHub: @source_url + } + ] end defp docs do - [extras: ["README.md"], - source_url: "https://github.com/koudelka/honeydew", - source_ref: @version, - assets: "assets", - main: "readme"] + [ + extras: [ + "CHANGELOG.md": [], + "LICENSE.md": [title: "License"], + "README.md": [title: "Overview"], + "guides/api.md": [], + "guides/caveats.md": [], + "guides/dispatchers.md": [], + "guides/job_lifecycle.md": [], + "guides/queues.md": [], + "guides/success_and_failure_modes.md": [], + "guides/workers.md": [] + ], + main: "readme", + assets: "assets", + source_url: @source_url, + source_ref: @version, + formatters: ["html"] + ] end end diff --git a/mix.lock b/mix.lock index 04e5b3a..1957419 100644 --- a/mix.lock +++ b/mix.lock @@ -2,17 +2,17 @@ "decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"}, "dialyxir": {:hex, :dialyxir, "1.1.0", "c5aab0d6e71e5522e77beff7ba9e08f8e02bad90dfbeffae60eaf0cb47e29488", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "07ea8e49c45f15264ebe6d5b93799d4dd56a44036cf42d0ad9c960bc266c0b9a"}, "earmark": {:hex, :earmark, "1.2.6", "b6da42b3831458d3ecc57314dff3051b080b9b2be88c2e5aa41cd642a5b044ed", [:mix], [], "hexpm", "b42a23e9bd92d65d16db2f75553982e58519054095356a418bb8320bbacb58b1"}, - "earmark_parser": {:hex, :earmark_parser, "1.4.13", "0c98163e7d04a15feb62000e1a891489feb29f3d10cb57d4f845c405852bbef8", [:mix], [], "hexpm", "d602c26af3a0af43d2f2645613f65841657ad6efc9f0e361c3b6c06b578214ba"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.18", "e1b2be73eb08a49fb032a0208bf647380682374a725dfb5b9e510def8397f6f2", [:mix], [], "hexpm", "114a0e85ec3cf9e04b811009e73c206394ffecfcc313e0b346de0d557774ee97"}, "ecto": {:hex, :ecto, "3.6.1", "7bb317e3fd0179ad725069fd0fe8a28ebe48fec6282e964ea502e4deccb0bd0f", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "cbb3294a990447b19f0725488a749f8cf806374e0d9d0dffc45d61e7aeaf6553"}, "eflame": {:git, "git@github.com:slfritchie/eflame", "a08518142126f5fc541a3a3c4a04c27f24448bae", []}, "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, - "ex_doc": {:hex, :ex_doc, "0.24.2", "e4c26603830c1a2286dae45f4412a4d1980e1e89dc779fcd0181ed1d5a05c8d9", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "e134e1d9e821b8d9e4244687fb2ace58d479b67b282de5158333b0d57c6fb7da"}, + "ex_doc": {:hex, :ex_doc, "0.26.0", "1922164bac0b18b02f84d6f69cab1b93bc3e870e2ad18d5dacb50a9e06b542a3", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "2775d66e494a9a48355db7867478ffd997864c61c65a47d31c4949459281c78d"}, "hamcrest": {:hex, :basho_hamcrest, "0.4.1", "fb7b2c92d252a1e9db936750b86089addaebeb8f87967fb4bbdda61e8863338e", [:make, :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.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"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.15.2", "dc72dfe17eb240552857465cc00cce390960d9a0c055c4ccd38b70629227e97c", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "fd23ae48d09b32eff49d4ced2b43c9f086d402ee4fd4fcb2d7fad97fa8823e75"}, "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, "meck": {:hex, :meck, "0.8.4", "59ca1cd971372aa223138efcf9b29475bde299e1953046a0c727184790ab1520", [:make, :rebar], [], "hexpm"}, - "nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.2.0", "b44d75e2a6542dcb6acf5d71c32c74ca88960421b6874777f79153bbbbd7dccc", [:mix], [], "hexpm", "52b2871a7515a5ac49b00f214e4165a40724cf99798d8e4a65e4fd64ebd002c1"}, "poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], [], "hexpm"}, "protobuffs": {:hex, :protobuffs, "0.8.4", "d38ca5f7380d8477c274680273372011890f8d0037c0d7e7db5c0207b89a4e0b", [:make, :rebar], [{:meck, "~> 0.8.4", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm"}, "riak_pb": {:hex, :riak_pb, "2.3.2", "48ffbf66dbb3f136ab9a7134bac4e496754baa5ef58c4f50a61326736d996390", [:make, :mix, :rebar3], [{:hamcrest, "~> 0.4.1", [hex: :basho_hamcrest, repo: "hexpm", optional: false]}], "hexpm"},