Packages
honeydew
1.1.4
1.5.0
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.0
1.2.8
1.2.7
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
1.0.0-rc7
1.0.0-rc6
1.0.0-rc5
1.0.0-rc4
1.0.0-rc3
1.0.0-rc2
1.0.0-rc1
0.0.11
0.0.10
0.0.9
0.0.8
0.0.7
0.0.6
0.0.5
0.0.4
0.0.3
0.0.2
0.0.1
Pluggable local/clusterable job queue focused on safety.
Current section
Files
Jump to
Current section
Files
lib/honeydew/ecto_poll_queue.ex
defmodule Honeydew.EctoPollQueue do
alias Honeydew.PollQueue
alias Honeydew.EctoSource
@type queue_name :: Honeydew.queue_name()
@type ecto_poll_queue_spec_opt ::
Honeydew.queue_spec_opt |
{:schema, module} |
{:repo, module} |
{:poll_interval, pos_integer} |
{:stale_timeout, pos_integer}
@doc """
Creates a supervision spec for an Ecto Poll Queue.
In addition to the arguments from `queue_spec/4`:
You *must* provide:
- `repo`: is your Ecto.Repo module
- `schema`: is your Ecto.Schema module
You may provide:
- `poll_interval`: is how often Honeydew will poll your database when the queue is silent, in seconds (default: 10)
- `stale_timeout`: is the amount of time a job can take before it risks retry, in seconds (default: 300)
For example:
- `Honeydew.queue_spec(:classify_photos, repo: MyApp.Repo, schema: MyApp.Photo)`
- `Honeydew.queue_spec(:classify_photos, repo: MyApp.Repo, schema: MyApp.Photo failure_mode: {Honeydew.Retry, times: 3})`
"""
@spec child_spec([queue_name | ecto_poll_queue_spec_opt]) :: Supervisor.Spec.spec
def child_spec([queue_name | opts]) do
{poll_interval, opts} = Keyword.pop(opts, :poll_interval)
{stale_timeout, opts} = Keyword.pop(opts, :stale_timeout)
{database_override, opts} = Keyword.pop(opts, :database)
if opts[:queue] do
raise ArgumentError, cant_specify_queue_type_error(opts[:queue])
end
schema = Keyword.fetch!(opts, :schema)
repo = Keyword.fetch!(opts, :repo)
sql = EctoSource.SQL.module(repo, database_override)
ecto_source_args =
[schema: schema,
repo: repo,
sql: sql,
poll_interval: poll_interval || 10,
stale_timeout: stale_timeout || 300]
opts =
opts
|> Keyword.delete(:schema)
|> Keyword.delete(:repo)
|> Keyword.put(:queue, {PollQueue, [EctoSource, ecto_source_args]})
Honeydew.queue_spec(queue_name, opts)
end
@doc false
def cant_specify_queue_type_error(argument) do
"you can't provide the :queue argument for Ecto Poll Queues, it's already a `PollQueue` with the `EctoSource`. You gave #{inspect argument}"
end
defmodule Schema do
defmacro honeydew_fields(queue) do
quote do
alias Honeydew.EctoSource.ErlangTerm
unquote(queue)
|> Honeydew.EctoSource.field_name(:lock)
|> Ecto.Schema.field(:integer)
unquote(queue)
|> Honeydew.EctoSource.field_name(:private)
|> Ecto.Schema.field(ErlangTerm)
end
end
end
defmodule Migration do
defmacro honeydew_fields(queue, opts \\ []) do
quote do
require unquote(__MODULE__)
alias Honeydew.EctoSource.SQL
alias Honeydew.EctoSource.ErlangTerm
require SQL
database = Keyword.get(unquote(opts), :database, nil)
sql_module =
:repo
|> Ecto.Migration.Runner.repo_config(nil)
|> SQL.module(database)
unquote(queue)
|> Honeydew.EctoSource.field_name(:lock)
|> Ecto.Migration.add(sql_module.integer_type(), default: SQL.ready_fragment(sql_module))
unquote(queue)
|> Honeydew.EctoSource.field_name(:private)
|> Ecto.Migration.add(ErlangTerm.type())
end
end
defmacro honeydew_indexes(table, queue, opts \\ []) do
quote do
lock_field = unquote(queue) |> Honeydew.EctoSource.field_name(:lock)
Ecto.Migration.create(index(unquote(table), [lock_field], unquote(opts)))
end
end
end
end