BullMQ.Backend behaviour (BullMQ v2.0.2)

View Source

Database-agnostic contract describing every high-level operation that the BullMQ.Queue, BullMQ.Worker, BullMQ.Job, BullMQ.QueueEvents, BullMQ.FlowProducer and BullMQ.JobScheduler modules need in order to function.

This is the Elixir port of the Node.js IQueueBackend interface (src/interfaces/queue-backend.ts). The goal is to express the queue semantics ("move job to active", "extend lock", "promote job", …) independently of the underlying datastore.

The built-in implementation is the Redis adapter (BullMQ.Backends.Redis); a PostgreSQL adapter can fulfil the same operations over a different datastore without any change to the high-level modules.

Design

Unlike the Node.js version where the backend is an object instance, an Elixir backend is an immutable struct that implements this behaviour. The struct carries the queue identity (name, prefix, keys) and references the connection process(es) it uses (a pooled BullMQ.RedisConnection plus an optional dedicated blocking connection). It never spawns a per-operation process, so operations run directly in the caller process — parallelism and connection lifecycle come from the referenced connection processes.

Every callback takes the backend struct as its first argument. Callers invoke operations through the thin dispatcher functions defined in this module (e.g. BullMQ.Backend.move_to_active(backend, token, opts)), which delegate to the concrete adapter module identified by the struct (backend.__struct__).

Return values

Callback return shapes intentionally mirror the existing BullMQ.Scripts return shapes ({:ok, term} / {:error, term} / raw values), so the Redis adapter is a near drop-in delegation and refactoring call sites is mechanical.

Summary

Types

The queue key context (%{prefix: ..., name: ...}).

A job identifier.

t()

A backend instance: any struct whose module implements BullMQ.Backend.

Callbacks

Atomically inserts a flow (tree) of jobs that may span multiple queues. Each entry carries its own prefix/queue_name.

Adds a single job, routing it to the correct initial state (wait / delayed / prioritized / waiting-children) based on opts.

Adds many jobs in a single efficient operation (pipeline / bulk).

Appends a row to a job's log, optionally trimming old entries.

Builds (without executing) the datastore command to add one parent flow node.

Builds (without executing) the datastore command to add one standard flow node.

Runs a full stalled-job sweep: finds active jobs whose lock has expired and recovers/fails them, returning %{recovered: n, failed: n}.

Removes jobs in a given state that are older than grace ms.

Builds the connection client name (used for set_name and discovery).

Closes the backend and its owned connection(s). When force is true, forcibly tears down connection(s) without waiting for in-flight commands.

The key context (%{prefix: ..., name: ...}) for the queue.

Unconditionally deletes a deduplication key.

Forcibly disconnects the backend's underlying connection(s).

Interrupts the backend's in-flight blocking wait.

Removes waiting (and optionally delayed) jobs from the queue.

Extends the lock of a single active job.

Extends the lock of several active jobs at once.

Returns a sibling backend bound to a different queue that shares this backend's underlying connection(s). Used by BullMQ.FlowProducer.

Returns the raw client list(s) for the queue's datastore.

Returns the job counts across states.

Returns the job count for each of the given types, in order.

Returns the job id currently holding the given deduplication key.

Returns the pending (unprocessed) child dependency keys.

Returns the count of pending child dependencies.

Returns the raw ignored-children failure hash entries (flat [k, v, ...]).

Returns the stored data for a job, or nil if it is missing.

Returns a page of a job's logs and the total log count.

Returns a job scheduler's raw metadata and template.

Returns the number of registered job schedulers.

Returns a page of scheduler ids with next-run scores, flattened [id, score, ...].

Returns completed/failed metrics for the queue.

Returns the raw processed-children hash entries (flat [k, v, ...]).

Reads the entire queue metadata hash.

Reads a single queue metadata field.

Reads several queue metadata fields at once, in order.

Returns a page of job ids for the given states/types.

Returns the ttl (ms) of the current rate-limit window.

Returns the current state of a job.

