Honeydew
========

Honeydew (["Honey, do!"](http://en.wiktionary.org/wiki/honey_do_list)) is a worker pool library for Elixir.

- Workers ("Honeys") are permanent and hold immutable state.
- Honeys pull jobs from the work queue ("Job List").
- Tasks are executed using `cast/1` and `call/2`, somewhat like a `GenServer`.
- If a Honey crashes while processing a job, the job is recovered and placed back on the queue.

## Usage
Simply create a module and `use Honeydew`, then start the pool with `YourModule.start_pool/2`.

You can request tasks be processed using `cast/1` or `call/2`, like so:

`Your.Module.cast({:insert_thing_in_db, ["key", "value"]})`
`Your.Module.call({:get_thing_from_db, ["key"]}) # -> "value"`

## Example
```elixir
<%= File.read!("examples/cooking_honey.ex") %>
```

## Worker State
Worker State itself is immutable, the only way to change it is to cause the worker to crash and restart.

Your worker module's `init/1` function must return `{:ok, state}`. If anything else is returned or the function raises an error, the worker will die and restart after a given time interval (by default, five seconds).

## Configuration

### Worker Respawn Delay
You can configure the worker module's respawn delay time, in case `init/1` fails, like so:

`Your.Module.start_pool([:some_worker_args], init_retry_secs: 20)`

### Maximum Failures
Jobs are only allowed to fail a certain number of times before they are no longer retried (default, three times), this is also configurable via `start_pool/1`:

`Your.Module.start_pool([:some_worker_args], max_failures: 5)`

(at present, jobs that fail too much are abandoned, but in the future will be written to disk)

### Number of Workers

Honeydew will supervise the number of workers you specify (default, ten worker)

`Your.Module.start_pool[:some_worker_args], workers: 50)`


## Process Tree
After calling `Your.Module.start_pool/2`, a process tree like this will be created under the supervision of Honeydew:

```
Honeydew.Supervisor
└── Honeydew.Your.Module.HomeSupervisor
    ├── Honeydew.Your.Module.JobList
    └── Honeydew.Your.Module.HoneySupervisor
        ├── Honeydew.Honey
        ├── Honeydew.Honey
        ├── Honeydew.Honey
        └── Honeydew.Honey
```

## Disclaimer

This library is under active development, please don't use it in production yet, and please contribute if you find it useful! :)

## Acknowledgements

Thanks to @marcelog, for his [failing worker restart strategy](http://inaka.net/blog/2012/11/29/every-day-erlang/).
