An embedded queue and stack abstraction in Elixir on top of CubDB.
It implements persistent local (double-ended) queue and stack semantics.
CubQ
is given a CubDB
process and a queue identifier upon start:
{:ok, db} = CubDB.start_link(data_dir: "my/data/directory")
{:ok, pid} = CubQ.start_link(db: db, queue: :my_queue_id)
Queue semantics are implemented by the enqueue
and dequeue
functions:
CubQ.enqueue(pid, :one)
#=> :ok
CubQ.enqueue(pid, :two)
#=> :ok
CubQ.dequeue(pid)
#=> {:ok, :one}
CubQ.dequeue(pid)
#=> {:ok, :two}
# When there are no more items in the queue, `dequeue` returns `nil`:
CubQ.dequeue(pid)
#=> nil
Note that items can be any Elixir (or Erlang) term:
CubQ.enqueue(pid, %SomeStruct{foo: "bar"})
#=> :ok
CubQ.dequeue(pid)
#=> {:ok, %SomeStruct{foo: "bar"}}
The queue is actually double-ended, so items can be prepended too:
CubQ.enqueue(pid, :one)
#=> :ok
CubQ.prepend(pid, :zero)
#=> :ok
CubQ.dequeue(pid)
#=> {:ok, :zero}
Stack semantics are implemented by the push
and pop
functions:
CubQ.push(pid, :one)
#=> :ok
CubQ.push(pid, :two)
#=> :ok
CubQ.pop(pid)
#=> {:ok, :two}
CubQ.pop(pid)
#=> {:ok, :one}
# When there are no more items in the stack, `pop` returns `nil`:
CubQ.pop(pid)
#=> nil
As the underlying data structure used for stacks and queues is the same, queue and stack semantics can be mixed on the same queue.
When multiple consumers are taking items from a queue, and "at least once"
semantics are required, the dequeue_ack
and pop_ack
functions allow to
explicitly acknowledge the successful consumption of an item, or else put it
back in the queue after a given timeout elapses:
CubQ.enqueue(pid, :one)
#=> :ok
CubQ.enqueue(pid, :two)
#=> :ok
{:ok, item, ack_id} = CubQ.dequeue_ack(pid, 3000)
#=> {:ok, :one, ack_id}
# If 3 seconds elapse without `ack` being called, or if `nack` is called, the
# item `:one` is put back to the queue, so it can be consumed again.
# When successful consumption is confirmed by calling `ack`, the item
# is finally discarded and won't be put back in the queue anymore:
CubQ.ack(pid, ack_id)
#=> :ok
The package can be installed by adding cubq
to your list of dependencies in
mix.exs
:
def deps do
[
{:cubq, "~> 0.3.0"}
]
end
Documentation can be generated with ExDoc and published on HexDocs. The docs can be found at https://hexdocs.pm/cubq.