Returns the workers connected to the queue (parsed and filtered by the queue's client-name convention). opts may carry :cluster_connections.

Returns whether a job currently holds a (non-expired) processing lock.

Returns whether a queue metadata field exists.

Returns whether the queue has reached its concurrency limit.

Moves a (manually rate-limited) job from active back to wait.

Recovers stalled jobs (active jobs whose lock expired) back to wait.

Moves the next eligible job from wait/prioritized to active.

Moves an active job to completed and optionally fetches the next job.

Moves a job to the delayed state, scheduling it after delay ms.

Moves an active job to failed and optionally fetches the next job.

Moves a parent job to the waiting-children state.

Irreversibly destroys the queue and all of its contents.

Parses a flow child/dependency node key ("<qualifiedName>:<id>") back into %{prefix: ..., queue_name: ..., id: ...}.

Pauses or resumes the whole queue.

Promotes a single delayed job so it can be processed as soon as possible.

Publishes a custom event to the queue's event stream.

The queue's fully-qualified name. Redis: "<prefix>:<queue>".

Blocks (up to block_timeout ms) reading the queue's event stream for entries newer than id, returning the raw stream entries (or a falsy value on timeout).

Re-establishes the backend's blocking connection after an interrupt.

Releases the lock of a single active job.

Removes a job and (optionally) its children.

Removes a deduplication key if it still maps to the given job.

Removes a job scheduler.

Reprocesses a finished (failed/completed) job, moving it back to wait.

Retries a failed/active job immediately by pushing it back to wait.

Sets a human-readable name on the underlying connection (observability).

Sets one or more queue metadata fields.

Builds a namespaced sub-key of the given type for this queue.

Replaces a job's data payload.

Updates the next-run time of a job scheduler and enqueues the next job.

Updates a job's progress and emits the corresponding event.

Blocks (up to block_timeout seconds) until the queue signals that a new job may be available.

Resolves once the backend's connection(s) are ready to accept operations.

Functions

Builds a backend for name using the configured backend factory.

Types

context()

@type context() :: BullMQ.Keys.queue_context()

The queue key context (%{prefix: ..., name: ...}).

job_id()

@type job_id() :: String.t()

A job identifier.

t()

@type t() :: struct()

A backend instance: any struct whose module implements BullMQ.Backend.

Callbacks

add_flow(t, entries, opts)

(optional)
@callback add_flow(t(), entries :: list(), opts :: keyword()) ::
  {:ok, term()} | {:error, term()}

Atomically inserts a flow (tree) of jobs that may span multiple queues. Each entry carries its own prefix/queue_name.

add_job(t, job, opts)

@callback add_job(t(), job :: struct(), opts :: keyword()) ::
  {:ok, job_id()} | {:error, term()}

Adds a single job, routing it to the correct initial state (wait / delayed / prioritized / waiting-children) based on opts.

add_job_scheduler( t, scheduler_id, next_millis, scheduler_opts, template_data, template_opts, delayed_opts, now, producer_id )

(optional)
@callback add_job_scheduler(
  t(),
  scheduler_id :: String.t(),
  next_millis :: integer(),
  scheduler_opts :: map(),
  template_data :: String.t(),
  template_opts :: map(),
  delayed_opts :: map(),
  now :: integer(),
  producer_id :: String.t() | nil
) :: {:ok, term()} | {:error, term()}

Registers a job scheduler and enqueues its next delayed iteration.

add_jobs(t, jobs_with_opts, opts)

@callback add_jobs(t(), jobs_with_opts :: list(), opts :: keyword()) ::
  {:ok, ok: job_id(), error: term()} | {:error, term()}

Adds many jobs in a single efficient operation (pipeline / bulk).

add_log(t, job_id, log_row, keep_logs)

@callback add_log(t(), job_id(), log_row :: String.t(), keep_logs :: integer() | nil) ::
  {:ok, term()} | {:error, term()}

Appends a row to a job's log, optionally trimming old entries.

build_add_parent_command(t, job, opts)

(optional)
@callback build_add_parent_command(t(), job :: map(), opts :: map()) ::
  {:ok, term()} | {:error, term()}

Builds (without executing) the datastore command to add one parent flow node.

build_add_standard_command(t, job, opts)

(optional)
@callback build_add_standard_command(t(), job :: map(), opts :: map()) ::
  {:ok, term()} | {:error, term()}

Builds (without executing) the datastore command to add one standard flow node.

check_stalled_jobs(t, max_stalled_count)

(optional)
@callback check_stalled_jobs(t(), max_stalled_count :: integer()) ::
  {:ok, %{recovered: non_neg_integer(), failed: non_neg_integer()}}
  | {:error, term()}

Runs a full stalled-job sweep: finds active jobs whose lock has expired and recovers/fails them, returning %{recovered: n, failed: n}.

clean_jobs_by_state(t, state, grace, opts)

@callback clean_jobs_by_state(
  t(),
  state :: atom(),
  grace :: integer(),
  opts :: keyword()
) :: {:ok, [job_id()]} | {:error, term()}

Removes jobs in a given state that are older than grace ms.

client_name(t, suffix)

@callback client_name(t(), suffix :: String.t() | nil) :: String.t()

Builds the connection client name (used for set_name and discovery).

close(t, force)

@callback close(t(), force :: boolean()) :: :ok

Closes the backend and its owned connection(s). When force is true, forcibly tears down connection(s) without waiting for in-flight commands.

context(t)

@callback context(t()) :: context()

The key context (%{prefix: ..., name: ...}) for the queue.

delete_deduplication_key(t, deduplication_id)

@callback delete_deduplication_key(t(), deduplication_id :: String.t()) ::
  {:ok, term()} | {:error, term()}

Unconditionally deletes a deduplication key.

disconnect(t)

@callback disconnect(t()) :: :ok

Forcibly disconnects the backend's underlying connection(s).

disconnect_blocking(t, wait?)

(optional)
@callback disconnect_blocking(t(), wait? :: boolean()) :: :ok

Interrupts the backend's in-flight blocking wait.

drain(t, delayed?)

@callback drain(t(), delayed? :: boolean()) :: {:ok, term()} | {:error, term()}

Removes waiting (and optionally delayed) jobs from the queue.

extend_lock(t, job_id, token, duration)

@callback extend_lock(t(), job_id(), token :: String.t(), duration :: integer()) ::
  {:ok, term()} | {:error, term()}

Extends the lock of a single active job.

extend_locks(t, job_ids, tokens, duration)

@callback extend_locks(
  t(),
  job_ids :: [job_id()],
  tokens :: [String.t()],
  duration :: integer()
) :: {:ok, term()} | {:error, term()}

Extends the lock of several active jobs at once.

for_queue(t, queue_name, prefix)

@callback for_queue(t(), queue_name :: String.t(), prefix :: String.t() | nil) :: t()

Returns a sibling backend bound to a different queue that shares this backend's underlying connection(s). Used by BullMQ.FlowProducer.

get_client_list(t)

@callback get_client_list(t()) :: {:ok, [String.t()]} | {:error, term()}

Returns the raw client list(s) for the queue's datastore.

get_counts(t)

@callback get_counts(t()) :: {:ok, term()} | {:error, term()}

Returns the job counts across states.

get_counts_by_types(t, types)

@callback get_counts_by_types(t(), types :: [atom()]) ::
  {:ok, [non_neg_integer()]} | {:error, term()}

Returns the job count for each of the given types, in order.

get_deduplication_job_id(t, deduplication_id)

@callback get_deduplication_job_id(t(), deduplication_id :: String.t()) ::
  {:ok, term()} | {:error, term()}

Returns the job id currently holding the given deduplication key.

get_dependencies(t, job_id)

@callback get_dependencies(t(), job_id()) :: {:ok, [String.t()]} | {:error, term()}

Returns the pending (unprocessed) child dependency keys.

get_dependencies_count(t, job_id)

@callback get_dependencies_count(t(), job_id()) ::
  {:ok, non_neg_integer()} | {:error, term()}

Returns the count of pending child dependencies.

get_ignored_children_failures(t, job_id)

@callback get_ignored_children_failures(t(), job_id()) ::
  {:ok, [String.t()]} | {:error, term()}

Returns the raw ignored-children failure hash entries (flat [k, v, ...]).

get_job_data(t, job_id)

@callback get_job_data(t(), job_id()) :: {:ok, term()} | {:error, term()}

Returns the stored data for a job, or nil if it is missing.

get_job_logs(t, job_id, start, stop, asc)

@callback get_job_logs(
  t(),
  job_id(),
  start :: integer(),
  stop :: integer(),
  asc :: boolean()
) ::
  {:ok, %{logs: [String.t()], count: non_neg_integer()}} | {:error, term()}

Returns a page of a job's logs and the total log count.

get_job_scheduler(t, id)

(optional)
@callback get_job_scheduler(t(), id :: String.t()) :: {:ok, term()} | {:error, term()}

Returns a job scheduler's raw metadata and template.

get_job_schedulers_count(t)

(optional)
@callback get_job_schedulers_count(t()) :: {:ok, non_neg_integer()} | {:error, term()}

Returns the number of registered job schedulers.

get_job_schedulers_range(t, start, stop, asc)

(optional)
@callback get_job_schedulers_range(
  t(),
  start :: integer(),
  stop :: integer(),
  asc :: boolean()
) ::
  {:ok, [String.t()]} | {:error, term()}

Returns a page of scheduler ids with next-run scores, flattened [id, score, ...].

get_metrics(t, type, start, stop)

@callback get_metrics(
  t(),
  type :: :completed | :failed,
  start :: integer(),
  stop :: integer()
) ::
  {:ok, term()} | {:error, term()}

Returns completed/failed metrics for the queue.

get_processed_children_values(t, job_id)

@callback get_processed_children_values(t(), job_id()) ::
  {:ok, [String.t()]} | {:error, term()}

Returns the raw processed-children hash entries (flat [k, v, ...]).

get_queue_meta(t)

@callback get_queue_meta(t()) :: {:ok, map()} | {:error, term()}

Reads the entire queue metadata hash.

get_queue_meta_field(t, field)

@callback get_queue_meta_field(t(), field :: String.t()) ::
  {:ok, String.t() | nil} | {:error, term()}

Reads a single queue metadata field.

get_queue_meta_fields(t, fields)

@callback get_queue_meta_fields(t(), fields :: [String.t()]) ::
  {:ok, [String.t() | nil]} | {:error, term()}

Reads several queue metadata fields at once, in order.

get_ranges(t, types, start, stop)

@callback get_ranges(
  t(),
  types :: [atom() | String.t()],
  start :: integer(),
  stop :: integer()
) ::
  {:ok, term()} | {:error, term()}

Returns a page of job ids for the given states/types.

get_rate_limit_ttl(t, opts)

@callback get_rate_limit_ttl(t(), opts :: keyword()) :: {:ok, term()} | {:error, term()}

Returns the ttl (ms) of the current rate-limit window.

get_state(t, job_id)

@callback get_state(t(), job_id()) :: {:ok, term()} | {:error, term()}

Returns the current state of a job.

get_workers(t, opts)

(optional)
@callback get_workers(t(), opts :: keyword()) :: {:ok, [map()]} | {:error, term()}

Returns the workers connected to the queue (parsed and filtered by the queue's client-name convention). opts may carry :cluster_connections.

has_job_lock?(t, job_id)

(optional)
@callback has_job_lock?(t(), job_id()) :: {:ok, boolean()} | {:error, term()}

Returns whether a job currently holds a (non-expired) processing lock.

has_queue_meta_field(t, field)

@callback has_queue_meta_field(t(), field :: String.t()) ::
  {:ok, boolean()} | {:error, term()}

Returns whether a queue metadata field exists.

is_maxed(t)

@callback is_maxed(t()) :: {:ok, boolean()} | {:error, term()}

Returns whether the queue has reached its concurrency limit.

move_job_from_active_to_wait(t, job_id, token)

@callback move_job_from_active_to_wait(t(), job_id(), token :: String.t()) ::
  {:ok, term()} | {:error, term()}

Moves a (manually rate-limited) job from active back to wait.

move_stalled_jobs_to_wait(t, max_stalled_count, opts)

@callback move_stalled_jobs_to_wait(
  t(),
  max_stalled_count :: integer(),
  opts :: keyword()
) ::
  {:ok, term()} | {:error, term()}

Recovers stalled jobs (active jobs whose lock expired) back to wait.

move_to_active(t, token, opts)

@callback move_to_active(t(), token :: String.t(), opts :: keyword()) ::
  {:ok, term()} | {:error, term()}

Moves the next eligible job from wait/prioritized to active.

move_to_completed(t, job_id, token, return_value, opts)

@callback move_to_completed(
  t(),
  job_id(),
  token :: String.t(),
  return_value :: term(),
  opts :: keyword()
) :: {:ok, term()} | {:error, term()}

Moves an active job to completed and optionally fetches the next job.

move_to_delayed(t, job_id, token, delay, opts)

@callback move_to_delayed(
  t(),
  job_id(),
  token :: String.t(),
  delay :: integer(),
  opts :: keyword()
) :: {:ok, term()} | {:error, term()}

Moves a job to the delayed state, scheduling it after delay ms.

move_to_failed(t, job_id, token, error, opts)

@callback move_to_failed(
  t(),
  job_id(),
  token :: String.t(),
  error :: term(),
  opts :: keyword()
) :: {:ok, term()} | {:error, term()}

Moves an active job to failed and optionally fetches the next job.

move_to_waiting_children(t, job_id, token, opts)

@callback move_to_waiting_children(
  t(),
  job_id(),
  token :: String.t(),
  opts :: keyword()
) :: {:ok, term()} | {:error, term()}

Moves a parent job to the waiting-children state.

obliterate(t, count, force)

@callback obliterate(t(), count :: integer(), force :: boolean()) ::
  {:ok, term()} | {:error, term()}

Irreversibly destroys the queue and all of its contents.

parse_node_key(t, key)

@callback parse_node_key(t(), key :: String.t()) :: %{
  prefix: String.t(),
  queue_name: String.t(),
  id: String.t()
}

Parses a flow child/dependency node key ("<qualifiedName>:<id>") back into %{prefix: ..., queue_name: ..., id: ...}.

pause(t, paused?)

@callback pause(t(), paused? :: boolean()) :: {:ok, term()} | {:error, term()}

Pauses or resumes the whole queue.

promote(t, job_id)

@callback promote(t(), job_id()) :: {:ok, term()} | {:error, term()}

Promotes a single delayed job so it can be processed as soon as possible.

publish_event(t, fields, max_events)

(optional)
@callback publish_event(t(), fields :: map(), max_events :: integer()) ::
  {:ok, String.t()} | {:error, term()}

Publishes a custom event to the queue's event stream.

qualified_name(t)

@callback qualified_name(t()) :: String.t()

The queue's fully-qualified name. Redis: "<prefix>:<queue>".

read_events(t, id, block_timeout)

(optional)
@callback read_events(t(), id :: String.t(), block_timeout :: integer()) ::
  {:ok, term()} | {:error, term()}

Blocks (up to block_timeout ms) reading the queue's event stream for entries newer than id, returning the raw stream entries (or a falsy value on timeout).

reconnect_blocking(t)

(optional)
@callback reconnect_blocking(t()) :: {:ok, t()} | {:error, term()}

Re-establishes the backend's blocking connection after an interrupt.

release_lock(t, job_id, token)

@callback release_lock(t(), job_id(), token :: String.t()) ::
  {:ok, term()} | {:error, term()}

Releases the lock of a single active job.

remove(t, job_id, remove_children)

@callback remove(t(), job_id(), remove_children :: boolean()) ::
  {:ok, term()} | {:error, term()}

Removes a job and (optionally) its children.

remove_deduplication_key(t, deduplication_id, job_id)

@callback remove_deduplication_key(t(), deduplication_id :: String.t(), job_id()) ::
  {:ok, term()} | {:error, term()}

Removes a deduplication key if it still maps to the given job.

remove_job_scheduler(t, scheduler_id)

(optional)
@callback remove_job_scheduler(t(), scheduler_id :: String.t()) ::
  {:ok, term()} | {:error, term()}

Removes a job scheduler.

reprocess_job(t, job_id, state, opts)

@callback reprocess_job(
  t(),
  job_id(),
  state :: :failed | :completed,
  opts :: keyword()
) :: {:ok, term()} | {:error, term()}

Reprocesses a finished (failed/completed) job, moving it back to wait.

retry_job(t, job_id, lifo, token, opts)

@callback retry_job(
  t(),
  job_id(),
  lifo :: boolean(),
  token :: String.t(),
  opts :: keyword()
) :: {:ok, term()} | {:error, term()}

Retries a failed/active job immediately by pushing it back to wait.

set_name(t, name)

@callback set_name(t(), name :: String.t()) :: :ok | {:error, term()}

Sets a human-readable name on the underlying connection (observability).

set_queue_meta(t, values)

@callback set_queue_meta(t(), values :: map()) :: {:ok, term()} | {:error, term()}

Sets one or more queue metadata fields.

to_key(t, type)

@callback to_key(t(), type :: String.t()) :: String.t()

Builds a namespaced sub-key of the given type for this queue.

update_data(t, job_id, data)

@callback update_data(t(), job_id(), data :: term()) :: {:ok, term()} | {:error, term()}

Replaces a job's data payload.

update_job_scheduler(t, scheduler_id, next_millis, template_data, delayed_job_opts, producer_id)

(optional)
@callback update_job_scheduler(
  t(),
  scheduler_id :: String.t(),
  next_millis :: integer(),
  template_data :: term(),
  delayed_job_opts :: map(),
  producer_id :: String.t() | nil
) :: {:ok, term()} | {:error, term()}

Updates the next-run time of a job scheduler and enqueues the next job.

update_progress(t, job_id, progress)

@callback update_progress(t(), job_id(), progress :: term()) ::
  {:ok, term()} | {:error, term()}

Updates a job's progress and emits the corresponding event.

wait_for_job(t, block_timeout)

(optional)
@callback wait_for_job(t(), block_timeout :: number()) ::
  {:job_available, integer() | nil} | :timeout | {:error, term()}

Blocks (up to block_timeout seconds) until the queue signals that a new job may be available.

Returns {:job_available, block_until} when a marker was found (block_until is the next delayed job's timestamp, or nil for an immediately-available job), :timeout when nothing appeared, or {:error, reason}.

wait_until_ready(t)

@callback wait_until_ready(t()) :: :ok | {:error, term()}

Resolves once the backend's connection(s) are ready to accept operations.

Functions

add_flow(b, entries, opts \\ [])

@spec add_flow(t(), list(), keyword()) :: {:ok, term()} | {:error, term()}

add_job(b, job, opts \\ [])

@spec add_job(t(), struct(), keyword()) :: {:ok, job_id()} | {:error, term()}

add_job_scheduler(b, scheduler_id, next_millis, scheduler_opts, template_data, template_opts, delayed_opts, now, producer_id \\ nil)

@spec add_job_scheduler(
  t(),
  String.t(),
  integer(),
  map(),
  String.t(),
  map(),
  map(),
  integer(),
  String.t() | nil
) :: {:ok, term()} | {:error, term()}

add_jobs(b, jobs_with_opts, opts \\ [])

@spec add_jobs(t(), list(), keyword()) ::
  {:ok, ok: job_id(), error: term()} | {:error, term()}

add_log(b, job_id, log_row, keep_logs \\ nil)

@spec add_log(t(), job_id(), String.t(), integer() | nil) ::
  {:ok, term()} | {:error, term()}

build_add_parent_command(b, job, opts)

@spec build_add_parent_command(t(), map(), map()) :: {:ok, term()} | {:error, term()}

build_add_standard_command(b, job, opts)

@spec build_add_standard_command(t(), map(), map()) ::
  {:ok, term()} | {:error, term()}

check_stalled_jobs(b, max_stalled_count)

@spec check_stalled_jobs(t(), integer()) ::
  {:ok, %{recovered: non_neg_integer(), failed: non_neg_integer()}}
  | {:error, term()}

clean_jobs_by_state(b, state, grace, opts \\ [])

@spec clean_jobs_by_state(t(), atom(), integer(), keyword()) ::
  {:ok, [job_id()]} | {:error, term()}

client_name(b, suffix \\ nil)

@spec client_name(t(), String.t() | nil) :: String.t()

close(b, force \\ false)

@spec close(t(), boolean()) :: :ok

context(b)

@spec context(t()) :: context()

create(name, opts)

@spec create(
  String.t(),
  keyword()
) :: t()

Builds a backend for name using the configured backend factory.

Mirrors the Node.js defaultBackendFactory: the default is the Redis adapter (BullMQ.Backends.Redis), but it can be overridden per call with the :backend option or globally via config :bullmq, :backend, MyAdapter. The chosen module must export new/2.

delete_deduplication_key(b, deduplication_id)

@spec delete_deduplication_key(t(), String.t()) :: {:ok, term()} | {:error, term()}

disconnect(b)

@spec disconnect(t()) :: :ok

disconnect_blocking(b, wait? \\ false)

@spec disconnect_blocking(t(), boolean()) :: :ok

drain(b, delayed?)

@spec drain(t(), boolean()) :: {:ok, term()} | {:error, term()}

extend_lock(b, job_id, token, duration)

@spec extend_lock(t(), job_id(), String.t(), integer()) ::
  {:ok, term()} | {:error, term()}

extend_locks(b, job_ids, tokens, duration)

@spec extend_locks(t(), [job_id()], [String.t()], integer()) ::
  {:ok, term()} | {:error, term()}

for_queue(b, queue_name, prefix \\ nil)

@spec for_queue(t(), String.t(), String.t() | nil) :: t()

get_client_list(b)

@spec get_client_list(t()) :: {:ok, [String.t()]} | {:error, term()}

get_counts(b)

@spec get_counts(t()) :: {:ok, term()} | {:error, term()}

get_counts_by_types(b, types)

@spec get_counts_by_types(t(), [atom()]) ::
  {:ok, [non_neg_integer()]} | {:error, term()}

get_deduplication_job_id(b, deduplication_id)

@spec get_deduplication_job_id(t(), String.t()) :: {:ok, term()} | {:error, term()}

get_dependencies(b, job_id)

@spec get_dependencies(t(), job_id()) :: {:ok, [String.t()]} | {:error, term()}

get_dependencies_count(b, job_id)

@spec get_dependencies_count(t(), job_id()) ::
  {:ok, non_neg_integer()} | {:error, term()}

get_ignored_children_failures(b, job_id)

@spec get_ignored_children_failures(t(), job_id()) ::
  {:ok, [String.t()]} | {:error, term()}

get_job_data(b, job_id)

@spec get_job_data(t(), job_id()) :: {:ok, term()} | {:error, term()}

get_job_logs(b, job_id, start, stop, asc)

@spec get_job_logs(t(), job_id(), integer(), integer(), boolean()) ::
  {:ok, %{logs: [String.t()], count: non_neg_integer()}} | {:error, term()}

get_job_scheduler(b, id)

@spec get_job_scheduler(t(), String.t()) :: {:ok, term()} | {:error, term()}

get_job_schedulers_count(b)

@spec get_job_schedulers_count(t()) :: {:ok, non_neg_integer()} | {:error, term()}

get_job_schedulers_range(b, start, stop, asc)

@spec get_job_schedulers_range(t(), integer(), integer(), boolean()) ::
  {:ok, [String.t()]} | {:error, term()}

get_metrics(b, type, start \\ 0, stop \\ -1)

@spec get_metrics(t(), :completed | :failed, integer(), integer()) ::
  {:ok, term()} | {:error, term()}

get_processed_children_values(b, job_id)

@spec get_processed_children_values(t(), job_id()) ::
  {:ok, [String.t()]} | {:error, term()}

get_queue_meta(b)

@spec get_queue_meta(t()) :: {:ok, map()} | {:error, term()}

get_queue_meta_field(b, field)

@spec get_queue_meta_field(t(), String.t()) ::
  {:ok, String.t() | nil} | {:error, term()}

get_queue_meta_fields(b, fields)

@spec get_queue_meta_fields(t(), [String.t()]) ::
  {:ok, [String.t() | nil]} | {:error, term()}

get_ranges(b, types, start, stop)

@spec get_ranges(t(), [atom() | String.t()], integer(), integer()) ::
  {:ok, term()} | {:error, term()}

get_rate_limit_ttl(b, opts \\ [])

@spec get_rate_limit_ttl(
  t(),
  keyword()
) :: {:ok, term()} | {:error, term()}

get_state(b, job_id)

@spec get_state(t(), job_id()) :: {:ok, term()} | {:error, term()}

get_workers(b, opts \\ [])

@spec get_workers(
  t(),
  keyword()
) :: {:ok, [map()]} | {:error, term()}

has_job_lock?(b, job_id)

@spec has_job_lock?(t(), job_id()) :: {:ok, boolean()} | {:error, term()}

has_queue_meta_field(b, field)

@spec has_queue_meta_field(t(), String.t()) :: {:ok, boolean()} | {:error, term()}

is_maxed(b)

@spec is_maxed(t()) :: {:ok, boolean()} | {:error, term()}

move_job_from_active_to_wait(b, job_id, token \\ "0")

@spec move_job_from_active_to_wait(t(), job_id(), String.t()) ::
  {:ok, term()} | {:error, term()}

move_stalled_jobs_to_wait(b, max_stalled_count, opts \\ [])

@spec move_stalled_jobs_to_wait(t(), integer(), keyword()) ::
  {:ok, term()} | {:error, term()}

move_to_active(b, token, opts \\ [])

@spec move_to_active(t(), String.t(), keyword()) :: {:ok, term()} | {:error, term()}

move_to_completed(b, job_id, token, return_value, opts \\ [])

@spec move_to_completed(t(), job_id(), String.t(), term(), keyword()) ::
  {:ok, term()} | {:error, term()}

move_to_delayed(b, job_id, token, delay, opts \\ [])

@spec move_to_delayed(t(), job_id(), String.t(), integer(), keyword()) ::
  {:ok, term()} | {:error, term()}

move_to_failed(b, job_id, token, error, opts \\ [])

@spec move_to_failed(t(), job_id(), String.t(), term(), keyword()) ::
  {:ok, term()} | {:error, term()}

move_to_waiting_children(b, job_id, token, opts \\ [])

@spec move_to_waiting_children(t(), job_id(), String.t(), keyword()) ::
  {:ok, term()} | {:error, term()}

obliterate(b, count, force \\ false)

@spec obliterate(t(), integer(), boolean()) :: {:ok, term()} | {:error, term()}

parse_node_key(b, key)

@spec parse_node_key(t(), String.t()) :: map()

pause(b, paused?)

@spec pause(t(), boolean()) :: {:ok, term()} | {:error, term()}

promote(b, job_id)

@spec promote(t(), job_id()) :: {:ok, term()} | {:error, term()}

publish_event(b, fields, max_events)

@spec publish_event(t(), map(), integer()) :: {:ok, String.t()} | {:error, term()}

qualified_name(b)

@spec qualified_name(t()) :: String.t()

read_events(b, id, block_timeout)

@spec read_events(t(), String.t(), integer()) :: {:ok, term()} | {:error, term()}

reconnect_blocking(b)

@spec reconnect_blocking(t()) :: {:ok, t()} | {:error, term()}

release_lock(b, job_id, token)

@spec release_lock(t(), job_id(), String.t()) :: {:ok, term()} | {:error, term()}

remove(b, job_id, remove_children \\ false)

@spec remove(t(), job_id(), boolean()) :: {:ok, term()} | {:error, term()}

remove_deduplication_key(b, deduplication_id, job_id)

@spec remove_deduplication_key(t(), String.t(), job_id()) ::
  {:ok, term()} | {:error, term()}

remove_job_scheduler(b, scheduler_id)

@spec remove_job_scheduler(t(), String.t()) :: {:ok, term()} | {:error, term()}

reprocess_job(b, job_id, state, opts \\ [])

@spec reprocess_job(t(), job_id(), :failed | :completed, keyword()) ::
  {:ok, term()} | {:error, term()}

retry_job(b, job_id, lifo, token, opts \\ [])

@spec retry_job(t(), job_id(), boolean(), String.t(), keyword()) ::
  {:ok, term()} | {:error, term()}

set_name(b, name)

@spec set_name(t(), String.t()) :: :ok | {:error, term()}

set_queue_meta(b, values)

@spec set_queue_meta(t(), map()) :: {:ok, term()} | {:error, term()}

to_key(b, type)

@spec to_key(t(), String.t()) :: String.t()

update_data(b, job_id, data)

@spec update_data(t(), job_id(), term()) :: {:ok, term()} | {:error, term()}

update_job_scheduler(b, scheduler_id, next_millis, template_data, delayed_job_opts, producer_id \\ nil)

@spec update_job_scheduler(
  t(),
  String.t(),
  integer(),
  term(),
  map(),
  String.t() | nil
) ::
  {:ok, term()} | {:error, term()}

update_progress(b, job_id, progress)

@spec update_progress(t(), job_id(), term()) :: {:ok, term()} | {:error, term()}

wait_for_job(b, block_timeout)

@spec wait_for_job(t(), number()) ::
  {:job_available, integer() | nil} | :timeout | {:error, term()}

wait_until_ready(b)

@spec wait_until_ready(t()) :: :ok | {:error, term()}