diff --git a/CHANGELOG.md b/CHANGELOG.md index 35dd0c9..e9607dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## master +## v3.3.0 [2021-10-12] + +- [Added] The ability to start as part of a supervision tree + ## v3.2.0 [2021-10-11] - [Improved] Updated to the new `ConsumerSupervisor` syntax diff --git a/README.md b/README.md index e42a473..4f4b5ff 100644 --- a/README.md +++ b/README.md @@ -28,25 +28,25 @@ end ## Usage -A simple example: +### A simple example: ```elixir -{:ok, opq} = OPQ.init +{:ok, opq} = OPQ.init() OPQ.enqueue(opq, fn -> IO.inspect("hello") end) OPQ.enqueue(opq, fn -> IO.inspect("world") end) ``` -Specify module, function and arguments: +### Specify module, function and arguments: ```elixir -{:ok, opq} = OPQ.init +{:ok, opq} = OPQ.init() OPQ.enqueue(opq, IO, :inspect, ["hello"]) OPQ.enqueue(opq, IO, :inspect, ["world"]) ``` -Specify a custom name for the queue: +### Specify a custom name for the queue: ```elixir OPQ.init(name: :items) @@ -55,14 +55,24 @@ OPQ.enqueue(:items, fn -> IO.inspect("hello") end) OPQ.enqueue(:items, fn -> IO.inspect("world") end) ``` -Specify a custom worker to process items in the queue: +### Start as part of a supervision tree: + +Note, when starting as part of a supervision tree, the `:name` option must be provided. + +```elixir +children = [ + {OPQ, name: :items} +] +``` + +### Specify a custom worker to process items in the queue: ```elixir defmodule CustomWorker do def start_link(item) do - Task.start_link fn -> + Task.start_link(fn -> Agent.update(:bucket, &[item | &1]) - end + end) end end @@ -76,23 +86,23 @@ OPQ.enqueue(opq, "world") Agent.get(:bucket, & &1) # => ["world", "hello"] ``` -Rate limit: +### Rate limit: ```elixir {:ok, opq} = OPQ.init(workers: 1, interval: 1000) -Task.async fn -> +Task.async(fn -> OPQ.enqueue(opq, fn -> IO.inspect("hello") end) OPQ.enqueue(opq, fn -> IO.inspect("world") end) -end +end) ``` If no interval is supplied, the ratelimiter will be bypassed. -Check the queue and number of available workers: +### Check the queue and number of available workers: ```elixir -{:ok, opq} = OPQ.init +{:ok, opq} = OPQ.init() OPQ.enqueue(opq, fn -> Process.sleep(1000) end) @@ -103,20 +113,20 @@ Process.sleep(1200) {queue, available_workers} = OPQ.info(opq) # => {:normal, {[], []}, 10} ``` -Stop the queue: +### Stop the queue: ```elixir -{:ok, opq} = OPQ.init +{:ok, opq} = OPQ.init() OPQ.enqueue(opq, fn -> IO.inspect("hello") end) OPQ.stop(opq) OPQ.enqueue(opq, fn -> IO.inspect("world") end) # => (EXIT) no process... ``` -Pause and resume the queue: +### Pause and resume the queue: ```elixir -{:ok, opq} = OPQ.init +{:ok, opq} = OPQ.init() OPQ.enqueue(opq, fn -> IO.inspect("hello") end) # => "hello" OPQ.pause(opq) diff --git a/lib/opq.ex b/lib/opq.ex index e305bc2..0483a91 100644 --- a/lib/opq.ex +++ b/lib/opq.ex @@ -6,6 +6,15 @@ defmodule OPQ do alias OPQ.{Options, Feeder, RateLimiter, WorkerSupervisor} alias OPQ.OptionsHandler, as: Opt + def child_spec(opts \\ []) do + %{ + id: opts[:name], + start: {OPQ, :start_link, [opts]} + } + end + + def start_link(opts \\ []), do: init(opts) + def init(opts \\ []) do opts |> Options.assign_defaults() diff --git a/mix.exs b/mix.exs index d08f98a..6132bbb 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule OPQ.Mixfile do def project do [ app: :opq, - version: "3.2.0", + version: "3.3.0", elixir: "~> 1.5", elixirc_paths: elixirc_paths(Mix.env()), package: package(), diff --git a/test/lib/opq_test.exs b/test/lib/opq_test.exs index 67974c4..9df5cfa 100644 --- a/test/lib/opq_test.exs +++ b/test/lib/opq_test.exs @@ -3,7 +3,33 @@ defmodule OPQTest do doctest OPQ - test "enqueue items" do + test "enqueue items - child_spec/1" do + Supervisor.start_link([{OPQ, name: :opq}], strategy: :one_for_one) + + OPQ.enqueue(:opq, :a) + OPQ.enqueue(:opq, :b) + + wait(fn -> + {_status, queue, _demand} = OPQ.info(:opq) + + assert :queue.len(queue) == 0 + end) + end + + test "enqueue items - start_link/1" do + {:ok, opq} = OPQ.start_link() + + OPQ.enqueue(opq, :a) + OPQ.enqueue(opq, :b) + + wait(fn -> + {_status, queue, _demand} = OPQ.info(opq) + + assert :queue.len(queue) == 0 + end) + end + + test "enqueue items - init/1" do {:ok, opq} = OPQ.init() OPQ.enqueue(opq, :a)