Broadway producer adapter backed by Singularity Workflow orchestration for durable,
PostgreSQL-backed message production. The producer coordinates with
SingularityWorkflow to fetch work items, apply batching, manage resource hints
(GPU locks, CPU cores, etc.), and ack/requeue jobs transactionally.
- Durability – workflow state is persisted in PostgreSQL for crash recovery.
- Batching – demand-aware batching with queue depth and latency heuristics.
- Resource Hints – optional GPU/CPU lock acquisition tied to workflow steps.
- Retry Semantics – configurable retries and stateful requeue handling.
- Observability – workflow metadata and telemetry hooks for monitoring.
Add :broadway_singularity_flow and its sibling workflow library to your
mix.exs dependencies:
def deps do
[
{:broadway, "~> 1.0"},
{:singularity_workflow, path: "../singularity-workflows"},
{:ecto_sql, "~> 3.10"},
{:broadway_singularity_flow, path: "../packages/broadway_singularity_flow"}
]
endFetch dependencies with:
mix deps.getStarts the producer GenServer and spins up the coupled SingularityWorkflow
process.
Required options:
:workflow_name– unique identifier for the workflow instance:queue_name– PostgreSQL table (or schema-qualified name) backing the queue
Optional options:
:concurrency– number of producer stages (default:10):batch_size– max messages per yield (default:16):singularity_workflows_config– workflow runtime config (timeouts, retries):resource_hints– list/map describing required external resources
{:ok, _pid} =
Broadway.SingularityWorkflowsProducer.start_link(
workflow_name: "embedding_producer",
queue_name: "embedding_jobs",
concurrency: 10,
batch_size: 16,
singularity_workflows_config: [timeout_ms: 300_000, retries: 3],
resource_hints: [gpu: true]
)Broadway.SingularityWorkflowsProducer.Workflow implements the step pipeline:
fetch/1– pulls pending rows constrained by demandadjust_batch/1– tunes batch size using queue depth and ack latencybatch/1– transforms rows intoBroadway.Messagebatchesyield_and_commit/1– reserves resources, marks jobsin_progress, yieldshandle_update/3– processes:ack/:requeueupdates and releases hints
Update the Broadway producer configuration:
producer: [
module:
{Broadway.SingularityWorkflowsProducer,
[
workflow_name: "embedding_producer",
queue_name: "embedding_jobs",
concurrency: 10,
batch_size: 16,
singularity_workflows_config: [timeout_ms: 300_000, retries: 3],
resource_hints: [gpu: true]
]},
concurrency: 10
]Ensure the backing table has the expected columns:
CREATE TABLE embedding_jobs (
id SERIAL PRIMARY KEY,
data JSONB NOT NULL,
metadata JSONB DEFAULT '{}',
status VARCHAR(20) DEFAULT 'pending',
inserted_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
failure_reason TEXT
);Default runtime configuration lives in config/config.exs:
config :singularity_workflows,
timeout_ms: 300_000,
retries: 3Override in your host application as needed:
config :singularity_workflows,
timeout_ms: 600_000,
retries: 5For GPU/resource hints, implement the appropriate advisory locking logic inside
Broadway.SingularityWorkflowsProducer.Workflow.
- Producer fails to start – verify the workflow repo config and database
connectivity; ensure
workflow_nameis unique. - No messages delivered – confirm pending rows exist and the queue table is correctly named; check workflow logs for fetch errors.
- High latency / low throughput – increase
:concurrencyor:batch_size, and monitor database indexes onstatusandinserted_at. - Resource hint contention – review
acquire_hint/release_hintimplementations and confirm worker nodes are releasing locks on ack/requeue.