shigoto (shigoto v1.9.10)

View Source

Public API for the Shigoto background job system.

Shigoto (仕事, "work") is a PostgreSQL-backed job queue for the Nova ecosystem. Jobs are claimed via FOR UPDATE SKIP LOCKED for safe multi-node operation.

Quick Start

%% Define a worker
-module(my_email_worker).
-behaviour(shigoto_worker).
-export([perform/1]).

perform(#{<<\"to\">> := To, <<\"subject\">> := Subject}) ->
    send_email(To, Subject),
    ok.
%% Enqueue a job
shigoto:insert(#{
    worker => my_email_worker,
    args => #{<<\"to\">> => <<\"user@example.com\">>, <<\"subject\">> => <<\"Hello\">>}
}).

Bulk Insert

shigoto:insert_all([
    #{worker => my_worker, args => #{<<\"id\">> => 1}},
    #{worker => my_worker, args => #{<<\"id\">> => 2}},
    #{worker => my_worker, args => #{<<\"id\">> => 3}}
]).

Batches

{ok, Batch} = shigoto:new_batch(#{
    callback_worker => my_batch_callback,
    callback_args => #{<<\"report\">> => 1}
}),
BatchId = maps:get(id, Batch),
shigoto:insert(#{worker => step1, args => #{}, batch => BatchId}),
shigoto:insert(#{worker => step2, args => #{}, batch => BatchId}).

Transactional Enqueue

Enqueue jobs atomically with your own database writes. Jobs inserted inside transaction/1 commit together with the surrounding work, and are dropped if it rolls back — so a job is never orphaned by a failed transaction, nor lost after a successful one.

shigoto:transaction(fun() ->
    {ok, User} = my_app:create_user(Params),
    {ok, _Job} = shigoto:insert(#{
        worker => welcome_email_worker,
        args => #{~"user_id" => maps:get(id, User)}
    }),
    User
end).

Summary

Functions

Add a queue at runtime without restart.

Cancel a job by ID. Stops the job if it is executing on this node.

Cancel a job by ID. Also stops executing jobs on this node.

Cancel jobs matching a pattern. Uses the active transaction's pool, or the configured pool. Filters: worker, queue, tags, args.

Cancel jobs matching a pattern. Filters: worker, queue, tags, args.

Drain a queue synchronously. Useful for testing.

Drain a queue with options (e.g., #{timeout => 5000}).

Get a batch by ID.

Get a job by ID.

Health check. Returns ok with stats or error with details.

Insert a job with default options.

Insert a job with options. Params: worker, args, queue, priority, scheduled_at, max_attempts, unique, tags, batch.

Bulk insert multiple jobs with default options.

Bulk insert multiple jobs with options.

Create a new batch for grouping jobs.

Pause a queue by name — stops claiming new jobs.

Run a worker through Shigoto's real perform path with no database, for unit tests. Returns the raw worker result. See shigoto_testing.

Like perform_job/2 with extra job context (deps_results, attempt, ...).

Remove a queue at runtime. Waits for in-flight jobs to finish.

Report job progress (0-100). Call from within a worker's perform/1.

Resume a paused queue by name.

Retry a discarded or cancelled job. Uses the active transaction's pool, or the configured pool.

Retry a discarded or cancelled job.

Retry all jobs matching a filter. Uses the active transaction's pool, or the configured pool. Filters: worker, queue, state, tags.

Retry all jobs matching a filter. Filters: worker, queue, state, tags.

Run Fun inside a database transaction on the Shigoto pool.

Like transaction/1, on a specific pool via #{pool => Pool}. Nested calls inherit the outer pool.

Functions

add_queue(Queue, Concurrency)

-spec add_queue(binary(), pos_integer()) -> {ok, pid()} | {error, term()}.

Add a queue at runtime without restart.

cancel(JobId)

-spec cancel(integer()) -> ok | {error, term()}.

Cancel a job by ID. Stops the job if it is executing on this node.

Not transaction-aware: the process stop and job_cancelled telemetry fire immediately, so this always uses the configured pool rather than an enclosing transaction/1,2 pool.

cancel(Pool, JobId)

-spec cancel(atom(), integer()) -> ok | {error, term()}.

Cancel a job by ID. Also stops executing jobs on this node.

cancel_by(Filters)

-spec cancel_by(map()) -> {ok, non_neg_integer()} | {error, term()}.

Cancel jobs matching a pattern. Uses the active transaction's pool, or the configured pool. Filters: worker, queue, tags, args.

cancel_by(Pool, Filters)

-spec cancel_by(atom(), map()) -> {ok, non_neg_integer()} | {error, term()}.

Cancel jobs matching a pattern. Filters: worker, queue, tags, args.

drain_queue(Queue)

-spec drain_queue(binary()) -> ok.

Drain a queue synchronously. Useful for testing.

drain_queue(Queue, Opts)

-spec drain_queue(binary(), map()) -> ok.

Drain a queue with options (e.g., #{timeout => 5000}).

get_batch(BatchId)

-spec get_batch(integer()) -> {ok, map()} | {error, term()}.

Get a batch by ID.

get_job(JobId)

-spec get_job(integer()) -> {ok, map()} | {error, term()}.

Get a job by ID.

health()

-spec health() -> {ok, map()} | {error, map()}.

Health check. Returns ok with stats or error with details.

insert(JobParams)

-spec insert(map()) -> {ok, map()} | {ok, {conflict, map()}} | {error, term()}.

Insert a job with default options.

insert(JobParams, Opts)

-spec insert(map(), map()) -> {ok, map()} | {ok, {conflict, map()}} | {error, term()}.

Insert a job with options. Params: worker, args, queue, priority, scheduled_at, max_attempts, unique, tags, batch.

insert_all(JobParamsList)

-spec insert_all([map()]) -> {ok, [map()]} | {error, term()}.

Bulk insert multiple jobs with default options.

insert_all(JobParamsList, Opts)

-spec insert_all([map()], map()) -> {ok, [map()]} | {error, term()}.

Bulk insert multiple jobs with options.

new_batch(Opts)

-spec new_batch(map()) -> {ok, map()} | {error, term()}.

Create a new batch for grouping jobs.

pause_queue(Queue)

-spec pause_queue(binary()) -> ok | {error, not_found}.

Pause a queue by name — stops claiming new jobs.

perform_job(Worker, Args)

-spec perform_job(module(), map()) -> ok | {ok, term()} | {error, term()} | {snooze, pos_integer()}.

Run a worker through Shigoto's real perform path with no database, for unit tests. Returns the raw worker result. See shigoto_testing.

perform_job(Worker, Args, Opts)

-spec perform_job(module(), map(), map()) ->
                     ok | {ok, term()} | {error, term()} | {snooze, pos_integer()}.

Like perform_job/2 with extra job context (deps_results, attempt, ...).

remove_queue(Queue)

-spec remove_queue(binary()) -> ok | {error, term()}.

Remove a queue at runtime. Waits for in-flight jobs to finish.

report_progress(JobId, Progress)

-spec report_progress(integer(), 0..100) -> ok | {error, term()}.

Report job progress (0-100). Call from within a worker's perform/1.

resume_queue(Queue)

-spec resume_queue(binary()) -> ok | {error, not_found}.

Resume a paused queue by name.

retry(JobId)

-spec retry(integer()) -> ok | {error, term()}.

Retry a discarded or cancelled job. Uses the active transaction's pool, or the configured pool.

retry(Pool, JobId)

-spec retry(atom(), integer()) -> ok | {error, term()}.

Retry a discarded or cancelled job.

retry_by(Filters)

-spec retry_by(map()) -> {ok, non_neg_integer()} | {error, term()}.

Retry all jobs matching a filter. Uses the active transaction's pool, or the configured pool. Filters: worker, queue, state, tags.

retry_by(Pool, Filters)

-spec retry_by(atom(), map()) -> {ok, non_neg_integer()} | {error, term()}.

Retry all jobs matching a filter. Filters: worker, queue, state, tags.

transaction(Fun)

-spec transaction(fun(() -> Result)) -> Result when Result :: term().

Run Fun inside a database transaction on the Shigoto pool.

Jobs enqueued with insert/1,2 or insert_all/1,2 from within Fun commit atomically with any other work done on the same pool: if Fun raises, the transaction rolls back and no jobs are enqueued. job_inserted telemetry fires only after a successful commit.

To roll back, raise an exception. If a statement inside Fun fails and aborts the transaction, the commit is rejected and transaction_rolled_back is raised — no jobs are enqueued and no telemetry fires. Returns the value of Fun.

transaction(Fun, Opts)

-spec transaction(fun(() -> Result), map()) -> Result when Result :: term().

Like transaction/1, on a specific pool via #{pool => Pool}. Nested calls inherit the outer pool.