README.md

# ThrottledQueue

Simple throttled queue with live status updates.

This throttled queue performs actions asynchronously and keep the client
informed of the status of the enqueued item through its lifecycle.

## Messages

The queue process will send status updates
to the client.

- `{:dequeued, ref}`: The action has been dequeued and is about to be executed. `ref` is the message reference returned by `ThrottledQueue.enqueue`.
- `{:position, ref, position}`: The new position in the queue with the message reference.
- `{:result, ref, result}`: The result of the action with the message reference.
- `{:error, ref}`: An error occured while executing the action.

## Examples

```elixir
iex> {:ok, _pid} = ThrottledQueue.start_link(wait: 1000)
iex> {:ok, _ref, 0} = ThrottledQueue.enqueue(fn ->
...> Process.sleep(3000)
...> :foo
...> end) # Processed right away because it's the first element in the queue.
iex> {:ok, _ref, 0} = ThrottledQueue.enqueue(fn -> :bar end)
iex> {:ok, _ref, 1} = ThrottledQueue.enqueue(fn -> :yeee end)
iex> {:ok, ref, 2} = ThrottledQueue.enqueue(fn -> :yeee end)
iex> is_reference(ref)
true
```

## Receiving messages

```elixir
receive do
  {:position, ref, pos} -> do_something_with_position_in_line(ref, pos)
  {:dequeued, ref} -> do_something_when_dequeued(ref)
  {:result, ref, result} -> do_something_with_the_result(ref, result)
  {:error, ref} -> do_something_with_the_error(ref)
end
```

## API

### ThrottledQueue.start_link

Starts the queue process.

#### Parameters

- `name`: Atom. Identifier for the queue. Defaults to **ThrottledQueue** (optional).
- `wait`: Integer. The wait time between actions in milliseconds. Defaults to 500.
- `max_queue`: Integer. The maximum number of items in the queue. Defaults to 10_000

#### Examples

```elixir
iex> {:ok, pid} = ThrottledQueue.start_link(
...> name: :my_queue,
...> max_queue: 100,
...> wait: 5000
...> )
iex> is_pid(pid)
true
```

### ThrottledQueue.enqueue

Enqueues an action in the queue.

#### Parameters

- `name`: Atom to identify the queue. Defaults to **ThrottledQueue** (optional).
- `action`: Function to enqueue.

#### Returns

- `{:ok, ref, position}`: Returns a tuple with `:ok`, the message reference and the position in the queue.
- `:error`: Returns `:error` if the queue is full.

#### Examples

```elixir
iex> ThrottledQueue.start_link(max_queue: 1)
iex> {:ok, _ref, 0} = ThrottledQueue.enqueue(fn -> Process.sleep(3000) end)
iex> {:ok, _ref, 0} = ThrottledQueue.enqueue(fn -> :bar end)
iex> {:ok, _ref, 1} = ThrottledQueue.enqueue(fn -> :hey end)
iex> ThrottledQueue.enqueue(fn -> :hey end)
:error
```

## Installation

```elixir
def deps do
  [
    {:throttled_queue, git: "https://github.com/felix-d/throttled_queue.git"}
  ]
end
```