queue

package module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 10, 2026 License: MIT Imports: 23 Imported by: 8

README

queue logo

queue is a queue and workflow library with pluggable backends and runtime extensions.

Go Reference Go Test Go version Latest tag Unit tests (executed count) Integration tests (executed count)

Installation

go get github.com/goforj/queue

Existing deployments upgrading to application-type direct delivery must replace workers before switching producers. Follow the direct delivery migration guide, including its SQL schema step and backend-specific rollback constraints.

Applications upgrading from the retired bus or queuefake packages should follow the legacy API migration guide. The retired Temporal compatibility adapter is replaced by the optional Temporal driver, which has its own explicit configuration and lifecycle contract.

Queue and its driver modules require Go 1.27 or newer. Projects on older Go releases can pin the v0.2 release line. The PostgreSQL driver continues to use pgx 5.9.2 or newer, the first release containing the GO-2026-5004 security fix.

Quick Start

import (
	"context"
	"fmt"

	"github.com/goforj/queue"
)

func main() {
	q, _ := queue.NewWorkerpool(
		queue.WithWorkers(2), // optional; default: runtime.NumCPU() (min 1)
	)
	type EmailPayload struct {
		To string `json:"to"`
	}

	q.Register("emails:send", func(ctx context.Context, m queue.Message) error {
		var payload EmailPayload
		_ = m.Bind(&payload)
		fmt.Println("send to", payload.To)
		return nil
	})

	_ = q.StartWorkers(context.Background())
	defer q.Shutdown(context.Background())

	_, _ = q.Dispatch(
		queue.NewJob("emails:send").
			Payload(EmailPayload{To: "user@example.com"}),
	)
}

Durable named continuations bind registered hook jobs to chains and batches with immutable trigger snapshots and recoverable outcomes.

Drivers

Each driver is thoroughly tested against the shared test suite using testcontainers or emulators where appropriate.

Driver / Backend Mode Notes Durable Async Delay Unique Backoff Timeout Native Stats Queue Admin
Null Drop-only Discards dispatched jobs; useful for disabled queue modes and smoke tests. - - - Instance - - - -
Sync Inline (caller) Deterministic local execution with no external infra. - - - Instance - ✓ - -
Workerpool In-process pool Local async behavior without external broker/database. - ✓ ✓ Instance ✓ ✓ - -
MySQL SQL durable queue MySQL driver module (driver/mysqlqueue) built on shared SQL queue core. ✓ ✓ ✓ Backend ✓ ✓ ✓ -
Postgres SQL durable queue Postgres driver module (driver/postgresqueue) built on shared SQL queue core. ✓ ✓ ✓ Backend ✓ ✓ ✓ -
SQLite SQL durable queue SQLite driver module (driver/sqlitequeue) built on shared SQL queue core. ✓ ✓ ✓ Backend ✓ ✓ ✓ -
Redis Redis/Asynq Production Redis backend (Asynq semantics). ✓ ✓ ✓ Backend - ✓ ✓ ✓
NATS Ephemeral broker Core NATS subject routing; every plain subscription can receive a broadcast copy. - ✓ ✓ Instance ✓ ✓ - -
SQS Broker target AWS SQS transport with endpoint overrides for localstack/testing. - ✓ ✓ Instance ✓ ✓ - -
RabbitMQ Broker target RabbitMQ transport and worker consumption. - ✓ ✓ Instance ✓ ✓ - -

| Temporal | Workflow service | Optional driver/temporalqueue; portable jobs, chains, batches and native SDK workflows. Configuration and limits. | ✓ | ✓ | ✓ | Unsupported | ✓ | ✓ | - | - |

SQL-backed queues (sqlite, mysql, postgres) are durable and convenient, but they trade throughput for operational simplicity. They default to 1 worker, and increasing concurrency may require DB tuning (indexes, connection pool, lock contention). Prefer broker-backed drivers for higher-throughput workloads.

Unique scope: Instance suppresses duplicates only within one queue runtime instance; Backend shares claims through the configured database or Redis service. Identity is the effective queue, logical application job type, and canonical serialized payload. Absent, zero-byte, and exact JSON null payloads share one absence identity; generated workflow IDs and delivery options do not change it. See docs/backend-guarantees.md for acceptance, rollout, and failure-boundary details.

Queue Admin status: the cross-driver admin contract is defined in core (ListJobs, RetryJob, CancelJob, DeleteJob, ClearQueue, QueueHistory), but full queue admin operations are currently implemented only for Redis. Other drivers return ErrQueueAdminUnsupported for unsupported admin actions.

Driver constructor quick examples

Use root constructors for in-process backends, and driver-module constructors for external backends. See the Driver Constructors API section below for full constructor shapes (New(...) and NewWithConfig(...)). Driver backends live in separate packages so applications only import/link the optional backend dependencies they actually use (smaller builds, less dependency overhead, cleaner deploys).

package main

import (
	"github.com/goforj/queue"
	"github.com/goforj/queue/driver/mysqlqueue"
	"github.com/goforj/queue/driver/natsqueue"
	"github.com/goforj/queue/driver/postgresqueue"
	"github.com/goforj/queue/driver/rabbitmqqueue"
	"github.com/goforj/queue/driver/redisqueue"
	"github.com/goforj/queue/driver/sqlitequeue"
	"github.com/goforj/queue/driver/sqsqueue"
)

func main() {
	queue.NewSync()       // in-process sync
	queue.NewWorkerpool() // in-process worker pool
	queue.NewNull()       // drop-only / disabled mode

	sqlitequeue.New("file:queue.db?_busy_timeout=5000") // SQL durable queue (SQLite)
	mysqlqueue.New("user:pass@tcp(127.0.0.1:3306)/app") // SQL durable queue (MySQL)
	postgresqueue.New("postgres://user:pass@127.0.0.1:5432/app?sslmode=disable") // SQL durable queue (Postgres)

	redisqueue.New("127.0.0.1:6379") // Redis/Asynq
	natsqueue.New("nats://127.0.0.1:4222") // NATS
	sqsqueue.New("us-east-1") // SQS
	rabbitmqqueue.New("amqp://guest:guest@127.0.0.1:5672/") // RabbitMQ
}

Quick Start (Advanced: Workflows)

import (
	"context"

	"github.com/goforj/queue"
)

type EmailPayload struct {
	ID int `json:"id"`
}

func main() {
	q, _ := queue.NewWorkerpool()

	q.Register("reports:generate", func(ctx context.Context, m queue.Message) error {
		return nil
	})
	q.Register("reports:upload", func(ctx context.Context, m queue.Message) error {
		var payload EmailPayload
		if err := m.Bind(&payload); err != nil {
			return err
		}
		return nil
	})
	q.Register("users:notify_report_ready", func(ctx context.Context, m queue.Message) error {
		return nil
	})

	_ = q.StartWorkers(context.Background())
	defer q.Shutdown(context.Background())

	chainID, _ := q.Chain(
		// 1) generate report data
		queue.NewJob("reports:generate").Payload(map[string]any{"report_id": "rpt_123"}),
		// 2) upload report artifact after generate succeeds
		queue.NewJob("reports:upload").Payload(EmailPayload{ID: 123}),
		// 3) notify user only after upload succeeds
		queue.NewJob("users:notify_report_ready").Payload(map[string]any{"user_id": 123}),
	).OnQueue("critical").Dispatch(context.Background())
	_ = chainID
}

Run as a Worker Service

Use Run(ctx) for long-lived workers: it starts processing, waits for shutdown signals, and performs graceful termination.

import (
	"context"
	"log"
	"os/signal"
	"syscall"

	"github.com/goforj/queue"
)

func main() {
	q, _ := queue.NewWorkerpool()

	// Register handlers before starting workers.
	q.Register("emails:send", func(ctx context.Context, m queue.Message) error {
		return nil
	})

	// Create a context that is canceled on SIGINT/SIGTERM (Ctrl+C, container stop).
	ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
	defer stop()

	// Run starts workers, blocks until ctx is canceled, then gracefully shuts down.
	if err := q.Run(ctx); err != nil {
		log.Fatal(err)
	}
}

Core Concepts

Job: Typed work unit for app handlers.

_, _ = q.Dispatch(
	queue.NewJob("emails:send").Payload(EmailPayload{To: "user@example.com"}),
)

Chain: Ordered workflow (A then B then C).

_, _ = q.Chain(
	queue.NewJob("reports:generate"),
	queue.NewJob("reports:upload"),
	queue.NewJob("users:notify_report_ready"),
).Dispatch(context.Background())

Batch: Parallel workflow with callbacks.

_, _ = q.Batch(
	queue.NewJob("emails:send"),
	queue.NewJob("sms:send"),
).Then(func(context.Context, queue.BatchState) error {
	return nil
}).Dispatch(context.Background())

Middleware: Cross-cutting execution policy.

q, _ := queue.New(
	queue.Config{Driver: queue.DriverWorkerpool},
	queue.WithMiddleware(audit, skipMaintenance, fatalValidation),
)

Events: Lifecycle hooks and observability.

q, _ := queue.New(
	queue.Config{Driver: queue.DriverWorkerpool},
	queue.WithObserver(queue.NewStatsCollector()),
)

Backends: Driver/runtime transport selection.

q, _ := queue.NewWorkerpool()
rq, _ := redisqueue.New("127.0.0.1:6379")
_, _ = q, rq

Job builder options

// Define a struct for your job payload.
type EmailPayload struct {
	ID int `json:"id"`
	To string `json:"to"`
}

// Fluent builder pattern for job options.
job := queue.NewJob("emails:send").
	// Payload can be bytes, structs, maps, or JSON-marshalable values.
	// Default payload is empty.
	Payload(EmailPayload{ID: 123, To: "user@example.com"}).
	// OnQueue sets the queue name.
	// Default is empty; broker-style drivers expect an explicit queue.
	OnQueue("default").
	// Timeout sets per-job execution timeout.
	// Default is unset; some drivers may apply driver/runtime defaults.
	Timeout(20 * time.Second).
	// Retry sets max retries.
	// Default is 0, which means one total attempt.
	Retry(3).
	// Backoff sets retry delay.
	// Default is unset; Redis dispatch returns ErrBackoffUnsupported.
	Backoff(500 * time.Millisecond).
	// Delay schedules first execution in the future.
	// Default is 0 (run immediately).
	Delay(2 * time.Second).
	// UniqueFor deduplicates Type+Payload for a TTL window.
	// Default is 0 (no dedupe).
	UniqueFor(45 * time.Second)

// Dispatch the job to the queue.
_, _ = q.Dispatch(job)

// In handlers, use Bind to decode payload into a struct.
q.Register("emails:send", func(ctx context.Context, m queue.Message) error {
	var payload EmailPayload
	if err := m.Bind(&payload); err != nil {
		return err
	}
	return nil
})

Benchmarks

Run local + integration-backed benchmarks (requires Docker/testcontainers):

cd docs && GOWORK=off INTEGRATION_BACKEND=all GOCACHE=/tmp/queue-gocache go test -tags=benchrender ./bench -run '^TestRenderBenchmarks$'

Latency (ns/op)

Queue benchmark latency chart

Throughput (ops/s)

Queue benchmark throughput chart

Allocated Bytes (B/op)

Queue benchmark bytes chart

Allocations (allocs/op)

Queue benchmark allocations chart

Tables

Class Driver ns/op ops/s B/op allocs/op
External nats 774 1291823 1258 13
External redis 95295 10494 2113 33
External rabbitmq 165780 6032 1882 57
External sqlite 202380 4941 1931 47
External postgres 1056731 946 3809 78
External sqs 1873911 534 94784 1082
External mysql 2286406 437 3303 62
Local null 37 26673780 128 1
Local sync 282 3539823 408 6
Local workerpool 650 1538462 456 7

Middleware

Use queue.WithMiddleware(...) to apply cross-cutting workflow behavior to workflow job execution (logging, filtering, and error policy).

Common patterns:

  • wrap handler execution (before/after logging, timing, tracing)
  • skip jobs conditionally (maintenance mode, feature flags)
  • convert matched errors into terminal failures (no retry)
var errValidation = errors.New("validation failed")
maintenanceMode := false

audit := queue.MiddlewareFunc(func(ctx context.Context, m queue.Message, next queue.Next) error {
	log.Printf("start job=%s", m.JobType)
	err := next(ctx, m)
	log.Printf("done job=%s err=%v", m.JobType, err)
	return err
})

skipMaintenance := queue.SkipWhen{
	Predicate: func(context.Context, queue.Message) bool {
		return maintenanceMode
	},
}

fatalValidation := queue.FailOnError{
	When: func(err error) bool {
		return errors.Is(err, errValidation)
	},
}

q, _ := queue.New(
	queue.Config{Driver: queue.DriverWorkerpool},
	queue.WithMiddleware(audit, skipMaintenance, fatalValidation),
)
_ = q

Observability

Use queue.Observer implementations to capture normalized runtime events across drivers.

collector := queue.NewStatsCollector()
observer := queue.MultiObserver(
    collector,
    queue.ObserverFunc(func(_ context.Context, event queue.Event) {
        _ = event.Kind
    }),
)

q, _ := queue.New(
    queue.Config{Driver: queue.DriverWorkerpool},
    queue.WithObserver(observer),
)
_ = q

Distributed counters and source of truth

  • StatsCollector counters are process-local and event-driven.
  • In multi-process deployments, aggregate metrics externally (OTel/Prometheus/etc.).
  • Prefer backend-native stats when available.
  • queue.SupportsNativeStats(q) indicates native driver snapshot support.
  • queue.Snapshot(ctx, q, collector) merges native + collector where possible.

Compose observers

events := make(chan queue.Event, 100)
collector := queue.NewStatsCollector()
observer := queue.MultiObserver(
    collector,
    queue.ChannelObserver{
        Events:     events,
        DropIfFull: true,
    },
    queue.ObserverFunc(func(_ context.Context, e queue.Event) {
        _ = e
    }),
)

q, _ := queue.New(
    queue.Config{Driver: queue.DriverWorkerpool},
    queue.WithObserver(observer),
)
_ = q

Kitchen sink event logging

Runnable example: examples/observeall/main.go

logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
observer := queue.ObserverFunc(func(ctx context.Context, event queue.Event) {
	logger.InfoContext(ctx, "queue event",
		"layer", event.Layer,
		"kind", event.Kind,
		"driver", event.Driver,
		"queue", event.Queue,
		"dispatch_id", event.DispatchID,
		"job_id", event.JobID,
		"chain_id", event.ChainID,
		"batch_id", event.BatchID,
		"job_type", event.JobType,
		"attempt", event.Attempt,
		"max_retry", event.MaxRetry,
		"duration", event.Duration,
		"err", event.Err,
	)
})

q, _ := queue.New(
	queue.Config{Driver: queue.DriverSync},
	queue.WithObserver(observer),
)
_ = q

Events reference

Layer EventKind Meaning
queue dispatch_started After job validation, the root facade began a public dispatch.
queue dispatch_succeeded The backend accepted the public dispatch; synchronous execution may still return an application error.
queue dispatch_failed Public dispatch ended before backend acceptance.
queue enqueue_accepted The driver confirmed enqueue acceptance.
queue enqueue_rejected The driver rejected enqueue with an error.
queue enqueue_duplicate Uniqueness policy rejected the logical job as a duplicate.
queue enqueue_canceled Context cancellation or deadline expiry prevented enqueue.
worker process_started A physical handler attempt began.
worker process_succeeded Handler success crossed the driver's settlement boundary; runtimes without a settlement hook emit after handler return.
worker process_failed A handler attempt returned an error or panicked.
worker process_retried A numbered application retry attempt began; infrastructure redelivery may repeat the fact.
worker process_archived A SQL driver confirmed its fenced transition to terminal dead state; other built-in runtimes omit it.
worker process_recovered SQL bulk recovery requeued one stale in-flight claim; identity fields are unavailable at that boundary.
worker republish_failed An internal delay or retry replacement could not be published.
worker settlement_failed Delivery finalization, acknowledgement, deletion, or negative settlement failed or was ambiguous; redelivery remains possible.
queue queue_paused A supporting driver confirmed queue consumption was paused.
queue queue_resumed A supporting driver confirmed queue consumption was resumed.
workflow job_started A logical execution attempt began before handler lookup.
workflow job_succeeded Logical job success committed; settlement-aware drivers publish the fact only after settlement.
workflow job_failed A logical job reached permanent or exhausted failure.
workflow chain_started A chain record was created and initial dispatch began.
workflow chain_advanced A committed node outcome advanced the chain to its next node.
workflow chain_completed The final chain node committed terminal success.
workflow chain_failed A chain committed terminal failure.
workflow batch_started A batch record was created and initial member dispatch began.
workflow batch_progressed A batch member committed a terminal outcome.
workflow batch_completed Batch reached terminal success (or allowed-failure completion).
workflow batch_failed A non-allowed member failure or initial member dispatch rejection committed terminal batch failure.
workflow batch_cancelled Remaining batch work was cancelled after terminal failure.
workflow callback_started A claimed terminal Catch, Then, or Finally callback began execution.
workflow callback_succeeded Terminal callback success crossed the applicable settlement boundary.
workflow callback_failed A terminal callback was invalid or unavailable, returned an error, or panicked.

Handler panics now emit process_failed before the original panic value is rethrown. This adds truthful failure telemetry without changing backend panic recovery or retry behavior.

Callback lifecycle facts cover terminal Catch, Then, and Finally callbacks. Inline Batch.Progress closures do not emit callback_* facts.

Examples

Runnable examples live in the separate examples module (./examples). They are not included when applications import github.com/goforj/queue, which keeps dependency graphs and build/link overhead smaller.

Admin Support

Queue admin APIs are part of the core contract so additional drivers can implement them over time. At this time, full admin operations (ListJobs, RetryJob, CancelJob, DeleteJob, ClearQueue) are Redis-only. Use queue.SupportsQueueAdmin(q) (or handle queue.ErrQueueAdminUnsupported) to gate admin workflows per runtime.

API reference

The API section below is autogenerated; do not edit between the markers.

API Index

Group Functions
Admin CancelJob · Queue.CancelJob · ClearQueue · Queue.ClearQueue · DeleteJob · Queue.DeleteJob · History · ListJobs · Queue.ListJobs · Normalize · QueueHistory · RetryJob · Queue.RetryJob · SinglePointHistory · SupportsQueueAdmin · TimelineHistoryFromSnapshot
Constructors New · NewMemoryStore · NewMessage · NewNull · NewSQLStore · NewSQLStoreWithManagedSchema · NewStatsCollector · NewSync · NewWorkerpool
Job Backoff · Bind · Delay · NewJob · OnQueue · Payload · PayloadAs · PayloadBytes · PayloadJSON · Retry · Timeout · UniqueFor
Observability Active · Archived · Failed · MultiObserver · ChannelObserver.Observe · Observer.Observe · ObserverFunc.Observe · StatsCollector.Observe · Pause · Paused · Pending · Processed · Queue · Queues · Ready · Resume · RetryCount · SafeObserve · Scheduled · Snapshot · StatsCollector.Snapshot · SupportsNativeStats · SupportsPause · Throughput
Other Acquire · AdvanceChain · Allow · AllowFailures · CancelBatch · BatchBuilder.Catch · ChainBuilder.Catch · Continuation · ContinuationRecords · CreateBatch · CreateChain · BatchBuilder.Dispatch · ChainBuilder.Dispatch · ContinuationBuilder.Dispatch · FailChain · FailChainNode · BatchBuilder.Finally · ChainBuilder.Finally · FakeQueue.FindContinuations · Queue.FindContinuations · GetBatch · GetChain · FailOnError.Handle · Middleware.Handle · MiddlewareFunc.Handle · RateLimit.Handle · RetryPolicy.Handle · SkipWhen.Handle · WithoutOverlapping.Handle · MarkBatchJobFailed · MarkBatchJobStarted · MarkBatchJobSucceeded · MarkCallbackInvoked · Name · OnCompletion · OnFailure · OnProgress · BatchBuilder.OnQueue · ChainBuilder.OnQueue · OnSuccess · PhysicalQueueName · PhysicalQueueWeights · Progress · Prune · Release · ResolveObservedJobType · SettleBatchJob · Then · WithResourceID
Queue Batch · Bind · Chain · Dispatch · Driver · FindBatch · FindChain · IsPermanent · Pause · PayloadAs · PayloadBytes · Permanent · Prune · Ready · Register · Resume · Run · Shutdown · StartWorkers · Stats · WithClock · WithContext · WithHandlerContextDecorator · WithLegacyDirectEnvelope · WithMiddleware · WithObserver · WithStore · WithWorkers · Queue.WithWorkers
Workflows Continue
Driver Constructors mysqlqueue.New · mysqlqueue.NewWithConfig · natsqueue.New · natsqueue.NewWithConfig · postgresqueue.New · postgresqueue.NewWithConfig · rabbitmqqueue.New · rabbitmqqueue.NewWithConfig · redisqueue.New · redisqueue.NewWithConfig · sqlitequeue.New · sqlitequeue.NewWithConfig · sqsqueue.New · sqsqueue.NewWithConfig · temporalqueue.NewWithConfig
Testing AssertBatchCount · AssertBatched · AssertChained · AssertCount · AssertDispatched · AssertDispatchedOn · AssertDispatchedTimes · AssertNotDispatched · AssertNothingBatched · AssertNothingDispatched · Batch · BatchRecords · Chain · ChainRecords · Dispatch · Driver · FindBatch · FindChain · NewFake · Prune · Ready · Records · Register · Reset · Shutdown · StartWorkers · WithContext · Workers

API

Admin
CancelJob

CancelJob cancels a job when supported.

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
err = queue.CancelJob(context.Background(), q, "job-id")
_ = err
Queue.CancelJob

CancelJob cancels a job via queue admin capability when supported.

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
if !queue.SupportsQueueAdmin(q) {
	return
}
err = q.CancelJob(context.Background(), "job-id")
_ = err
ClearQueue

ClearQueue clears queue jobs when supported.

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
err = queue.ClearQueue(context.Background(), q, "default")
_ = err
Queue.ClearQueue

ClearQueue clears queue jobs via queue admin capability when supported.

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
if !queue.SupportsQueueAdmin(q) {
	return
}
err = q.ClearQueue(context.Background(), "default")
_ = err
DeleteJob

DeleteJob deletes a job when supported.

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
err = queue.DeleteJob(context.Background(), q, "default", "job-id")
_ = err
Queue.DeleteJob

DeleteJob deletes a job via queue admin capability when supported.

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
if !queue.SupportsQueueAdmin(q) {
	return
}
err = q.DeleteJob(context.Background(), "default", "job-id")
_ = err
History

History returns queue history points via queue admin capability when supported.

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
points, err := q.History(context.Background(), "default", queue.QueueHistoryHour)
_ = err
ListJobs

ListJobs lists jobs for a queue and state when supported.

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
_, err = queue.ListJobs(context.Background(), q, queue.ListJobsOptions{
	Queue: "default",
	State: queue.JobStatePending,
})
_ = err
Queue.ListJobs

ListJobs lists jobs via queue admin capability when supported.

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
_, err = q.ListJobs(context.Background(), queue.ListJobsOptions{
	Queue: "default",
	State: queue.JobStatePending,
})
_ = err
Normalize

Normalize returns a safe options payload with defaults applied.

opts := queue.ListJobsOptions{Queue: "", State: "", Page: 0, PageSize: 1000}
normalized := opts.Normalize()
fmt.Println(normalized.Queue, normalized.State, normalized.Page, normalized.PageSize)
// Output: default pending 1 500
QueueHistory

QueueHistory returns queue history points when supported.

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
_, err = queue.QueueHistory(context.Background(), q, "default", queue.QueueHistoryHour)
_ = err
RetryJob

RetryJob retries (runs now) a job when supported.

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
err = queue.RetryJob(context.Background(), q, "default", "job-id")
_ = err
Queue.RetryJob

RetryJob retries (runs now) a job via queue admin capability when supported.

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
if !queue.SupportsQueueAdmin(q) {
	return
}
err = q.RetryJob(context.Background(), "default", "job-id")
_ = err
SinglePointHistory

SinglePointHistory converts a snapshot into a single current-history point. This helper is intended for driver modules that do not expose historical buckets.

snapshot := queue.StatsSnapshot{
	ByQueue: map[string]queue.QueueCounters{
		"default": {Processed: 12, Failed: 1},
	},
}
points := queue.SinglePointHistory(snapshot, "default")
fmt.Println(len(points), points[0].Processed, points[0].Failed)
// Output: 1 12 1
SupportsQueueAdmin

SupportsQueueAdmin reports whether queue admin operations are available.

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
fmt.Println(queue.SupportsQueueAdmin(q))
// Output: true
TimelineHistoryFromSnapshot

TimelineHistoryFromSnapshot records queue counters and returns windowed points. This is intended for drivers that don't expose native multi-point history.

snapshot := queue.StatsSnapshot{
	ByQueue: map[string]queue.QueueCounters{
		"default": {Processed: 5, Failed: 1},
	},
}
points := queue.TimelineHistoryFromSnapshot(snapshot, "default", queue.QueueHistoryHour)
fmt.Println(len(points) >= 1)
// Output: true
Constructors
queue.New

New creates the high-level Queue API based on Config.Driver.

q, err := queue.New(queue.Config{Driver: queue.DriverWorkerpool})
if err != nil {
	return
}
type EmailPayload struct {
	ID int `json:"id"`
}
q.Register("emails:send", func(ctx context.Context, m queue.Message) error {
	var payload EmailPayload
	if err := m.Bind(&payload); err != nil {
		return err
	}
	_ = payload
	return nil
})
_ = q.WithWorkers(1).StartWorkers(context.Background()) // optional; default: runtime.NumCPU() (min 1)
defer q.Shutdown(context.Background())
_, _ = q.Dispatch(
	queue.NewJob("emails:send").
		Payload(EmailPayload{ID: 1}).
		OnQueue("default"),
)
NewMemoryStore

NewMemoryStore creates an in-memory workflow state store. It copies chain nodes and payload bytes on creation and return so callers retain independent ownership.

NewMessage

NewMessage creates a logical queue message from an application job type and exact payload bytes. The payload is copied so callers can safely reuse or mutate their input buffer.

NewNull

NewNull creates a Queue on the null backend.

q, err := queue.NewNull()
if err != nil {
	return
}
NewSQLStore

NewSQLStore creates a SQL-backed workflow state store.

NewSQLStoreWithManagedSchema

NewSQLStoreWithManagedSchema creates a SQL-backed workflow state store without executing schema DDL. The supplied database must already contain the dialect-correct workflow tables, including transition receipts.

NewStatsCollector

NewStatsCollector creates an event collector for queue counters.

collector := queue.NewStatsCollector()
NewSync

NewSync creates a Queue on the synchronous in-process backend.

q, err := queue.NewSync()
if err != nil {
	return
}
NewWorkerpool

NewWorkerpool creates a Queue on the in-process workerpool backend.

q, err := queue.NewWorkerpool()
if err != nil {
	return
}
Job
Backoff

Backoff sets delay between retries.

job := queue.NewJob("emails:send").Backoff(500 * time.Millisecond)
Job.Bind

Bind unmarshals job payload JSON into dst.

type EmailPayload struct {
	ID int    `json:"id"`
	To string `json:"to"`
}
job := queue.NewJob("emails:send").Payload(EmailPayload{
	ID: 1,
	To: "user@example.com",
})
var payload EmailPayload
if err := job.Bind(&payload); err != nil {
	return
}
_ = payload.To
Delay

Delay defers execution by duration.

job := queue.NewJob("emails:send").Delay(300 * time.Millisecond)
NewJob

NewJob creates a job value with a required job type.

job := queue.NewJob("emails:send")
Job.OnQueue

OnQueue sets the target queue name.

job := queue.NewJob("emails:send").OnQueue("critical")
Payload

Payload sets job payload from common value types.

Example: payload bytes

jobBytes := queue.NewJob("emails:send").Payload([]byte(`{"id":1}`))

Example: payload struct

type Meta struct {
	Nested bool `json:"nested"`
}
type EmailPayload struct {
	ID   int    `json:"id"`
	To   string `json:"to"`
	Meta Meta   `json:"meta"`
}
jobStruct := queue.NewJob("emails:send").Payload(EmailPayload{
	ID:   1,
	To:   "user@example.com",
	Meta: Meta{Nested: true},
})

Example: payload map

jobMap := queue.NewJob("emails:send").Payload(map[string]any{
	"id":  1,
	"to":  "user@example.com",
	"meta": map[string]any{"nested": true},
})
Job.PayloadAs

PayloadAs unmarshals the job payload JSON and returns it as T.

type EmailPayload struct {
	To string `json:"to"`
}
job := queue.NewJob("emails:send").Payload(EmailPayload{To: "user@example.com"})
payload, err := job.PayloadAs[EmailPayload]()
fmt.Println(err == nil, payload.To)
// true user@example.com
Job.PayloadBytes

PayloadBytes returns a copy of job payload bytes.

job := queue.NewJob("emails:send").Payload([]byte(`{"id":1}`))
payload := job.PayloadBytes()
PayloadJSON

PayloadJSON marshals payload as JSON.

job := queue.NewJob("emails:send").PayloadJSON(map[string]int{"id": 1})
Retry

Retry sets max retry attempts.

job := queue.NewJob("emails:send").Retry(4)
Timeout

Timeout sets per-job execution timeout.

job := queue.NewJob("emails:send").Timeout(10 * time.Second)
UniqueFor

UniqueFor enables uniqueness dedupe within the given TTL.

job := queue.NewJob("emails:send").UniqueFor(45 * time.Second)
Observability
Active

Active returns active count for a queue.

snapshot := queue.StatsSnapshot{
	ByQueue: map[string]queue.QueueCounters{
		"default": {Active: 2},
	},
}
fmt.Println(snapshot.Active("default"))
// Output: 2
Archived

Archived returns archived count for a queue.

snapshot := queue.StatsSnapshot{
	ByQueue: map[string]queue.QueueCounters{
		"default": {Archived: 7},
	},
}
fmt.Println(snapshot.Archived("default"))
// Output: 7
Failed

Failed returns failed count for a queue.

snapshot := queue.StatsSnapshot{
	ByQueue: map[string]queue.QueueCounters{
		"default": {Failed: 2},
	},
}
fmt.Println(snapshot.Failed("default"))
// Output: 2
MultiObserver

MultiObserver fans out events to multiple observers.

events := make(chan queue.Event, 2)
observer := queue.MultiObserver(
	queue.ChannelObserver{Events: events},
	queue.ObserverFunc(func(context.Context, queue.Event) {}),
)
observer.Observe(context.Background(), queue.Event{Kind: queue.EventEnqueueAccepted})
fmt.Println(len(events))
// Output: 1
ChannelObserver.Observe

Observe forwards an event to the configured channel.

ch := make(chan queue.Event, 1)
observer := queue.ChannelObserver{Events: ch}
observer.Observe(context.Background(), queue.Event{Kind: queue.EventProcessStarted, Queue: "default"})
event := <-ch
Observer.Observe

Observe handles a queue runtime event.

var observer queue.Observer
observer.Observe(context.Background(), queue.Event{
	Kind:   queue.EventEnqueueAccepted,
	Driver: queue.DriverSync,
	Queue:  "default",
})
ObserverFunc.Observe

Observe calls the wrapped function.

logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
observer := queue.ObserverFunc(func(ctx context.Context, event queue.Event) {
	logger.Info("queue event",
		"kind", event.Kind,
		"driver", event.Driver,
		"queue", event.Queue,
		"job_type", event.JobType,
		"attempt", event.Attempt,
		"max_retry", event.MaxRetry,
		"duration", event.Duration,
		"err", event.Err,
	)
})
observer.Observe(context.Background(), queue.Event{
	Kind:     queue.EventProcessSucceeded,
	Driver:   queue.DriverSync,
	Queue:    "default",
	JobType: "emails:send",
})
StatsCollector.Observe

Observe records an event and updates normalized counters.

collector := queue.NewStatsCollector()
collector.Observe(context.Background(), queue.Event{
	Kind:   queue.EventEnqueueAccepted,
	Driver: queue.DriverSync,
	Queue:  "default",
	Time:   time.Now(),
})
Pause

Pause pauses queue consumption for drivers that support it.

q, _ := queue.NewSync()
_ = queue.Pause(context.Background(), q, "default")
snapshot, _ := queue.Snapshot(context.Background(), q, nil)
fmt.Println(snapshot.Paused("default"))
// Output: 1
Paused

Paused returns the observed pause state for a queue as zero or one.

collector := queue.NewStatsCollector()
collector.Observe(context.Background(), queue.Event{
	Kind:   queue.EventQueuePaused,
	Driver: queue.DriverSync,
	Queue:  "default",
	Time:   time.Now(),
})
snapshot := collector.Snapshot()
fmt.Println(snapshot.Paused("default"))
// Output: 1
Pending

Pending returns pending count for a queue.

snapshot := queue.StatsSnapshot{
	ByQueue: map[string]queue.QueueCounters{
		"default": {Pending: 3},
	},
}
fmt.Println(snapshot.Pending("default"))
// Output: 3
Processed

Processed returns processed count for a queue.

snapshot := queue.StatsSnapshot{
	ByQueue: map[string]queue.QueueCounters{
		"default": {Processed: 11},
	},
}
fmt.Println(snapshot.Processed("default"))
// Output: 11
Queue

Queue returns queue counters for a queue name.

collector := queue.NewStatsCollector()
collector.Observe(context.Background(), queue.Event{
	Kind:   queue.EventEnqueueAccepted,
	Driver: queue.DriverSync,
	Queue:  "default",
	Time:   time.Now(),
})
snapshot := collector.Snapshot()
counters, ok := snapshot.Queue("default")
fmt.Println(ok, counters.Pending)
// Output: true 1
Queues

Queues returns sorted queue names present in the snapshot.

collector := queue.NewStatsCollector()
collector.Observe(context.Background(), queue.Event{
	Kind:   queue.EventEnqueueAccepted,
	Driver: queue.DriverSync,
	Queue:  "critical",
	Time:   time.Now(),
})
snapshot := collector.Snapshot()
names := snapshot.Queues()
fmt.Println(len(names), names[0])
// Output: 1 critical
Ready

Ready validates backend readiness for the provided queue runtime.

q, _ := queue.NewSync()
fmt.Println(queue.Ready(context.Background(), q) == nil)
// true
Resume

Resume resumes queue consumption for drivers that support it.

q, _ := queue.NewSync()
_ = queue.Pause(context.Background(), q, "default")
_ = queue.Resume(context.Background(), q, "default")
snapshot, _ := queue.Snapshot(context.Background(), q, nil)
fmt.Println(snapshot.Paused("default"))
// Output: 0
RetryCount

RetryCount returns retry count for a queue.

snapshot := queue.StatsSnapshot{
	ByQueue: map[string]queue.QueueCounters{
		"default": {Retry: 1},
	},
}
fmt.Println(snapshot.RetryCount("default"))
// Output: 1
SafeObserve

SafeObserve delivers an event to an observer and recovers observer panics.

This is an advanced helper intended for driver-module implementations.

Scheduled

Scheduled returns scheduled count for a queue.

snapshot := queue.StatsSnapshot{
	ByQueue: map[string]queue.QueueCounters{
		"default": {Scheduled: 4},
	},
}
fmt.Println(snapshot.Scheduled("default"))
// Output: 4
Snapshot

Snapshot returns driver-native stats, falling back to collector data.

q, _ := queue.NewSync()
snapshot, _ := q.Stats(context.Background())
_, ok := snapshot.Queue("default")
fmt.Println(ok)
// Output: true
StatsCollector.Snapshot

Snapshot returns a copy of collected counters.

collector := queue.NewStatsCollector()
collector.Observe(context.Background(), queue.Event{
	Kind:   queue.EventEnqueueAccepted,
	Driver: queue.DriverSync,
	Queue:  "default",
	Time:   time.Now(),
})
collector.Observe(context.Background(), queue.Event{
	Kind:   queue.EventProcessStarted,
	Driver: queue.DriverSync,
	Queue:  "default",
	JobKey: "job-1",
	Time:   time.Now(),
})
collector.Observe(context.Background(), queue.Event{
	Kind:     queue.EventProcessSucceeded,
	Driver:   queue.DriverSync,
	Queue:    "default",
	JobKey:  "job-1",
	Duration: 12 * time.Millisecond,
	Time:     time.Now(),
})
snapshot := collector.Snapshot()
counters, _ := snapshot.Queue("default")
throughput, _ := snapshot.Throughput("default")
fmt.Printf("queues=%v\n", snapshot.Queues())
fmt.Printf("counters=%+v\n", counters)
fmt.Printf("hour=%+v\n", throughput.Hour)
// Output:
// queues=[default]
// counters={Pending:0 Active:0 Scheduled:0 Retry:0 Archived:0 Processed:1 Failed:0 Paused:0 AvgWait:0s AvgRun:12ms}
// hour={Processed:1 Failed:0}
SupportsNativeStats

SupportsNativeStats reports whether a queue runtime exposes native stats snapshots.

q, _ := queue.NewSync()
fmt.Println(queue.SupportsNativeStats(q))
// Output: true
SupportsPause

SupportsPause reports whether a queue runtime supports Pause/Resume.

q, _ := queue.NewSync()
fmt.Println(queue.SupportsPause(q))
// Output: true
Throughput

Throughput returns rolling throughput windows for a queue name.

collector := queue.NewStatsCollector()
collector.Observe(context.Background(), queue.Event{
	Kind:   queue.EventProcessSucceeded,
	Driver: queue.DriverSync,
	Queue:  "default",
	Time:   time.Now(),
})
snapshot := collector.Snapshot()
throughput, ok := snapshot.Throughput("default")
fmt.Printf("ok=%v hour=%+v day=%+v week=%+v\n", ok, throughput.Hour, throughput.Day, throughput.Week)
// Output: ok=true hour={Processed:1 Failed:0} day={Processed:1 Failed:0} week={Processed:1 Failed:0}
Other
Acquire

Acquire attempts to hold key for ttl.

AdvanceChain

AdvanceChain atomically claims completedNode and returns the current successor. Repeating the same (chainID, completedNode) claim must not advance again. When done is true, GetChain must immediately expose Completed or Failed state.

Allow

Allow returns whether key may execute and any suggested retry delay.

AllowFailures

AllowFailures keeps remaining members active after a terminal member failure.

CancelBatch

CancelBatch commits aggregate batch cancellation.

BatchBuilder.Catch

Catch registers the explicitly ephemeral batch failure callback.

ChainBuilder.Catch

Catch registers the explicitly ephemeral chain failure callback.

Continuation

Continuation returns immutable invocation metadata when this message is a durable hook.

ContinuationRecords

ContinuationRecords returns accepted fake workflow definitions without phantom pending invocations.

CreateBatch

CreateBatch persists a newly accepted batch. BatchID and every JobID must be non-empty, Jobs must contain at least one entry, and JobIDs must be unique.

CreateChain

CreateChain persists a newly accepted chain. ChainID and every NodeID must be non-empty, Nodes must contain at least one entry, and NodeIDs must be unique.

BatchBuilder.Dispatch

Dispatch persists and starts the batch workflow.

ChainBuilder.Dispatch

Dispatch persists and starts the chain workflow.

ContinuationBuilder.Dispatch

Dispatch validates and accepts one immutable workflow with its durable hook definitions.

FailChain

FailChain commits terminal failure without replacing completed state.

FailChainNode

FailChainNode commits failure only while nodeID is the current unsettled node. owned remains true on replay while that node's failure owns the chain.

BatchBuilder.Finally

Finally registers the explicitly ephemeral batch terminal callback.

ChainBuilder.Finally

Finally registers the explicitly ephemeral chain terminal callback.

FakeQueue.FindContinuations

FindContinuations returns committed triggered fake outcomes independently of definitions.

Queue.FindContinuations

FindContinuations returns triggered invocation outcomes, including scheduled but unsettled work.

GetBatch

GetBatch returns current batch state.

GetChain

GetChain returns current chain state.

FailOnError.Handle

Handle wraps matched errors as fatal errors to stop retries.

Middleware.Handle

Handle wraps the remaining middleware and handler chain.

MiddlewareFunc.Handle

Handle calls the wrapped middleware function.

RateLimit.Handle

Handle applies limiter checks before executing the next handler.

RetryPolicy.Handle

Handle passes execution through without modification.

SkipWhen.Handle

Handle skips job execution when Predicate returns true.

WithoutOverlapping.Handle

Handle acquires a lock and prevents concurrent overlap for the same key.

MarkBatchJobFailed

MarkBatchJobFailed commits the first outcome for (batchID, jobID). Duplicate outcomes must return current state without changing counters.

MarkBatchJobStarted

MarkBatchJobStarted records that one batch member began execution.

MarkBatchJobSucceeded

MarkBatchJobSucceeded commits the first outcome for (batchID, jobID). Duplicate outcomes must return current state without changing counters.

MarkCallbackInvoked

MarkCallbackInvoked atomically claims one callback idempotency key.

Name

Name assigns an application-facing label to the batch.

OnCompletion

OnCompletion appends a named hook to the first aggregate terminal transition.

OnFailure

OnFailure appends a named hook to the first terminal business failure.

OnProgress

OnProgress appends a named hook for each first committed batch member outcome.

BatchBuilder.OnQueue

OnQueue applies a default queue to batch jobs without an explicit target.

ChainBuilder.OnQueue

OnQueue applies a default queue to chain jobs without an explicit target.

OnSuccess

OnSuccess appends a named hook to the workflow's successful aggregate transition.

PhysicalQueueName

PhysicalQueueName maps a logical queue name into the physical name used by the backing queue driver.

PhysicalQueueWeights

PhysicalQueueWeights maps logical weighted queue names into their physical backend names.

Progress

Progress registers the explicitly ephemeral batch progress callback.

WorkflowStore.Prune

Prune removes terminal workflow state older than before.

Release

Release relinquishes the acquired lease.

ResolveObservedJobType

ResolveObservedJobType returns the effective application job type that should be emitted to observers. External workers may process private workflow delivery envelopes (for example, "bus:job") whose payload embeds the real application job type. When possible, this helper unwraps that payload so dashboards and metrics reflect the user-facing job type instead of the transport wrapper.

SettleBatchJob

SettleBatchJob returns the first committed outcome for one batch member. owned remains true on same-outcome replay and false when the opposite outcome won. Ownership covers the outcome category; BatchState does not retain a per-member cause.

Then

Then registers the explicitly ephemeral batch success callback.

WithResourceID

WithResourceID supplies the stable resource scope used by durable built-in continuation recovery. Use the same value across consumers of one queue and distinct values for independent resources sharing a store.

Queue
Queue.Batch

Batch creates a batch builder for fan-out workflow execution.

q, err := queue.NewSync()
if err != nil {
	return
}
q.Register("emails:send", func(ctx context.Context, m queue.Message) error { return nil })
if err := q.StartWorkers(context.Background()); err != nil {
	return
}
defer q.Shutdown(context.Background())
_, _ = q.Batch(
	queue.NewJob("emails:send").Payload(map[string]any{"id": 1}),
	queue.NewJob("emails:send").Payload(map[string]any{"id": 2}),
).Name("send-emails").OnQueue("default").Dispatch(context.Background())
Message.Bind

Bind unmarshals the raw job payload into dst.

Queue.Chain

Chain creates a chain builder for sequential workflow execution.

q, err := queue.NewSync()
if err != nil {
	return
}
q.Register("first", func(ctx context.Context, m queue.Message) error { return nil })
q.Register("second", func(ctx context.Context, m queue.Message) error { return nil })
if err := q.StartWorkers(context.Background()); err != nil {
	return
}
defer q.Shutdown(context.Background())
_, _ = q.Chain(
	queue.NewJob("first"),
	queue.NewJob("second"),
).OnQueue("default").Dispatch(context.Background())
Queue.Dispatch

Dispatch enqueues a high-level job using its application type and exact payload bytes together with the queue's bound context.

q, err := queue.NewSync()
if err != nil {
	return
}
q.Register("emails:send", func(ctx context.Context, m queue.Message) error { return nil })
if err := q.StartWorkers(context.Background()); err != nil {
	return
}
defer q.Shutdown(context.Background())
job := queue.NewJob("emails:send").Payload(map[string]any{"id": 1}).OnQueue("default")
_, _ = q.Dispatch(job)
Queue.Driver

Driver reports the configured backend driver for the underlying queue runtime.

q, err := queue.NewSync()
if err != nil {
	return
}
fmt.Println(q.Driver())
// Output: sync
Queue.FindBatch

FindBatch returns current batch state by ID.

q, err := queue.NewSync()
if err != nil {
	return
}
q.Register("emails:send", func(ctx context.Context, m queue.Message) error { return nil })
batchID, err := q.Batch(queue.NewJob("emails:send")).Dispatch(context.Background())
if err != nil {
	return
}
_, _ = q.FindBatch(context.Background(), batchID)
Queue.FindChain

FindChain returns current chain state by ID.

q, err := queue.NewSync()
if err != nil {
	return
}
q.Register("first", func(ctx context.Context, m queue.Message) error { return nil })
chainID, err := q.Chain(queue.NewJob("first")).Dispatch(context.Background())
if err != nil {
	return
}
_, _ = q.FindChain(context.Background(), chainID)
IsPermanent

IsPermanent reports whether an error requests terminal application settlement.

Queue.Pause

Pause pauses consumption for a queue when supported by the underlying driver. See the README "Queue Backends" table for Pause/Resume support and docs/backend-guarantees.md (Capability Matrix) for broader backend differences.

q, err := queue.NewSync()
if err != nil {
	return
}
if queue.SupportsPause(q) {
	_ = q.Pause(context.Background(), "default")
}
Message.PayloadAs

PayloadAs unmarshals the delivered payload and returns it as T.

type EmailPayload struct {
	To string `json:"to"`
}
message := queue.NewMessage("emails:send", []byte(`{"to":"user@example.com"}`))
payload, err := message.PayloadAs[EmailPayload]()
fmt.Println(err == nil, payload.To)
// true user@example.com
Message.PayloadBytes

PayloadBytes returns an isolated copy of the raw job payload.

Permanent

Permanent marks an error as terminal so workers do not spend the remaining application retry budget on it.

Queue.Prune

Prune deletes old workflow state records.

q, err := queue.NewSync()
if err != nil {
	return
}
_ = q.Prune(context.Background(), time.Now().Add(-24*time.Hour))
Queue.Ready

Ready validates queue backend readiness for dispatch/worker operation.

q, err := queue.NewSync()
if err != nil {
	return
}
fmt.Println(q.Ready(context.Background()) == nil)
// true
Queue.Register

Register binds a handler for a high-level job type.

q, err := queue.NewSync()
if err != nil {
	return
}
type EmailPayload struct {
	ID int `json:"id"`
}
q.Register("emails:send", func(ctx context.Context, m queue.Message) error {
	var payload EmailPayload
	if err := m.Bind(&payload); err != nil {
		return err
	}
	_ = payload
	return nil
})
Queue.Resume

Resume resumes consumption for a queue when supported by the underlying driver.

q, err := queue.NewSync()
if err != nil {
	return
}
if queue.SupportsPause(q) {
	_ = q.Resume(context.Background(), "default")
}
Run

Run starts worker processing, blocks until ctx is canceled, then gracefully shuts down.

ctx, cancel := context.WithCancel(context.Background())
defer cancel()
q, err := queue.NewWorkerpool()
if err != nil {
	return
}
q.Register("emails:send", func(ctx context.Context, m queue.Message) error { return nil })
go func() {
	time.Sleep(100 * time.Millisecond)
	cancel()
}()
_ = q.Run(ctx)
Queue.Shutdown

Shutdown drains workers and closes underlying resources.

q, err := queue.NewWorkerpool()
if err != nil {
	return
}
_ = q.StartWorkers(context.Background())
_ = q.Shutdown(context.Background())
Queue.StartWorkers

StartWorkers starts worker processing.

q, err := queue.NewWorkerpool()
if err != nil {
	return
}
_ = q.StartWorkers(context.Background())
Stats

Stats returns a normalized snapshot when supported by the underlying driver.

q, err := queue.NewSync()
if err != nil {
	return
}
if queue.SupportsNativeStats(q) {
	_, _ = q.Stats(context.Background())
}
WithClock

WithClock overrides the workflow runtime clock.

q, err := queue.New(
	queue.Config{Driver: queue.DriverSync},
	queue.WithClock(func() time.Time { return time.Unix(0, 0) }),
)
if err != nil {
	return
}
Queue.WithContext

WithContext returns a derived queue handle bound to ctx.

WithHandlerContextDecorator

WithHandlerContextDecorator decorates queue handler execution context before process lifecycle events and handler execution run.

q, err := queue.New(
	queue.Config{Driver: queue.DriverSync},
	queue.WithHandlerContextDecorator(func(ctx context.Context) context.Context {
		return context.WithValue(ctx, "source", "jobs")
	}),
)
if err != nil {
	return
}
WithLegacyDirectEnvelope

WithLegacyDirectEnvelope keeps ordinary dispatches on the version-one bus:job wire route during a workers-first migration. Remove this option only after every consumer can process canonical direct deliveries. See the direct delivery migration guide for backend-specific rollout and rollback.

WithMiddleware

WithMiddleware appends queue workflow middleware.

mw := queue.MiddlewareFunc(func(ctx context.Context, m queue.Message, next queue.Next) error {
	return next(ctx, m)
})
q, err := queue.New(queue.Config{Driver: queue.DriverSync}, queue.WithMiddleware(mw))
if err != nil {
	return
}
WithObserver

WithObserver installs one observer for queue, worker, and workflow lifecycle events.

observer := queue.ObserverFunc(func(_ context.Context, event queue.Event) {
	_ = event.Kind
})
q, err := queue.New(queue.Config{Driver: queue.DriverSync}, queue.WithObserver(observer))
if err != nil {
	return
}
WithStore

WithStore overrides the workflow orchestration store.

var store queue.WorkflowStore
q, err := queue.New(queue.Config{Driver: queue.DriverSync}, queue.WithStore(store))
if err != nil {
	return
}
WithWorkers

WithWorkers sets desired worker concurrency before StartWorkers. It applies to high-level queue constructors (for example NewWorkerpool/New/NewSync).

q, err := queue.NewWorkerpool(
	queue.WithWorkers(4), // optional; default: runtime.NumCPU() (min 1)
)
if err != nil {
	return
}
Queue.WithWorkers

WithWorkers sets desired worker concurrency before StartWorkers.

q, err := queue.NewWorkerpool()
if err != nil {
	return
}
q.WithWorkers(4) // optional; default: runtime.NumCPU() (min 1)
Workflows
Continue

Continue snapshots a queue-owned chain or batch without changing existing builder interfaces. Unsupported custom builders and mixed closure callbacks fail when Dispatch is called.

q, err := queue.NewSync(queue.WithResourceID("reports"))
if err != nil {
	return
}
q.Register("reports:build", func(context.Context, queue.Message) error { return nil })
q.Register("reports:complete", func(_ context.Context, m queue.Message) error {
	invocation, _ := m.Continuation()
	_ = invocation.ID // Stable across retry, suitable for application idempotency.
	return nil
})
if err := q.StartWorkers(context.Background()); err != nil {
	return
}
defer q.Shutdown(context.Background())
id, err := queue.Continue(q.Chain(queue.NewJob("reports:build"))).
	OnCompletion(queue.NewJob("reports:complete")).Dispatch(context.Background())
_ = err

Driver Constructors

mysqlqueue

mysqlqueue.New

New creates a high-level Queue using the MySQL SQL backend.

q, err := mysqlqueue.New(
	"user:pass@tcp(127.0.0.1:3306)/queue?parseTime=true",
	queue.WithWorkers(4), // optional; default: 1 worker
)
if err != nil {
	return
}
mysqlqueue.NewWithConfig

NewWithConfig creates a high-level Queue using an explicit MySQL SQL driver config.

q, err := mysqlqueue.NewWithConfig(
	mysqlqueue.Config{
		DriverBaseConfig: queueconfig.DriverBaseConfig{
			DefaultQueue: "critical", // default if empty: "default"
			Observer:     nil,        // default: nil
		},
		DB: nil, // optional; provide *sql.DB instead of DSN
		DSN: "user:pass@tcp(127.0.0.1:3306)/queue?parseTime=true", // optional if DB is set
		DisableAutoMigrate: false, // set true when schema migrations are managed externally
		ProcessingRecoveryGrace:  2 * time.Second, // default if <=0: 2s
		ProcessingLeaseNoTimeout: 5 * time.Minute, // default if <=0: 5m
	},
	queue.WithWorkers(4), // optional; default: 1 worker
)
if err != nil {
	return
}

natsqueue

natsqueue.New

New creates a high-level Queue using the NATS backend.

q, err := natsqueue.New(
	"nats://127.0.0.1:4222",
	queue.WithWorkers(4), // optional; default: runtime.NumCPU() (min 1)
)
if err != nil {
	return
}
natsqueue.NewWithConfig

NewWithConfig creates a high-level Queue using an explicit NATS driver config.

q, err := natsqueue.NewWithConfig(
	natsqueue.Config{
		DriverBaseConfig: queueconfig.DriverBaseConfig{
			DefaultQueue: "critical", // default if empty: "default"
			Observer:     nil,        // default: nil
		},
		URL: "nats://127.0.0.1:4222", // required
	},
	queue.WithWorkers(4), // optional; default: runtime.NumCPU() (min 1)
)
if err != nil {
	return
}

postgresqueue

postgresqueue.New

New creates a high-level Queue using the Postgres SQL backend.

q, err := postgresqueue.New(
	"postgres://user:pass@127.0.0.1:5432/queue?sslmode=disable",
	queue.WithWorkers(4), // optional; default: 1 worker
)
if err != nil {
	return
}
postgresqueue.NewWithConfig

NewWithConfig creates a high-level Queue using an explicit Postgres SQL driver config.

q, err := postgresqueue.NewWithConfig(
	postgresqueue.Config{
		DriverBaseConfig: queueconfig.DriverBaseConfig{
			DefaultQueue: "critical", // default if empty: "default"
			Observer:     nil,        // default: nil
		},
		DB: nil, // optional; provide *sql.DB instead of DSN
		DSN: "postgres://user:pass@127.0.0.1:5432/queue?sslmode=disable", // optional if DB is set
		DisableAutoMigrate: false, // set true when schema migrations are managed externally
		ProcessingRecoveryGrace:  2 * time.Second, // default if <=0: 2s
		ProcessingLeaseNoTimeout: 5 * time.Minute, // default if <=0: 5m
	},
	queue.WithWorkers(4), // optional; default: 1 worker
)
if err != nil {
	return
}

rabbitmqqueue

rabbitmqqueue.New

New creates a high-level Queue using the RabbitMQ backend.

q, err := rabbitmqqueue.New(
	"amqp://guest:guest@127.0.0.1:5672/",
	queue.WithWorkers(4), // optional; default: runtime.NumCPU() (min 1)
)
if err != nil {
	return
}
rabbitmqqueue.NewWithConfig

NewWithConfig creates a high-level Queue using an explicit RabbitMQ driver config.

q, err := rabbitmqqueue.NewWithConfig(
	rabbitmqqueue.Config{
		DriverBaseConfig: queueconfig.DriverBaseConfig{
			DefaultQueue: "critical", // default if empty: "default"
			Observer:     nil,        // default: nil
		},
		URL: "amqp://guest:guest@127.0.0.1:5672/", // required
	},
	queue.WithWorkers(4), // optional; default: runtime.NumCPU() (min 1)
)
if err != nil {
	return
}

redisqueue

redisqueue.New

New creates a high-level Queue using the Redis backend.

q, err := redisqueue.New(
	"127.0.0.1:6379",
	queue.WithWorkers(4), // optional; default: runtime.NumCPU() (min 1)
)
if err != nil {
	return
}
redisqueue.NewWithConfig

NewWithConfig creates a high-level Queue using an explicit Redis driver config.

q, err := redisqueue.NewWithConfig(
	redisqueue.Config{
		DriverBaseConfig: queueconfig.DriverBaseConfig{
			DefaultQueue: "critical", // default if empty: "default"
			Observer:     nil,        // default: nil
		},
		Addr: "127.0.0.1:6379", // required
		Password: "",           // optional; default empty
		DB: 0,                  // optional; default 0
		Logger: nil,            // optional; default backend logger
		ServerLogLevel: redisqueue.ServerLogLevelDefault, // optional
	},
	queue.WithWorkers(4), // optional; default: runtime.NumCPU() (min 1)
)
if err != nil {
	return
}

sqlitequeue

sqlitequeue.New

New creates a high-level Queue using the SQLite SQL backend.

q, err := sqlitequeue.New(
	"file:queue.db?_busy_timeout=5000",
	queue.WithWorkers(4), // optional; default: 1 worker
)
if err != nil {
	return
}
sqlitequeue.NewWithConfig

NewWithConfig creates a high-level Queue using an explicit SQLite SQL driver config.

q, err := sqlitequeue.NewWithConfig(
	sqlitequeue.Config{
		DriverBaseConfig: queueconfig.DriverBaseConfig{
			DefaultQueue: "critical", // default if empty: "default"
			Observer:     nil,        // default: nil
		},
		DB: nil, // optional; provide *sql.DB instead of DSN
		DSN: "file:queue.db?_busy_timeout=5000", // optional if DB is set
		DisableAutoMigrate: false, // set true when schema migrations are managed externally
		ProcessingRecoveryGrace:  2 * time.Second, // default if <=0: 2s
		ProcessingLeaseNoTimeout: 5 * time.Minute, // default if <=0: 5m
	},
	queue.WithWorkers(4), // optional; default: 1 worker
)
if err != nil {
	return
}

sqsqueue

sqsqueue.New

New creates a high-level Queue using the SQS backend.

q, err := sqsqueue.New(
	"us-east-1",
	queue.WithWorkers(4), // optional; default: runtime.NumCPU() (min 1)
)
if err != nil {
	return
}
sqsqueue.NewWithConfig

NewWithConfig creates a high-level Queue using an explicit SQS driver config.

q, err := sqsqueue.NewWithConfig(
	sqsqueue.Config{
		DriverBaseConfig: queueconfig.DriverBaseConfig{
			DefaultQueue: "critical", // default if empty: "default"
			Observer:     nil,        // default: nil
		},
		Region: "us-east-1", // default if empty: "us-east-1"
		Endpoint: "",        // optional; set for LocalStack/custom endpoint
		AccessKey: "",       // optional; static credentials
		SecretKey: "",       // optional; static credentials
	},
	queue.WithWorkers(4), // optional; default: runtime.NumCPU() (min 1)
)
if err != nil {
	return
}

temporalqueue

temporalqueue.NewWithConfig

NewWithConfig constructs a Temporal-backed queue without starting workers.

q, err := temporalqueue.NewWithConfig(temporalqueue.Config{
	DriverBaseConfig:       queueconfig.DriverBaseConfig{DefaultQueue: "reports"},
	ClientOptions:          client.Options{HostPort: "localhost:7233"},
	DefaultActivityTimeout: 30 * time.Second,
	ShutdownTimeout:        15 * time.Second,
}, queue.WithWorkers(4))
if err != nil {
	return
}
defer q.Shutdown(context.Background())
_ = q
Other
Client

Client returns the actual SDK client belonging to this queue resource. Applications borrow it and must leave Close to the resource owner.

ClientBinding.Client

Client returns the actual SDK client for signals, updates, queries and typed workflows.

Close

Close rejects outstanding queue borrowers and joins admitted adapter work. Native SDK callers must be joined by the owner before calling Close.

DecodingLimits

DecodingLimits declares limits enforced inside custom decoding/expansion.

DefaultSerializationLimits

DefaultSerializationLimits returns conservative limits below service message ceilings.

MaxDecodedBytes

MaxDecodedBytes bounds total allocation caused by untrusted propagated headers.

MaxEncodedOverhead

MaxEncodedOverhead bounds bytes added beyond JSON encoding, including protection metadata.

Namespace

Namespace returns the namespace fixed when this binding was constructed.

NewClientBinding

NewClientBinding creates a lazy SDK client with bounded conversion and redacted diagnostics. It does not connect or create a namespace during construction.

NewProtectedFailureConverter

NewProtectedFailureConverter preserves native failure details through an approved protected data converter. Error type names remain visible because Temporal uses them for retry matching.

NewWorkflowReplayer

NewWorkflowReplayer creates an SDK replayer with this resource's authoritative serialization policy. Its immutable registration plan is shared with worker startup and must contain deterministic definitions. Finish replays before closing this resource, or use a separate read/replay resource with a retained binding. Raw-history replay is routed through the stable namespace-aware SDK path so protected converters receive the same namespace as the original execution.

ProtectsFailureDetails

ProtectsFailureDetails confirms the adapter's authenticated encryption policy.

RegistrationFingerprint

RegistrationFingerprint returns the current native and logical handler catalog digest.

ValidateProtectedPayload

ValidateProtectedPayload checks the adapter's mandatory protection envelope.

WorkerRouting

WorkerRouting returns the actual SDK task queues without silently rewriting native activity options.

Testing API

queue.NewFake is a recording fake with its established Dispatch(any) error surface. Inject it where *queue.FakeQueue or that recording contract is accepted; it is not a drop-in *queue.Queue.

Examples in this section assume they are used inside tests and t is a *testing.T (or testing.TB).

FakeQueue.AssertBatchCount

AssertBatchCount fails unless the accepted batch count equals expected.

fake := queue.NewFake()
_, _ = fake.Batch(queue.NewJob("emails:send")).Dispatch(context.Background())
fake.AssertBatchCount(t, 1)
FakeQueue.AssertBatched

AssertBatched fails unless an accepted canonical batch matches predicate. The predicate runs outside the recorder lock so it may safely inspect the fake.

fake := queue.NewFake()
_, _ = fake.Batch(queue.NewJob("emails:send")).Name("nightly").Dispatch(context.Background())
fake.AssertBatched(t, func(record queue.BatchRecord) bool { return record.Name == "nightly" })
FakeQueue.AssertChained

AssertChained fails unless an accepted chain has the expected ordered job types.

fake := queue.NewFake()
_, _ = fake.Chain(
	queue.NewJob("reports:build"),
	queue.NewJob("reports:publish"),
).Dispatch(context.Background())
fake.AssertChained(t, []string{"reports:build", "reports:publish"})
FakeQueue.AssertCount

AssertCount fails when the direct dispatch count is not expected.

fake := queue.NewFake()
_ = fake.Dispatch(queue.NewJob("emails:send"))
fake.AssertCount(t, 1)
FakeQueue.AssertDispatched

AssertDispatched fails when jobType was not dispatched.

fake := queue.NewFake()
_ = fake.Dispatch(queue.NewJob("emails:send"))
fake.AssertDispatched(t, "emails:send")
FakeQueue.AssertDispatchedOn

AssertDispatchedOn fails when jobType was not dispatched on queueName.

fake := queue.NewFake()
_ = fake.Dispatch(
	queue.NewJob("emails:send").
		OnQueue("critical"),
)
fake.AssertDispatchedOn(t, "critical", "emails:send")
FakeQueue.AssertDispatchedTimes

AssertDispatchedTimes fails when jobType dispatch count does not match expected.

fake := queue.NewFake()
_ = fake.Dispatch(queue.NewJob("emails:send"))
_ = fake.Dispatch(queue.NewJob("emails:send"))
fake.AssertDispatchedTimes(t, "emails:send", 2)
FakeQueue.AssertNotDispatched

AssertNotDispatched fails when jobType was dispatched.

fake := queue.NewFake()
_ = fake.Dispatch(queue.NewJob("emails:send"))
fake.AssertNotDispatched(t, "emails:cancel")
FakeQueue.AssertNothingBatched

AssertNothingBatched fails when any accepted batch was recorded.

FakeQueue.AssertNothingDispatched

AssertNothingDispatched fails when any direct dispatch was recorded.

fake := queue.NewFake()
fake.AssertNothingDispatched(t)
FakeQueue.Batch

Batch creates a fake batch backed by the production workflow builder and records it only when Dispatch accepts all initial member deliveries. Fluent function callbacks are accepted for compatibility but are not retained in fake runtime state or executed.

FakeQueue.BatchRecords

BatchRecords returns isolated creation records for accepted fake batches.

fake := queue.NewFake()
_, _ = fake.Batch(
	queue.NewJob("emails:first"),
	queue.NewJob("emails:second"),
).Name("nightly").AllowFailures().Dispatch(context.Background())
record := fake.BatchRecords()[0]
fmt.Println(record.Name, len(record.Jobs), record.AllowFailed)
// Output: nightly 2 true
FakeQueue.Chain

Chain creates a fake chain backed by the production workflow builder and records it only when Dispatch accepts its initial delivery. Fluent function callbacks are accepted for compatibility but are not retained in fake runtime state or executed.

FakeQueue.ChainRecords

ChainRecords returns isolated creation records for accepted fake chains.

fake := queue.NewFake()
_, _ = fake.Chain(
	queue.NewJob("reports:build"),
	queue.NewJob("reports:publish"),
).OnQueue("workflow").Dispatch(context.Background())
record := fake.ChainRecords()[0]
fmt.Println(len(record.Nodes), record.Queue)
// Output: 2 workflow
FakeQueue.Dispatch

Dispatch records a typed job payload in-memory using the fake default queue.

fake := queue.NewFake()
err := fake.Dispatch(queue.NewJob("emails:send").OnQueue("default"))
FakeQueue.Driver

Driver returns the active queue driver.

fake := queue.NewFake()
driver := fake.Driver()
FakeQueue.FindBatch

FindBatch returns workflow state created by the fake's production engine.

FakeQueue.FindChain

FindChain returns workflow state created by the fake's production engine.

NewFake

NewFake creates the canonical fake for direct and workflow tests.

fake := queue.NewFake()
_ = fake.Dispatch(
	queue.NewJob("emails:send").
		Payload(map[string]any{"id": 1}).
		OnQueue("critical"),
)
records := fake.Records()
fmt.Println(len(records), records[0].Queue, records[0].Job.Type)
// Output: 1 critical emails:send
FakeQueue.Prune

Prune removes terminal workflow state while retaining fake dispatch records.

FakeQueue.Ready

Ready validates fake queue readiness.

fake := queue.NewFake()
fmt.Println(fake.Ready(context.Background()) == nil)
// Output: true
FakeQueue.Records

Records returns isolated records for accepted direct dispatches. Chain and batch creation is available through ChainRecords and BatchRecords.

fake := queue.NewFake()
_ = fake.Dispatch(queue.NewJob("emails:send").OnQueue("default"))
records := fake.Records()
fmt.Println(len(records), records[0].Job.Type)
// Output: 1 emails:send
FakeQueue.Register

Register is a compatibility no-op because the recording fake never executes handlers.

fake := queue.NewFake()
fake.Register("emails:send", func(context.Context, queue.Job) error { return nil })
FakeQueue.Reset

Reset clears direct dispatches and all workflow records through every fake view.

fake := queue.NewFake()
_ = fake.Dispatch(queue.NewJob("emails:send").OnQueue("default"))
fmt.Println(len(fake.Records()))
fake.Reset()
fmt.Println(len(fake.Records()))
// Output:
// 1
// 0
FakeQueue.Shutdown

Shutdown is a compatibility no-op because the recording fake owns no worker resources.

fake := queue.NewFake()
err := fake.Shutdown(context.Background())
FakeQueue.StartWorkers

StartWorkers is a compatibility no-op because the recording fake owns no workers.

fake := queue.NewFake()
err := fake.StartWorkers(context.Background())
FakeQueue.WithContext

WithContext returns a derived fake queue handle bound to ctx.

FakeQueue.Workers

Workers preserves fluent lifecycle compatibility without creating workers.

fake := queue.NewFake()
q := fake.Workers(4)
fmt.Println(q != nil)
// Output: true

Development

Use make test for root-module tests, make vet for static checks, and make generate to refresh generated documentation. make test-integration runs the separate integration module; pass a backend such as make test-integration sqlite to narrow the matrix. Integration tests may need local services.

Driver, docs, examples, and integration directories are independent Go modules; test each changed module from its directory. Matrix status and backend notes are tracked in docs/integration-scenarios.md.

Documentation

Index

Constants

View Source
const DriverJobMetadataVersion = busruntime.DeliveryMetadataVersion

DriverJobMetadataVersion identifies the direct-delivery metadata understood by this version of the driver integration contract. @group Driver Integration

Variables

View Source
var (
	// ErrSkipped identifies a job intentionally suppressed by middleware.
	ErrSkipped = errors.New("bus job skipped by middleware")
	// ErrRateLimited identifies a job rejected by its configured rate limiter.
	ErrRateLimited = errors.New("bus job rate limited")
	// ErrOverlapping identifies a job rejected because its execution key is already locked.
	ErrOverlapping = errors.New("bus job overlap prevented")
)
View Source
var ErrBackoffUnsupported = errors.New("backoff option is not supported by this driver")

ErrBackoffUnsupported indicates requested backoff is unsupported by a driver.

View Source
var ErrDuplicate = errors.New("duplicate job")

ErrDuplicate indicates a duplicate unique job enqueue.

View Source
var ErrPauseUnsupported = errors.New("pause/resume is not supported by this driver")

ErrPauseUnsupported indicates queue pause/resume is unsupported by a driver.

View Source
var ErrQueueAdminUnsupported = errors.New("queue admin is not supported by this driver")

ErrQueueAdminUnsupported indicates queue admin operations are unsupported by a driver. @group Admin

View Source
var ErrQueuePaused = errors.New("queue is paused")

ErrQueuePaused indicates enqueue was rejected because queue is paused.

View Source
var ErrQueuerShuttingDown = errors.New("queue is shutting down")

ErrQueuerShuttingDown indicates enqueue was rejected during shutdown.

View Source
var ErrWorkerpoolQueueNotInitialized = errors.New("workerpool queue not initialized")

ErrWorkerpoolQueueNotInitialized indicates workerpool queue is unavailable.

View Source
var ErrWorkflowNotFound = workflow.ErrNotFound

ErrWorkflowNotFound indicates a workflow state record is not present. @group Queue

View Source
var ErrWorkflowUnsupported = errors.New("portable workflows are unsupported")

ErrWorkflowUnsupported indicates that the selected driver cannot perform a portable workflow operation. @group Queue

Functions

func CancelJob

func CancelJob(ctx context.Context, q any, jobID string) error

CancelJob cancels a job when supported. @group Admin

Example: cancel a job via helper

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
err = queue.CancelJob(context.Background(), q, "job-id")
_ = err

func ClearQueue

func ClearQueue(ctx context.Context, q any, queueName string) error

ClearQueue clears queue jobs when supported. @group Admin

Example: clear queue via helper

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
err = queue.ClearQueue(context.Background(), q, "default")
_ = err

func DeleteJob

func DeleteJob(ctx context.Context, q any, queueName, jobID string) error

DeleteJob deletes a job when supported. @group Admin

Example: delete a job via helper

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
err = queue.DeleteJob(context.Background(), q, "default", "job-id")
_ = err

func DriverUniqueKey added in v0.3.0

func DriverUniqueKey(job Job, queueName string) string

DriverUniqueKey returns a versioned queue-scoped identity for driver deduplication. Correlation IDs and delivery policy are excluded when a workflow envelope carries a logical job. @group Driver Integration

func IsPermanent added in v0.3.0

func IsPermanent(err error) bool

IsPermanent reports whether an error requests terminal application settlement. @group Queue

func Pause

func Pause(ctx context.Context, q any, queueName string) error

Pause pauses queue consumption for drivers that support it. @group Observability

Example: pause queue

q, _ := queue.NewSync()
_ = queue.Pause(context.Background(), q, "default")
snapshot, _ := queue.Snapshot(context.Background(), q, nil)
fmt.Println(snapshot.Paused("default"))
// Output: 1

func Permanent added in v0.3.0

func Permanent(err error) error

Permanent marks an error as terminal so workers do not spend the remaining application retry budget on it. @group Queue

func PhysicalQueueName added in v0.1.17

func PhysicalQueueName(defaultQueue string, queueName string) string

PhysicalQueueName maps a logical queue name into the physical name used by the backing queue driver.

func PhysicalQueueWeights added in v0.1.17

func PhysicalQueueWeights(defaultQueue string, weights map[string]int) map[string]int

PhysicalQueueWeights maps logical weighted queue names into their physical backend names.

func Ready

func Ready(ctx context.Context, q any) error

Ready validates backend readiness for the provided queue runtime. @group Observability

Example: ready via package helper

q, _ := queue.NewSync()
fmt.Println(queue.Ready(context.Background(), q) == nil)
// true

func ResolveObservedJobType added in v0.1.8

func ResolveObservedJobType(rawType string, payload []byte) string

ResolveObservedJobType returns the effective application job type that should be emitted to observers. External workers may process private workflow delivery envelopes (for example, "bus:job") whose payload embeds the real application job type. When possible, this helper unwraps that payload so dashboards and metrics reflect the user-facing job type instead of the transport wrapper.

func Resume

func Resume(ctx context.Context, q any, queueName string) error

Resume resumes queue consumption for drivers that support it. @group Observability

Example: resume queue

q, _ := queue.NewSync()
_ = queue.Pause(context.Background(), q, "default")
_ = queue.Resume(context.Background(), q, "default")
snapshot, _ := queue.Snapshot(context.Background(), q, nil)
fmt.Println(snapshot.Paused("default"))
// Output: 0

func RetryJob

func RetryJob(ctx context.Context, q any, queueName, jobID string) error

RetryJob retries (runs now) a job when supported. @group Admin

Example: retry a job via helper

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
err = queue.RetryJob(context.Background(), q, "default", "job-id")
_ = err

func SafeObserve

func SafeObserve(ctx context.Context, observer Observer, event Event)

SafeObserve delivers an event to an observer and recovers observer panics.

This is an advanced helper intended for driver-module implementations. @group Observability

func SupportsNativeStats

func SupportsNativeStats(q any) bool

SupportsNativeStats reports whether a queue runtime exposes native stats snapshots. @group Observability

Example: check native stats support

q, _ := queue.NewSync()
fmt.Println(queue.SupportsNativeStats(q))
// Output: true

func SupportsPause

func SupportsPause(q any) bool

SupportsPause reports whether a queue runtime supports Pause/Resume. @group Observability

Example: check pause support

q, _ := queue.NewSync()
fmt.Println(queue.SupportsPause(q))
// Output: true

func SupportsQueueAdmin

func SupportsQueueAdmin(q any) bool

SupportsQueueAdmin reports whether queue admin operations are available. @group Admin

Example: detect admin support

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
fmt.Println(queue.SupportsQueueAdmin(q))
// Output: true

func ValidateDriverJob

func ValidateDriverJob(job Job) error

ValidateDriverJob validates a job value for backend dispatch.

This is an advanced helper intended for driver-module implementations. @group Driver Integration

Types

type BatchBuilder

type BatchBuilder interface {
	// Name assigns an application-facing label to the batch.
	Name(name string) BatchBuilder
	// OnQueue applies a default queue to batch jobs without an explicit target.
	OnQueue(queue string) BatchBuilder
	// AllowFailures keeps remaining members active after a terminal member failure.
	AllowFailures() BatchBuilder
	// Progress registers the explicitly ephemeral batch progress callback.
	Progress(fn func(ctx context.Context, st BatchState) error) BatchBuilder
	// Then registers the explicitly ephemeral batch success callback.
	Then(fn func(ctx context.Context, st BatchState) error) BatchBuilder
	// Catch registers the explicitly ephemeral batch failure callback.
	Catch(fn func(ctx context.Context, st BatchState, err error) error) BatchBuilder
	// Finally registers the explicitly ephemeral batch terminal callback.
	Finally(fn func(ctx context.Context, st BatchState) error) BatchBuilder
	// Dispatch persists and starts the batch workflow.
	Dispatch(ctx context.Context) (string, error)
}

BatchBuilder is the high-level batch workflow builder. @group Queue

type BatchJob added in v0.3.0

type BatchJob struct {
	JobID string
	Job   StoredJob
}

BatchJob is one persisted member of a batch workflow. @group Queue

type BatchJobOutcome added in v0.3.0

type BatchJobOutcome string

BatchJobOutcome identifies the durable result that first settled one batch member. @group Queue

const (
	// BatchJobSucceeded records successful member settlement.
	// @group Queue
	BatchJobSucceeded BatchJobOutcome = "succeeded"
	// BatchJobFailed records failed member settlement.
	// @group Queue
	BatchJobFailed BatchJobOutcome = "failed"
)

type BatchRecord added in v0.3.0

type BatchRecord struct {
	BatchID     string
	DispatchID  string
	Name        string
	Queue       string
	AllowFailed bool
	Jobs        []BatchJob
	CreatedAt   time.Time
}

BatchRecord is the persisted representation used to create a batch workflow. @group Queue

type BatchState

type BatchState struct {
	BatchID     string
	DispatchID  string
	Name        string
	Queue       string
	AllowFailed bool
	Total       int
	Pending     int
	Processed   int
	Failed      int
	Cancelled   bool
	Completed   bool
	CreatedAt   time.Time
	UpdatedAt   time.Time
}

BatchState is the persisted aggregate execution view of a batch workflow. @group Queue

type ChainBuilder

type ChainBuilder interface {
	// OnQueue applies a default queue to chain jobs without an explicit target.
	OnQueue(queue string) ChainBuilder
	// Catch registers the explicitly ephemeral chain failure callback.
	Catch(fn func(ctx context.Context, st ChainState, err error) error) ChainBuilder
	// Finally registers the explicitly ephemeral chain terminal callback.
	Finally(fn func(ctx context.Context, st ChainState) error) ChainBuilder
	// Dispatch persists and starts the chain workflow.
	Dispatch(ctx context.Context) (string, error)
}

ChainBuilder is the high-level chain workflow builder. @group Queue

type ChainNode added in v0.3.0

type ChainNode struct {
	NodeID string
	Job    StoredJob
}

ChainNode is one persisted step in a chain workflow. @group Queue

type ChainRecord added in v0.3.0

type ChainRecord struct {
	ChainID    string
	DispatchID string
	Queue      string
	Nodes      []ChainNode
	CreatedAt  time.Time
}

ChainRecord is the persisted representation used to create a chain workflow. @group Queue

type ChainState

type ChainState struct {
	ChainID    string
	DispatchID string
	Queue      string
	Nodes      []ChainNode
	NextIndex  int
	Completed  bool
	Failed     bool
	Failure    string
	CreatedAt  time.Time
	UpdatedAt  time.Time
}

ChainState is the persisted view of a chain workflow. @group Queue

type ChannelObserver

type ChannelObserver struct {
	Events     chan<- Event
	DropIfFull bool
}

ChannelObserver forwards events to a channel. @group Observability

func (ChannelObserver) Observe

func (c ChannelObserver) Observe(_ context.Context, event Event)

Observe forwards an event to the configured channel. @group Observability

Example: channel observer

ch := make(chan queue.Event, 1)
observer := queue.ChannelObserver{Events: ch}
observer.Observe(context.Background(), queue.Event{Kind: queue.EventProcessStarted, Queue: "default"})
event := <-ch
_ = event

type Config

type Config struct {
	Driver Driver
	Logger Logger

	DefaultQueue string
}

Config configures queue creation for New (and advanced driver/runtime interop). @group Config

type Continuation added in v0.3.0

type Continuation = busruntime.Continuation

Continuation identifies a durable workflow hook invocation independently of its job payload.

type ContinuationBuilder added in v0.3.0

type ContinuationBuilder struct {
	// contains filtered or unexported fields
}

ContinuationBuilder binds named durable hooks to a snapshot of a configured workflow. Configure the ChainBuilder or BatchBuilder before passing it to Continue.

func Continue added in v0.3.0

func Continue(builder any) *ContinuationBuilder

Continue snapshots a queue-owned chain or batch without changing existing builder interfaces. Unsupported custom builders and mixed closure callbacks fail when Dispatch is called. @group Workflows

Example: named durable completion

q, err := queue.NewSync(queue.WithResourceID("reports"))
if err != nil {
	return
}
q.Register("reports:build", func(context.Context, queue.Message) error { return nil })
q.Register("reports:complete", func(_ context.Context, m queue.Message) error {
	invocation, _ := m.Continuation()
	_ = invocation.ID // Stable across retry, suitable for application idempotency.
	return nil
})
if err := q.StartWorkers(context.Background()); err != nil {
	return
}
defer q.Shutdown(context.Background())
id, err := queue.Continue(q.Chain(queue.NewJob("reports:build"))).
	OnCompletion(queue.NewJob("reports:complete")).Dispatch(context.Background())
_ = id
_ = err

func (*ContinuationBuilder) Dispatch added in v0.3.0

func (b *ContinuationBuilder) Dispatch(ctx context.Context) (string, error)

Dispatch validates and accepts one immutable workflow with its durable hook definitions.

func (*ContinuationBuilder) OnCompletion added in v0.3.0

func (b *ContinuationBuilder) OnCompletion(job Job) *ContinuationBuilder

OnCompletion appends a named hook to the first aggregate terminal transition.

func (*ContinuationBuilder) OnFailure added in v0.3.0

func (b *ContinuationBuilder) OnFailure(job Job) *ContinuationBuilder

OnFailure appends a named hook to the first terminal business failure.

func (*ContinuationBuilder) OnProgress added in v0.3.0

func (b *ContinuationBuilder) OnProgress(job Job) *ContinuationBuilder

OnProgress appends a named hook for each first committed batch member outcome.

func (*ContinuationBuilder) OnSuccess added in v0.3.0

func (b *ContinuationBuilder) OnSuccess(job Job) *ContinuationBuilder

OnSuccess appends a named hook to the workflow's successful aggregate transition.

type ContinuationDefinition added in v0.3.0

type ContinuationDefinition struct {
	Phase string
	Job   StoredJob
}

ContinuationDefinition describes a named hook without representing a triggered invocation.

type ContinuationOutcome added in v0.3.0

type ContinuationOutcome = busruntime.ContinuationOutcome

ContinuationOutcome reports a triggered hook's durable scheduling and settlement.

type ContinuationRecord added in v0.3.0

type ContinuationRecord struct {
	WorkflowID  string
	Definitions []ContinuationDefinition
}

ContinuationRecord contains the immutable hook catalog of an accepted fake workflow.

type ContinuationSummary added in v0.3.0

type ContinuationSummary = busruntime.ContinuationSummary

ContinuationSummary contains immutable safe trigger counters and member identity.

type DatabaseConfig

type DatabaseConfig struct {
	DB                       *sql.DB
	DriverName               string
	DSN                      string
	Workers                  int
	PollInterval             time.Duration
	DefaultQueue             string
	AutoMigrate              bool
	DisableAutoMigrate       bool
	ProcessingRecoveryGrace  time.Duration
	ProcessingLeaseNoTimeout time.Duration
	Observer                 Observer
	Logger                   Logger
}

DatabaseConfig configures the SQL-backed database q. @group Config

type DispatchRecord

type DispatchRecord struct {
	Job   Job
	Queue string
}

DispatchRecord captures one dispatch observed by FakeQueue. @group Testing

type DispatchResult

type DispatchResult struct {
	DispatchID string
}

DispatchResult identifies an accepted logical dispatch. @group Queue

type Driver

type Driver string

Driver identifies the queue backend. @group Driver

Example: driver values

fmt.Println(queue.DriverNull, queue.DriverSync, queue.DriverWorkerpool, queue.DriverDatabase, queue.DriverRedis, queue.DriverNATS, queue.DriverSQS, queue.DriverRabbitMQ)
const (
	// DriverNull drops dispatched jobs and performs no execution.
	DriverNull Driver = "null"
	// DriverSync runs handlers inline in the caller goroutine.
	DriverSync Driver = "sync"
	// DriverWorkerpool runs handlers on an in-memory workerpool.
	DriverWorkerpool Driver = "workerpool"
	// DriverDatabase selects the SQL-backed queue backend.
	DriverDatabase Driver = "database"
	// DriverRedis selects the Redis (asynq) backend.
	DriverRedis Driver = "redis"
	// DriverNATS selects the NATS backend.
	DriverNATS Driver = "nats"
	// DriverSQS selects the AWS SQS backend.
	DriverSQS Driver = "sqs"
	// DriverTemporal selects the optional Temporal workflow backend.
	DriverTemporal Driver = "temporal"
	// DriverRabbitMQ selects the RabbitMQ backend.
	DriverRabbitMQ Driver = "rabbitmq"
)

type DriverJobMetadata added in v0.3.0

type DriverJobMetadata = busruntime.DeliveryMetadata

DriverJobMetadata carries stable correlation separately from an application's job type and payload. Drivers persist this metadata alongside their native delivery representation so ordinary jobs do not require a workflow envelope.

This is an advanced type intended for optional driver integrations. @group Driver Integration

func DriverMetadata added in v0.3.0

func DriverMetadata(job Job) DriverJobMetadata

DriverMetadata returns supported direct-delivery correlation attached to job. Unknown metadata versions are intentionally hidden so older workers do not trust fields whose semantics they cannot validate.

This is an advanced helper intended for driver-module implementations. @group Driver Integration

type DriverJobOptions

type DriverJobOptions struct {
	QueueName string
	Timeout   *time.Duration
	MaxRetry  *int
	Attempt   int
	Backoff   *time.Duration
	Delay     time.Duration
	UniqueTTL time.Duration
}

DriverJobOptions exposes parsed job enqueue metadata for driver-module implementations.

This is an advanced type intended for optional driver integrations. @group Driver Integration

func DriverOptions

func DriverOptions(job Job) DriverJobOptions

DriverOptions returns parsed enqueue metadata for backend dispatch.

This is an advanced helper intended for driver-module implementations. @group Driver Integration

type Event

type Event struct {
	SchemaVersion int
	EventID       string
	Layer         EventLayer
	Kind          EventKind
	Driver        Driver
	Queue         string
	JobType       string
	JobKey        string
	DispatchID    string
	JobID         string
	ChainID       string
	BatchID       string
	Attempt       int
	MaxRetry      int
	Scheduled     bool
	Duration      time.Duration
	Err           error
	Time          time.Time
}

Event is emitted through Observer hooks for queue, worker, and workflow activity. @group Driver Integration

type EventKind

type EventKind string

EventKind identifies a queue runtime event. @group Driver Integration

const (
	// EventDispatchStarted indicates public dispatch began.
	EventDispatchStarted EventKind = "dispatch_started"
	// EventDispatchSucceeded indicates the backend accepted the public dispatch; synchronous execution may still return an application error.
	EventDispatchSucceeded EventKind = "dispatch_succeeded"
	// EventDispatchFailed indicates public dispatch failed before backend acceptance.
	EventDispatchFailed EventKind = "dispatch_failed"
	// EventEnqueueAccepted indicates a job was accepted for enqueue.
	EventEnqueueAccepted EventKind = "enqueue_accepted"
	// EventEnqueueRejected indicates enqueue failed.
	EventEnqueueRejected EventKind = "enqueue_rejected"
	// EventEnqueueDuplicate indicates enqueue was rejected as duplicate.
	EventEnqueueDuplicate EventKind = "enqueue_duplicate"
	// EventEnqueueCanceled indicates enqueue was canceled by context.
	EventEnqueueCanceled EventKind = "enqueue_canceled"
	// EventProcessStarted indicates a handler started processing.
	EventProcessStarted EventKind = "process_started"
	// EventProcessSucceeded indicates a handler completed successfully.
	EventProcessSucceeded EventKind = "process_succeeded"
	// EventProcessFailed indicates a handler returned an error or panicked; panics are reported before being rethrown.
	EventProcessFailed EventKind = "process_failed"
	// EventProcessRetried indicates processing began for a numbered application retry attempt; redelivery may repeat the fact.
	EventProcessRetried EventKind = "process_retried"
	// EventProcessArchived indicates a driver confirmed terminal settlement for a failed attempt.
	EventProcessArchived EventKind = "process_archived"
	// EventQueuePaused indicates queue consumption was paused.
	EventQueuePaused EventKind = "queue_paused"
	// EventQueueResumed indicates queue consumption was resumed.
	EventQueueResumed EventKind = "queue_resumed"
	// EventProcessRecovered indicates SQL bulk recovery requeued one stale in-flight claim without loading its identity fields.
	EventProcessRecovered EventKind = "process_recovered"
	// EventRepublishFailed indicates an internal delay/retry republish attempt failed.
	EventRepublishFailed EventKind = "republish_failed"
	// EventSettlementFailed indicates delivery finalization or broker settlement failed or remained ambiguous.
	EventSettlementFailed EventKind = "settlement_failed"
	// EventJobStarted indicates logical job execution began.
	EventJobStarted EventKind = "job_started"
	// EventJobSucceeded indicates logical job execution succeeded.
	EventJobSucceeded EventKind = "job_succeeded"
	// EventJobFailed indicates logical job execution reached a failed outcome.
	EventJobFailed EventKind = "job_failed"
	// EventChainStarted indicates a chain was created and started.
	EventChainStarted EventKind = "chain_started"
	// EventChainAdvanced indicates a chain advanced to its next job.
	EventChainAdvanced EventKind = "chain_advanced"
	// EventChainCompleted indicates a chain completed successfully.
	EventChainCompleted EventKind = "chain_completed"
	// EventChainFailed indicates a chain reached a failed outcome.
	EventChainFailed EventKind = "chain_failed"
	// EventBatchStarted indicates a batch was created and started.
	EventBatchStarted EventKind = "batch_started"
	// EventBatchProgressed indicates a batch job reached a terminal outcome.
	EventBatchProgressed EventKind = "batch_progressed"
	// EventBatchCompleted indicates a batch completed successfully.
	EventBatchCompleted EventKind = "batch_completed"
	// EventBatchFailed indicates a batch reached a failed outcome.
	EventBatchFailed EventKind = "batch_failed"
	// EventBatchCancelled indicates remaining batch work was cancelled.
	EventBatchCancelled EventKind = "batch_cancelled"
	// EventCallbackStarted indicates an ephemeral workflow callback began.
	EventCallbackStarted EventKind = "callback_started"
	// EventCallbackSucceeded indicates an ephemeral workflow callback succeeded.
	EventCallbackSucceeded EventKind = "callback_succeeded"
	// EventCallbackFailed indicates an ephemeral workflow callback failed.
	EventCallbackFailed EventKind = "callback_failed"
)

type EventLayer added in v0.3.0

type EventLayer string

EventLayer identifies the subsystem that committed an observed fact. @group Observability

const (
	// EventLayerQueue identifies dispatch, enqueue, and queue-control facts.
	EventLayerQueue EventLayer = "queue"
	// EventLayerWorker identifies physical delivery and handler-attempt facts.
	EventLayerWorker EventLayer = "worker"
	// EventLayerWorkflow identifies chain, batch, and continuation facts.
	EventLayerWorkflow EventLayer = "workflow"
)

type FailOnError

type FailOnError struct {
	When func(err error) bool
}

FailOnError marks selected handler failures as permanent. @group Queue

func (FailOnError) Handle added in v0.3.0

func (f FailOnError) Handle(ctx context.Context, message Message, next Next) error

Handle wraps matched errors as fatal errors to stop retries.

type FakeQueue

type FakeQueue struct {
	// contains filtered or unexported fields
}

FakeQueue is the concurrency-safe queue and workflow fake for tests. @group Testing

func NewFake

func NewFake() *FakeQueue

NewFake creates the canonical fake for direct and workflow tests. @group Testing

Example: fake queue assertions

fake := queue.NewFake()
_ = fake.Dispatch(
	queue.NewJob("emails:send").
		Payload(map[string]any{"id": 1}).
		OnQueue("critical"),
)
records := fake.Records()
fmt.Println(len(records), records[0].Queue, records[0].Job.Type)
// Output: 1 critical emails:send

func (*FakeQueue) AssertBatchCount added in v0.3.0

func (f *FakeQueue) AssertBatchCount(t testing.TB, expected int)

AssertBatchCount fails unless the accepted batch count equals expected. @group Testing

Example: assert fake batch count

fake := queue.NewFake()
_, _ = fake.Batch(queue.NewJob("emails:send")).Dispatch(context.Background())
fake.AssertBatchCount(t, 1)

func (*FakeQueue) AssertBatched added in v0.3.0

func (f *FakeQueue) AssertBatched(t testing.TB, predicate func(BatchRecord) bool)

AssertBatched fails unless an accepted canonical batch matches predicate. The predicate runs outside the recorder lock so it may safely inspect the fake. @group Testing

Example: assert fake batch policy

fake := queue.NewFake()
_, _ = fake.Batch(queue.NewJob("emails:send")).Name("nightly").Dispatch(context.Background())
fake.AssertBatched(t, func(record queue.BatchRecord) bool { return record.Name == "nightly" })

func (*FakeQueue) AssertChained added in v0.3.0

func (f *FakeQueue) AssertChained(t testing.TB, expected []string)

AssertChained fails unless an accepted chain has the expected ordered job types. @group Testing

Example: assert a fake chain

fake := queue.NewFake()
_, _ = fake.Chain(
	queue.NewJob("reports:build"),
	queue.NewJob("reports:publish"),
).Dispatch(context.Background())
fake.AssertChained(t, []string{"reports:build", "reports:publish"})

func (*FakeQueue) AssertCount

func (f *FakeQueue) AssertCount(t testing.TB, expected int)

AssertCount fails when the direct dispatch count is not expected. @group Testing

Example: assert dispatch count

fake := queue.NewFake()
_ = fake.Dispatch(queue.NewJob("emails:send"))
fake.AssertCount(t, 1)

func (*FakeQueue) AssertDispatched

func (f *FakeQueue) AssertDispatched(t testing.TB, jobType string)

AssertDispatched fails when jobType was not dispatched. @group Testing

Example: assert job type dispatched

fake := queue.NewFake()
_ = fake.Dispatch(queue.NewJob("emails:send"))
fake.AssertDispatched(t, "emails:send")

func (*FakeQueue) AssertDispatchedOn

func (f *FakeQueue) AssertDispatchedOn(t testing.TB, queueName, jobType string)

AssertDispatchedOn fails when jobType was not dispatched on queueName. @group Testing

Example: assert job type dispatched on queue

fake := queue.NewFake()
_ = fake.Dispatch(
	queue.NewJob("emails:send").
		OnQueue("critical"),
)
fake.AssertDispatchedOn(t, "critical", "emails:send")

func (*FakeQueue) AssertDispatchedTimes

func (f *FakeQueue) AssertDispatchedTimes(t testing.TB, jobType string, expected int)

AssertDispatchedTimes fails when jobType dispatch count does not match expected. @group Testing

Example: assert job type dispatched times

fake := queue.NewFake()
_ = fake.Dispatch(queue.NewJob("emails:send"))
_ = fake.Dispatch(queue.NewJob("emails:send"))
fake.AssertDispatchedTimes(t, "emails:send", 2)

func (*FakeQueue) AssertNotDispatched

func (f *FakeQueue) AssertNotDispatched(t testing.TB, jobType string)

AssertNotDispatched fails when jobType was dispatched. @group Testing

Example: assert job type not dispatched

fake := queue.NewFake()
_ = fake.Dispatch(queue.NewJob("emails:send"))
fake.AssertNotDispatched(t, "emails:cancel")

func (*FakeQueue) AssertNothingBatched added in v0.3.0

func (f *FakeQueue) AssertNothingBatched(t testing.TB)

AssertNothingBatched fails when any accepted batch was recorded. @group Testing

func (*FakeQueue) AssertNothingDispatched

func (f *FakeQueue) AssertNothingDispatched(t testing.TB)

AssertNothingDispatched fails when any direct dispatch was recorded. @group Testing

Example: assert nothing dispatched

fake := queue.NewFake()
fake.AssertNothingDispatched(t)

func (*FakeQueue) Batch added in v0.3.0

func (f *FakeQueue) Batch(jobs ...Job) BatchBuilder

Batch creates a fake batch backed by the production workflow builder and records it only when Dispatch accepts all initial member deliveries. Fluent function callbacks are accepted for compatibility but are not retained in fake runtime state or executed. @group Testing

func (*FakeQueue) BatchRecords added in v0.3.0

func (f *FakeQueue) BatchRecords() []BatchRecord

BatchRecords returns isolated creation records for accepted fake batches. @group Testing

Example: inspect a fake batch

fake := queue.NewFake()
_, _ = fake.Batch(
	queue.NewJob("emails:first"),
	queue.NewJob("emails:second"),
).Name("nightly").AllowFailures().Dispatch(context.Background())
record := fake.BatchRecords()[0]
fmt.Println(record.Name, len(record.Jobs), record.AllowFailed)
// Output: nightly 2 true

func (*FakeQueue) BusDispatch

func (f *FakeQueue) BusDispatch(ctx context.Context, jobType string, payload []byte, opts busruntime.JobOptions) error

BusDispatch satisfies the internal orchestration runtime adapter. @group Testing

func (*FakeQueue) BusDispatchDirect added in v0.3.0

func (f *FakeQueue) BusDispatchDirect(ctx context.Context, jobType string, payload []byte, metadata busruntime.DeliveryMetadata, opts busruntime.JobOptions) error

BusDispatchDirect records the application job and its correlation metadata without introducing the legacy workflow envelope. @group Testing

func (*FakeQueue) BusRegister

func (f *FakeQueue) BusRegister(string, busruntime.Handler)

BusRegister satisfies the internal orchestration runtime adapter. @group Testing

func (*FakeQueue) Chain added in v0.3.0

func (f *FakeQueue) Chain(jobs ...Job) ChainBuilder

Chain creates a fake chain backed by the production workflow builder and records it only when Dispatch accepts its initial delivery. Fluent function callbacks are accepted for compatibility but are not retained in fake runtime state or executed. @group Testing

func (*FakeQueue) ChainRecords added in v0.3.0

func (f *FakeQueue) ChainRecords() []ChainRecord

ChainRecords returns isolated creation records for accepted fake chains. @group Testing

Example: inspect a fake chain

fake := queue.NewFake()
_, _ = fake.Chain(
	queue.NewJob("reports:build"),
	queue.NewJob("reports:publish"),
).OnQueue("workflow").Dispatch(context.Background())
record := fake.ChainRecords()[0]
fmt.Println(len(record.Nodes), record.Queue)
// Output: 2 workflow

func (*FakeQueue) ContinuationRecords added in v0.3.0

func (f *FakeQueue) ContinuationRecords() []ContinuationRecord

ContinuationRecords returns accepted fake workflow definitions without phantom pending invocations.

func (*FakeQueue) Dispatch

func (f *FakeQueue) Dispatch(job any) error

Dispatch records a typed job payload in-memory using the fake default queue. @group Testing

Example: dispatch to fake queue

fake := queue.NewFake()
err := fake.Dispatch(queue.NewJob("emails:send").OnQueue("default"))
_ = err

func (*FakeQueue) Driver

func (f *FakeQueue) Driver() Driver

Driver returns the active queue driver. @group Testing

Example: fake driver

fake := queue.NewFake()
driver := fake.Driver()
_ = driver

func (*FakeQueue) FindBatch added in v0.3.0

func (f *FakeQueue) FindBatch(ctx context.Context, batchID string) (BatchState, error)

FindBatch returns workflow state created by the fake's production engine. @group Testing

func (*FakeQueue) FindChain added in v0.3.0

func (f *FakeQueue) FindChain(ctx context.Context, chainID string) (ChainState, error)

FindChain returns workflow state created by the fake's production engine. @group Testing

func (*FakeQueue) FindContinuations added in v0.3.0

func (f *FakeQueue) FindContinuations(ctx context.Context, id string) ([]ContinuationOutcome, error)

FindContinuations returns committed triggered fake outcomes independently of definitions.

func (*FakeQueue) Prune added in v0.3.0

func (f *FakeQueue) Prune(ctx context.Context, before time.Time) error

Prune removes terminal workflow state while retaining fake dispatch records. @group Testing

func (*FakeQueue) Ready

func (f *FakeQueue) Ready(ctx context.Context) error

Ready validates fake queue readiness. @group Testing

Example: fake ready

fake := queue.NewFake()
fmt.Println(fake.Ready(context.Background()) == nil)
// Output: true

func (*FakeQueue) Records

func (f *FakeQueue) Records() []DispatchRecord

Records returns isolated records for accepted direct dispatches. Chain and batch creation is available through ChainRecords and BatchRecords. @group Testing

Example: read records

fake := queue.NewFake()
_ = fake.Dispatch(queue.NewJob("emails:send").OnQueue("default"))
records := fake.Records()
fmt.Println(len(records), records[0].Job.Type)
// Output: 1 emails:send

func (*FakeQueue) Register

func (f *FakeQueue) Register(string, Handler)

Register is a compatibility no-op because the recording fake never executes handlers. @group Testing

Example: register no-op on fake

fake := queue.NewFake()
fake.Register("emails:send", func(context.Context, queue.Job) error { return nil })

func (*FakeQueue) Reset

func (f *FakeQueue) Reset()

Reset clears direct dispatches and all workflow records through every fake view. @group Testing

Example: reset records

fake := queue.NewFake()
_ = fake.Dispatch(queue.NewJob("emails:send").OnQueue("default"))
fmt.Println(len(fake.Records()))
fake.Reset()
fmt.Println(len(fake.Records()))
// Output:
// 1
// 0

func (*FakeQueue) Shutdown

func (f *FakeQueue) Shutdown(context.Context) error

Shutdown is a compatibility no-op because the recording fake owns no worker resources. @group Testing

Example: shutdown fake queue

fake := queue.NewFake()
err := fake.Shutdown(context.Background())
_ = err

func (*FakeQueue) StartWorkers

func (f *FakeQueue) StartWorkers(context.Context) error

StartWorkers is a compatibility no-op because the recording fake owns no workers. @group Testing

Example: start fake workers

fake := queue.NewFake()
err := fake.StartWorkers(context.Background())
_ = err

func (*FakeQueue) WithContext added in v0.1.12

func (f *FakeQueue) WithContext(ctx context.Context) queueRuntime

WithContext returns a derived fake queue handle bound to ctx. @group Testing

func (*FakeQueue) Workers

func (f *FakeQueue) Workers(int) queueRuntime

Workers preserves fluent lifecycle compatibility without creating workers. @group Testing

Example: set worker count

fake := queue.NewFake()
q := fake.Workers(4)
fmt.Println(q != nil)
// Output: true

type Handler

type Handler func(ctx context.Context, job Job) error

Handler processes a job. @group Job

Example: handler

handler := func(ctx context.Context, job queue.Job) error { return nil }
_ = handler

type Job

type Job struct {
	Type string
	// contains filtered or unexported fields
}

Job is a pure queue payload value plus enqueue metadata. @group Job

Example: job

job := queue.NewJob("emails:send").
	PayloadJSON(map[string]string{"to": "user@example.com"}).
	OnQueue("critical")
_ = job

func DriverWithAttempt

func DriverWithAttempt(job Job, attempt int) Job

DriverWithAttempt returns a copy of the job with the attempt number set.

This is an advanced helper intended for driver-module implementations. @group Driver Integration

func DriverWithMetadata added in v0.3.0

func DriverWithMetadata(job Job, metadata DriverJobMetadata) Job

DriverWithMetadata returns a job carrying supported direct-delivery correlation. Unknown versions are ignored while the application payload and delivery policy remain usable.

This is an advanced helper intended for driver-module implementations. @group Driver Integration

func NewJob

func NewJob(jobType string) Job

NewJob creates a job value with a required job type. @group Job

Example: new job

job := queue.NewJob("emails:send")
_ = job

func (Job) Backoff

func (t Job) Backoff(backoff time.Duration) Job

Backoff sets delay between retries. @group Job

Example: backoff

job := queue.NewJob("emails:send").Backoff(500 * time.Millisecond)
_ = job

func (Job) Bind

func (t Job) Bind(dst any) error

Bind unmarshals job payload JSON into dst. @group Job

Example: bind payload

type EmailPayload struct {
	ID int    `json:"id"`
	To string `json:"to"`
}
job := queue.NewJob("emails:send").Payload(EmailPayload{
	ID: 1,
	To: "user@example.com",
})
var payload EmailPayload
if err := job.Bind(&payload); err != nil {
	return
}
_ = payload.To

func (Job) Delay

func (t Job) Delay(delay time.Duration) Job

Delay defers execution by duration. @group Job

Example: delay

job := queue.NewJob("emails:send").Delay(300 * time.Millisecond)
_ = job

func (Job) OnQueue

func (t Job) OnQueue(name string) Job

OnQueue sets the target queue name. @group Job

Example: on queue

job := queue.NewJob("emails:send").OnQueue("critical")
_ = job

func (Job) Payload

func (t Job) Payload(payload any) Job

Payload sets job payload from common value types. @group Job

Example: payload bytes

jobBytes := queue.NewJob("emails:send").Payload([]byte(`{"id":1}`))
_ = jobBytes

Example: payload struct

type Meta struct {
	Nested bool `json:"nested"`
}
type EmailPayload struct {
	ID   int    `json:"id"`
	To   string `json:"to"`
	Meta Meta   `json:"meta"`
}
jobStruct := queue.NewJob("emails:send").Payload(EmailPayload{
	ID:   1,
	To:   "user@example.com",
	Meta: Meta{Nested: true},
})
_ = jobStruct

Example: payload map

jobMap := queue.NewJob("emails:send").Payload(map[string]any{
	"id":  1,
	"to":  "user@example.com",
	"meta": map[string]any{"nested": true},
})
_ = jobMap

func (Job) PayloadAs added in v0.3.0

func (t Job) PayloadAs[T any]() (T, error)

PayloadAs unmarshals the job payload JSON and returns it as T. @group Job

Example: typed job payload

type EmailPayload struct {
	To string `json:"to"`
}
job := queue.NewJob("emails:send").Payload(EmailPayload{To: "user@example.com"})
payload, err := job.PayloadAs[EmailPayload]()
fmt.Println(err == nil, payload.To)
// true user@example.com

func (Job) PayloadBytes

func (t Job) PayloadBytes() []byte

PayloadBytes returns a copy of job payload bytes. @group Job

Example: payload bytes read

job := queue.NewJob("emails:send").Payload([]byte(`{"id":1}`))
payload := job.PayloadBytes()
_ = payload

func (Job) PayloadJSON

func (t Job) PayloadJSON(v any) Job

PayloadJSON marshals payload as JSON. @group Job

Example: payload json

job := queue.NewJob("emails:send").PayloadJSON(map[string]int{"id": 1})
_ = job

func (Job) Retry

func (t Job) Retry(maxRetry int) Job

Retry sets max retry attempts. @group Job

Example: retry

job := queue.NewJob("emails:send").Retry(4)
_ = job

func (Job) Timeout

func (t Job) Timeout(timeout time.Duration) Job

Timeout sets per-job execution timeout. @group Job

Example: timeout

job := queue.NewJob("emails:send").Timeout(10 * time.Second)
_ = job

func (Job) UniqueFor

func (t Job) UniqueFor(ttl time.Duration) Job

UniqueFor enables uniqueness dedupe within the given TTL. @group Job

Example: unique for

job := queue.NewJob("emails:send").UniqueFor(45 * time.Second)
_ = job

type JobSnapshot

type JobSnapshot struct {
	ID            string
	Queue         string
	State         JobState
	Type          string
	Payload       string
	Attempt       int
	MaxRetry      int
	LastError     string
	NextProcessAt *time.Time
	CompletedAt   *time.Time
}

JobSnapshot describes an admin-facing queue job record. @group Admin

type JobState

type JobState string

JobState identifies queue job state used by queue admin APIs. @group Admin

const (
	JobStatePending   JobState = "pending"
	JobStateActive    JobState = "active"
	JobStateScheduled JobState = "scheduled"
	JobStateRetry     JobState = "retry"
	JobStateArchived  JobState = "archived"
	JobStateCompleted JobState = "completed"
)

type ListJobsOptions

type ListJobsOptions struct {
	Queue    string
	State    JobState
	Page     int
	PageSize int
}

ListJobsOptions configures queue admin list jobs calls. @group Admin

func (ListJobsOptions) Normalize

func (o ListJobsOptions) Normalize() ListJobsOptions

Normalize returns a safe options payload with defaults applied. @group Admin

Example: normalize list options

opts := queue.ListJobsOptions{Queue: "", State: "", Page: 0, PageSize: 1000}
normalized := opts.Normalize()
fmt.Println(normalized.Queue, normalized.State, normalized.Page, normalized.PageSize)
// Output: default pending 1 500

type ListJobsResult

type ListJobsResult struct {
	Jobs  []JobSnapshot
	Total int64
}

ListJobsResult contains queue admin job listing output. @group Admin

func ListJobs

func ListJobs(ctx context.Context, q any, opts ListJobsOptions) (ListJobsResult, error)

ListJobs lists jobs for a queue and state when supported. @group Admin

Example: list jobs via helper

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
_, err = queue.ListJobs(context.Background(), q, queue.ListJobsOptions{
	Queue: "default",
	State: queue.JobStatePending,
})
_ = err

type Lock

type Lock interface {
	// Release relinquishes the acquired lease.
	Release(ctx context.Context) error
}

Lock represents an acquired overlap-prevention lease. @group Queue

type Locker

type Locker interface {
	// Acquire attempts to hold key for ttl.
	Acquire(ctx context.Context, key string, ttl time.Duration) (Lock, bool, error)
}

Locker acquires keyed leases for overlap prevention. @group Queue

type Logger

type Logger interface {
	Debug(args ...interface{})
	Info(args ...interface{})
	Warn(args ...interface{})
	Error(args ...interface{})
	Fatal(args ...interface{})
}

Logger is a generic runtime logger contract that drivers may use to surface their internal worker/server lifecycle output.

type Message

type Message struct {
	SchemaVersion int
	DispatchID    string
	JobID         string
	ChainID       string
	BatchID       string
	Attempt       int
	JobType       string
	// contains filtered or unexported fields
}

Message is the delivered logical job message passed to queue handlers and middleware. Its exported fields carry workflow correlation metadata while its payload remains isolated behind PayloadBytes and Bind. @group Queue

func NewMessage added in v0.3.0

func NewMessage(jobType string, payload []byte) Message

NewMessage creates a logical queue message from an application job type and exact payload bytes. The payload is copied so callers can safely reuse or mutate their input buffer. @group Constructors

func (Message) Bind added in v0.3.0

func (m Message) Bind(dst any) error

Bind unmarshals the raw job payload into dst. @group Queue

func (Message) Continuation added in v0.3.0

func (m Message) Continuation() (Continuation, bool)

Continuation returns immutable invocation metadata when this message is a durable hook.

func (Message) PayloadAs added in v0.3.0

func (m Message) PayloadAs[T any]() (T, error)

PayloadAs unmarshals the delivered payload and returns it as T. @group Queue

Example: typed message payload

type EmailPayload struct {
	To string `json:"to"`
}
message := queue.NewMessage("emails:send", []byte(`{"to":"user@example.com"}`))
payload, err := message.PayloadAs[EmailPayload]()
fmt.Println(err == nil, payload.To)
// true user@example.com

func (Message) PayloadBytes added in v0.3.0

func (m Message) PayloadBytes() []byte

PayloadBytes returns an isolated copy of the raw job payload. @group Queue

type Middleware

type Middleware interface {
	// Handle wraps the remaining middleware and handler chain.
	Handle(ctx context.Context, message Message, next Next) error
}

Middleware intercepts logical queue job execution. @group Queue

type MiddlewareFunc

type MiddlewareFunc func(ctx context.Context, message Message, next Next) error

MiddlewareFunc adapts a function to Middleware. @group Queue

func (MiddlewareFunc) Handle added in v0.3.0

func (f MiddlewareFunc) Handle(ctx context.Context, message Message, next Next) error

Handle calls the wrapped middleware function.

type Next

type Next func(ctx context.Context, message Message) error

Next invokes the remaining queue middleware and logical job handler. @group Queue

type NoopLogger

type NoopLogger struct{}

NoopLogger disables driver-managed internal logs when passed through config.

func (NoopLogger) Debug

func (NoopLogger) Debug(...interface{})

func (NoopLogger) Error

func (NoopLogger) Error(...interface{})

func (NoopLogger) Fatal

func (NoopLogger) Fatal(...interface{})

func (NoopLogger) Info

func (NoopLogger) Info(...interface{})

func (NoopLogger) Warn

func (NoopLogger) Warn(...interface{})

type ObservedJobMetadata added in v0.3.0

type ObservedJobMetadata struct {
	JobType    string
	JobKey     string
	DispatchID string
	JobID      string
	ChainID    string
	BatchID    string
}

ObservedJobMetadata contains application identity and correlation resolved from direct driver metadata or a legacy internal delivery envelope. JobKey groups the same logical type and payload used by UniqueFor without becoming its persisted, queue-scoped key. @group Driver Integration

func ResolveObservedJobMetadata added in v0.3.0

func ResolveObservedJobMetadata(rawType string, payload []byte) ObservedJobMetadata

ResolveObservedJobMetadata bridges legacy versioned workflow envelopes into the event model. Direct-aware drivers should use ResolveObservedJobMetadataFromJob. Malformed, unknown-version, and non-internal payloads remain observable as their raw physical job. @group Driver Integration

func ResolveObservedJobMetadataFromJob added in v0.3.0

func ResolveObservedJobMetadataFromJob(job Job) ObservedJobMetadata

ResolveObservedJobMetadataFromJob returns correlation from the direct driver metadata channel when present and otherwise decodes a legacy workflow delivery.

This is an advanced helper intended for optional driver integrations. @group Driver Integration

type Observer

type Observer interface {
	// Observe handles a queue runtime event.
	// @group Observability
	//
	// Example: observe runtime event
	//
	//	var observer queue.Observer
	//	observer.Observe(context.Background(), queue.Event{
	//		Kind:   queue.EventEnqueueAccepted,
	//		Driver: queue.DriverSync,
	//		Queue:  "default",
	//	})
	Observe(ctx context.Context, event Event)
}

Observer receives queue, worker, and workflow events. Implementations must be safe for concurrent calls from dispatchers and workers. @group Observability

func MultiObserver

func MultiObserver(observers ...Observer) Observer

MultiObserver fans out events to multiple observers. @group Observability

Example: fan out to multiple observers

events := make(chan queue.Event, 2)
observer := queue.MultiObserver(
	queue.ChannelObserver{Events: events},
	queue.ObserverFunc(func(context.Context, queue.Event) {}),
)
observer.Observe(context.Background(), queue.Event{Kind: queue.EventEnqueueAccepted})
fmt.Println(len(events))
// Output: 1

type ObserverFunc

type ObserverFunc func(ctx context.Context, event Event)

ObserverFunc adapts a function to an Observer. @group Observability

func (ObserverFunc) Observe

func (f ObserverFunc) Observe(ctx context.Context, event Event)

Observe calls the wrapped function. @group Observability

Example: observer func logging hook

logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
observer := queue.ObserverFunc(func(ctx context.Context, event queue.Event) {
	logger.Info("queue event",
		"kind", event.Kind,
		"driver", event.Driver,
		"queue", event.Queue,
		"job_type", event.JobType,
		"attempt", event.Attempt,
		"max_retry", event.MaxRetry,
		"duration", event.Duration,
		"err", event.Err,
	)
})
observer.Observe(context.Background(), queue.Event{
	Kind:     queue.EventProcessSucceeded,
	Driver:   queue.DriverSync,
	Queue:    "default",
	JobType: "emails:send",
})

type Option

type Option func(*runtimeOptions)

Option configures the high-level queue and workflow runtime. @group Queue

func WithClock

func WithClock(clock func() time.Time) Option

WithClock overrides the workflow runtime clock. @group Queue

Example: workflow clock

q, err := queue.New(
	queue.Config{Driver: queue.DriverSync},
	queue.WithClock(func() time.Time { return time.Unix(0, 0) }),
)
if err != nil {
	return
}
_ = q

func WithHandlerContextDecorator added in v0.1.14

func WithHandlerContextDecorator(fn func(context.Context) context.Context) Option

WithHandlerContextDecorator decorates queue handler execution context before process lifecycle events and handler execution run. @group Queue

Example: decorate handler context

q, err := queue.New(
	queue.Config{Driver: queue.DriverSync},
	queue.WithHandlerContextDecorator(func(ctx context.Context) context.Context {
		return context.WithValue(ctx, "source", "jobs")
	}),
)
if err != nil {
	return
}
_ = q

func WithLegacyDirectEnvelope added in v0.3.0

func WithLegacyDirectEnvelope() Option

WithLegacyDirectEnvelope keeps ordinary dispatches on the version-one `bus:job` wire route during a workers-first migration. Remove this option only after every consumer can process canonical direct deliveries. See the [direct delivery migration guide] for backend-specific rollout and rollback.

[direct delivery migration guide]: https://github.com/goforj/queue/blob/main/docs/direct-delivery-migration.md @group Queue

func WithMiddleware

func WithMiddleware(middlewares ...Middleware) Option

WithMiddleware appends queue workflow middleware. @group Queue

Example: middleware

mw := queue.MiddlewareFunc(func(ctx context.Context, m queue.Message, next queue.Next) error {
	return next(ctx, m)
})
q, err := queue.New(queue.Config{Driver: queue.DriverSync}, queue.WithMiddleware(mw))
if err != nil {
	return
}
_ = q

func WithObserver

func WithObserver(observer Observer) Option

WithObserver installs one observer for queue, worker, and workflow lifecycle events. @group Queue

Example: observe all queue activity

observer := queue.ObserverFunc(func(_ context.Context, event queue.Event) {
	_ = event.Kind
})
q, err := queue.New(queue.Config{Driver: queue.DriverSync}, queue.WithObserver(observer))
if err != nil {
	return
}
_ = q

func WithResourceID added in v0.3.0

func WithResourceID(id string) Option

WithResourceID supplies the stable resource scope used by durable built-in continuation recovery. Use the same value across consumers of one queue and distinct values for independent resources sharing a store.

func WithStore

func WithStore(store WorkflowStore) Option

WithStore overrides the workflow orchestration store. @group Queue

Example: workflow store

var store queue.WorkflowStore
q, err := queue.New(queue.Config{Driver: queue.DriverSync}, queue.WithStore(store))
if err != nil {
	return
}
_ = q

func WithWorkers

func WithWorkers(count int) Option

WithWorkers sets desired worker concurrency before StartWorkers. It applies to high-level queue constructors (for example NewWorkerpool/New/NewSync). @group Queue

Example: constructor workers option

q, err := queue.NewWorkerpool(
	queue.WithWorkers(4), // optional; default: runtime.NumCPU() (min 1)
)
if err != nil {
	return
}
_ = q

type Queue

type Queue struct {
	// contains filtered or unexported fields
}

Queue is the high-level user-facing queue API. It composes shared job execution with the internal workflow coordinator. @group Queue

func New

func New(cfg Config, opts ...Option) (*Queue, error)

New creates the high-level Queue API based on Config.Driver. @group Constructors

Example: create a queue and dispatch a workflow-capable job

q, err := queue.New(queue.Config{Driver: queue.DriverWorkerpool})
if err != nil {
	return
}
type EmailPayload struct {
	ID int `json:"id"`
}
q.Register("emails:send", func(ctx context.Context, m queue.Message) error {
	var payload EmailPayload
	if err := m.Bind(&payload); err != nil {
		return err
	}
	_ = payload
	return nil
})
_ = q.WithWorkers(1).StartWorkers(context.Background()) // optional; default: runtime.NumCPU() (min 1)
defer q.Shutdown(context.Background())
_, _ = q.Dispatch(
	queue.NewJob("emails:send").
		Payload(EmailPayload{ID: 1}).
		OnQueue("default"),
)

func NewNull

func NewNull(opts ...Option) (*Queue, error)

NewNull creates a Queue on the null backend. @group Constructors

Example: null backend

q, err := queue.NewNull()
if err != nil {
	return
}
_ = q

func NewSync

func NewSync(opts ...Option) (*Queue, error)

NewSync creates a Queue on the synchronous in-process backend. @group Constructors

Example: sync backend

q, err := queue.NewSync()
if err != nil {
	return
}
_ = q

func NewWorkerpool

func NewWorkerpool(opts ...Option) (*Queue, error)

NewWorkerpool creates a Queue on the in-process workerpool backend. @group Constructors

Example: workerpool backend

q, err := queue.NewWorkerpool()
if err != nil {
	return
}
_ = q

func (*Queue) Batch

func (r *Queue) Batch(jobs ...Job) BatchBuilder

Batch creates a batch builder for fan-out workflow execution. @group Queue

Example: batch

q, err := queue.NewSync()
if err != nil {
	return
}
q.Register("emails:send", func(ctx context.Context, m queue.Message) error { return nil })
if err := q.StartWorkers(context.Background()); err != nil {
	return
}
defer q.Shutdown(context.Background())
_, _ = q.Batch(
	queue.NewJob("emails:send").Payload(map[string]any{"id": 1}),
	queue.NewJob("emails:send").Payload(map[string]any{"id": 2}),
).Name("send-emails").OnQueue("default").Dispatch(context.Background())

func (*Queue) CancelJob

func (r *Queue) CancelJob(ctx context.Context, jobID string) error

CancelJob cancels a job via queue admin capability when supported. @group Admin

Example: queue method cancel job

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
if !queue.SupportsQueueAdmin(q) {
	return
}
err = q.CancelJob(context.Background(), "job-id")
_ = err

func (*Queue) Chain

func (r *Queue) Chain(jobs ...Job) ChainBuilder

Chain creates a chain builder for sequential workflow execution. @group Queue

Example: chain

q, err := queue.NewSync()
if err != nil {
	return
}
q.Register("first", func(ctx context.Context, m queue.Message) error { return nil })
q.Register("second", func(ctx context.Context, m queue.Message) error { return nil })
if err := q.StartWorkers(context.Background()); err != nil {
	return
}
defer q.Shutdown(context.Background())
_, _ = q.Chain(
	queue.NewJob("first"),
	queue.NewJob("second"),
).OnQueue("default").Dispatch(context.Background())

func (*Queue) ClearQueue

func (r *Queue) ClearQueue(ctx context.Context, queueName string) error

ClearQueue clears queue jobs via queue admin capability when supported. @group Admin

Example: queue method clear queue

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
if !queue.SupportsQueueAdmin(q) {
	return
}
err = q.ClearQueue(context.Background(), "default")
_ = err

func (*Queue) DeleteJob

func (r *Queue) DeleteJob(ctx context.Context, queueName, jobID string) error

DeleteJob deletes a job via queue admin capability when supported. @group Admin

Example: queue method delete job

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
if !queue.SupportsQueueAdmin(q) {
	return
}
err = q.DeleteJob(context.Background(), "default", "job-id")
_ = err

func (*Queue) Dispatch

func (r *Queue) Dispatch(job Job) (DispatchResult, error)

Dispatch enqueues a high-level job using its application type and exact payload bytes together with the queue's bound context. @group Queue

Example: dispatch

q, err := queue.NewSync()
if err != nil {
	return
}
q.Register("emails:send", func(ctx context.Context, m queue.Message) error { return nil })
if err := q.StartWorkers(context.Background()); err != nil {
	return
}
defer q.Shutdown(context.Background())
job := queue.NewJob("emails:send").Payload(map[string]any{"id": 1}).OnQueue("default")
_, _ = q.Dispatch(job)

func (*Queue) Driver

func (r *Queue) Driver() Driver

Driver reports the configured backend driver for the underlying queue runtime. @group Queue

Example: driver

q, err := queue.NewSync()
if err != nil {
	return
}
fmt.Println(q.Driver())
// Output: sync

func (*Queue) FindBatch

func (r *Queue) FindBatch(ctx context.Context, batchID string) (BatchState, error)

FindBatch returns current batch state by ID. @group Queue

Example: find batch

q, err := queue.NewSync()
if err != nil {
	return
}
q.Register("emails:send", func(ctx context.Context, m queue.Message) error { return nil })
batchID, err := q.Batch(queue.NewJob("emails:send")).Dispatch(context.Background())
if err != nil {
	return
}
_, _ = q.FindBatch(context.Background(), batchID)

func (*Queue) FindChain

func (r *Queue) FindChain(ctx context.Context, chainID string) (ChainState, error)

FindChain returns current chain state by ID. @group Queue

Example: find chain

q, err := queue.NewSync()
if err != nil {
	return
}
q.Register("first", func(ctx context.Context, m queue.Message) error { return nil })
chainID, err := q.Chain(queue.NewJob("first")).Dispatch(context.Background())
if err != nil {
	return
}
_, _ = q.FindChain(context.Background(), chainID)

func (*Queue) FindContinuations added in v0.3.0

func (r *Queue) FindContinuations(ctx context.Context, id string) ([]ContinuationOutcome, error)

FindContinuations returns triggered invocation outcomes, including scheduled but unsettled work.

func (*Queue) History

func (r *Queue) History(ctx context.Context, queueName string, window QueueHistoryWindow) ([]QueueHistoryPoint, error)

History returns queue history points via queue admin capability when supported. @group Admin

Example: queue method history

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
points, err := q.History(context.Background(), "default", queue.QueueHistoryHour)
_ = points
_ = err

func (*Queue) ListJobs

func (r *Queue) ListJobs(ctx context.Context, opts ListJobsOptions) (ListJobsResult, error)

ListJobs lists jobs via queue admin capability when supported. @group Admin

Example: queue method list jobs

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
_, err = q.ListJobs(context.Background(), queue.ListJobsOptions{
	Queue: "default",
	State: queue.JobStatePending,
})
_ = err

func (*Queue) Pause

func (r *Queue) Pause(ctx context.Context, queueName string) error

Pause pauses consumption for a queue when supported by the underlying driver. See the README "Queue Backends" table for Pause/Resume support and docs/backend-guarantees.md (Capability Matrix) for broader backend differences. @group Queue

Example: pause queue

q, err := queue.NewSync()
if err != nil {
	return
}
if queue.SupportsPause(q) {
	_ = q.Pause(context.Background(), "default")
}

func (*Queue) Prune

func (r *Queue) Prune(ctx context.Context, before time.Time) error

Prune deletes old workflow state records. @group Queue

Example: prune workflow state

q, err := queue.NewSync()
if err != nil {
	return
}
_ = q.Prune(context.Background(), time.Now().Add(-24*time.Hour))

func (*Queue) Ready

func (r *Queue) Ready(ctx context.Context) error

Ready validates queue backend readiness for dispatch/worker operation. @group Queue

Example: queue ready

q, err := queue.NewSync()
if err != nil {
	return
}
fmt.Println(q.Ready(context.Background()) == nil)
// true

func (*Queue) Register

func (r *Queue) Register(jobType string, handler func(context.Context, Message) error)

Register binds a handler for a high-level job type. @group Queue

Example: register

q, err := queue.NewSync()
if err != nil {
	return
}
type EmailPayload struct {
	ID int `json:"id"`
}
q.Register("emails:send", func(ctx context.Context, m queue.Message) error {
	var payload EmailPayload
	if err := m.Bind(&payload); err != nil {
		return err
	}
	_ = payload
	return nil
})

func (*Queue) Resume

func (r *Queue) Resume(ctx context.Context, queueName string) error

Resume resumes consumption for a queue when supported by the underlying driver. @group Queue

Example: resume queue

q, err := queue.NewSync()
if err != nil {
	return
}
if queue.SupportsPause(q) {
	_ = q.Resume(context.Background(), "default")
}

func (*Queue) RetryJob

func (r *Queue) RetryJob(ctx context.Context, queueName, jobID string) error

RetryJob retries (runs now) a job via queue admin capability when supported. @group Admin

Example: queue method retry job

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
if !queue.SupportsQueueAdmin(q) {
	return
}
err = q.RetryJob(context.Background(), "default", "job-id")
_ = err

func (*Queue) Run

func (r *Queue) Run(ctx context.Context) error

Run starts worker processing, blocks until ctx is canceled, then gracefully shuts down. @group Queue

Example: run until canceled

ctx, cancel := context.WithCancel(context.Background())
defer cancel()
q, err := queue.NewWorkerpool()
if err != nil {
	return
}
q.Register("emails:send", func(ctx context.Context, m queue.Message) error { return nil })
go func() {
	time.Sleep(100 * time.Millisecond)
	cancel()
}()
_ = q.Run(ctx)

func (*Queue) Shutdown

func (r *Queue) Shutdown(ctx context.Context) error

Shutdown drains workers and closes underlying resources. @group Queue

Example: shutdown

q, err := queue.NewWorkerpool()
if err != nil {
	return
}
_ = q.StartWorkers(context.Background())
_ = q.Shutdown(context.Background())

func (*Queue) StartWorkers

func (r *Queue) StartWorkers(ctx context.Context) error

StartWorkers starts worker processing. @group Queue

Example: start workers

q, err := queue.NewWorkerpool()
if err != nil {
	return
}
_ = q.StartWorkers(context.Background())

func (*Queue) Stats

func (r *Queue) Stats(ctx context.Context) (StatsSnapshot, error)

Stats returns a normalized snapshot when supported by the underlying driver. @group Queue

Example: stats

q, err := queue.NewSync()
if err != nil {
	return
}
if queue.SupportsNativeStats(q) {
	_, _ = q.Stats(context.Background())
}

func (*Queue) WithContext added in v0.1.12

func (r *Queue) WithContext(ctx context.Context) *Queue

WithContext returns a derived queue handle bound to ctx. @group Queue

func (*Queue) WithWorkers

func (r *Queue) WithWorkers(count int) *Queue

WithWorkers sets desired worker concurrency before StartWorkers. @group Queue

Example: workers

q, err := queue.NewWorkerpool()
if err != nil {
	return
}
q.WithWorkers(4) // optional; default: runtime.NumCPU() (min 1)

type QueueAdmin

type QueueAdmin interface {
	ListJobs(ctx context.Context, opts ListJobsOptions) (ListJobsResult, error)
	RetryJob(ctx context.Context, queueName, jobID string) error
	CancelJob(ctx context.Context, jobID string) error
	DeleteJob(ctx context.Context, queueName, jobID string) error
	ClearQueue(ctx context.Context, queueName string) error
	History(ctx context.Context, queueName string, window QueueHistoryWindow) ([]QueueHistoryPoint, error)
}

QueueAdmin exposes optional queue admin capabilities. @group Admin

type QueueController

type QueueController interface {
	Pause(ctx context.Context, queueName string) error
	Resume(ctx context.Context, queueName string) error
}

QueueController exposes queue pause/resume controls. @group Observability

type QueueCounters

type QueueCounters struct {
	Pending   int64
	Active    int64
	Scheduled int64
	Retry     int64
	Archived  int64
	Processed int64
	Failed    int64
	Paused    int64
	AvgWait   time.Duration
	AvgRun    time.Duration
}

QueueCounters exposes normalized queue counters collected from events. @group Observability

type QueueHistoryPoint

type QueueHistoryPoint struct {
	At        time.Time
	Processed int64
	Failed    int64
}

QueueHistoryPoint represents processed/failed totals at a point in time. @group Admin

func QueueHistory

func QueueHistory(ctx context.Context, q any, queueName string, window QueueHistoryWindow) ([]QueueHistoryPoint, error)

QueueHistory returns queue history points when supported. @group Admin

Example: history via helper

q, err := redisqueue.New("127.0.0.1:6379")
if err != nil {
	return
}
_, err = queue.QueueHistory(context.Background(), q, "default", queue.QueueHistoryHour)
_ = err

func SinglePointHistory

func SinglePointHistory(snapshot StatsSnapshot, queueName string) []QueueHistoryPoint

SinglePointHistory converts a snapshot into a single current-history point. This helper is intended for driver modules that do not expose historical buckets. @group Admin

Example: single-point history

snapshot := queue.StatsSnapshot{
	ByQueue: map[string]queue.QueueCounters{
		"default": {Processed: 12, Failed: 1},
	},
}
points := queue.SinglePointHistory(snapshot, "default")
fmt.Println(len(points), points[0].Processed, points[0].Failed)
// Output: 1 12 1

func TimelineHistoryFromSnapshot

func TimelineHistoryFromSnapshot(snapshot StatsSnapshot, queueName string, window QueueHistoryWindow) []QueueHistoryPoint

TimelineHistoryFromSnapshot records queue counters and returns windowed points. This is intended for drivers that don't expose native multi-point history. @group Admin

Example: timeline history from snapshots

snapshot := queue.StatsSnapshot{
	ByQueue: map[string]queue.QueueCounters{
		"default": {Processed: 5, Failed: 1},
	},
}
points := queue.TimelineHistoryFromSnapshot(snapshot, "default", queue.QueueHistoryHour)
fmt.Println(len(points) >= 1)
// Output: true

type QueueHistoryProvider

type QueueHistoryProvider interface {
	History(ctx context.Context, queueName string, window QueueHistoryWindow) ([]QueueHistoryPoint, error)
}

QueueHistoryProvider exposes queue history capability independently from full queue admin support. Drivers like sync/workerpool can provide history without supporting per-job admin operations. @group Admin

type QueueHistoryWindow

type QueueHistoryWindow string

QueueHistoryWindow identifies queue history horizon. @group Admin

const (
	QueueHistoryHour QueueHistoryWindow = "hour"
	QueueHistoryDay  QueueHistoryWindow = "day"
	QueueHistoryWeek QueueHistoryWindow = "week"
)

type QueueThroughput

type QueueThroughput struct {
	Hour ThroughputWindow
	Day  ThroughputWindow
	Week ThroughputWindow
}

QueueThroughput contains rolling throughput windows for a queue. @group Observability

type RateLimit

type RateLimit struct {
	Key     func(ctx context.Context, message Message) string
	Limiter RateLimiter
}

RateLimit applies a RateLimiter before handler execution. @group Queue

func (RateLimit) Handle added in v0.3.0

func (r RateLimit) Handle(ctx context.Context, message Message, next Next) error

Handle applies limiter checks before executing the next handler.

type RateLimiter

type RateLimiter interface {
	// Allow returns whether key may execute and any suggested retry delay.
	Allow(ctx context.Context, key string) (allowed bool, retryAfter time.Duration, err error)
}

RateLimiter decides whether a logical key may execute now. @group Queue

type RetryPolicy

type RetryPolicy struct{}

RetryPolicy leaves retry ownership to the underlying worker runtime. @group Queue

func (RetryPolicy) Handle added in v0.3.0

func (RetryPolicy) Handle(ctx context.Context, message Message, next Next) error

Handle passes execution through without modification.

type SQLStoreConfig added in v0.3.0

type SQLStoreConfig struct {
	DB         *sql.DB
	DriverName string
	DSN        string
	// AutoMigrate is retained for source compatibility. NewSQLStore keeps
	// startup schema creation enabled regardless of the false zero value; use
	// NewSQLStoreWithManagedSchema when deployment tooling owns the schema.
	AutoMigrate bool
}

SQLStoreConfig configures connection ownership, dialect binding, and schema setup for a SQL workflow store. @group Queue

type SkipWhen

type SkipWhen struct {
	Predicate func(ctx context.Context, message Message) bool
}

SkipWhen suppresses handler execution when its predicate matches. @group Queue

func (SkipWhen) Handle added in v0.3.0

func (s SkipWhen) Handle(ctx context.Context, message Message, next Next) error

Handle skips job execution when Predicate returns true.

type StatsCollector

type StatsCollector struct {
	// contains filtered or unexported fields
}

StatsCollector aggregates normalized counters from Observer events. @group Observability

func NewStatsCollector

func NewStatsCollector() *StatsCollector

NewStatsCollector creates an event collector for queue counters. @group Constructors

Example: new stats collector

collector := queue.NewStatsCollector()
_ = collector

func (*StatsCollector) Observe

func (c *StatsCollector) Observe(ctx context.Context, event Event)

Observe records an event and updates normalized counters. @group Observability

Example: observe event

collector := queue.NewStatsCollector()
collector.Observe(context.Background(), queue.Event{
	Kind:   queue.EventEnqueueAccepted,
	Driver: queue.DriverSync,
	Queue:  "default",
	Time:   time.Now(),
})

func (*StatsCollector) Snapshot

func (c *StatsCollector) Snapshot() StatsSnapshot

Snapshot returns a copy of collected counters. @group Observability

Example: snapshot print

collector := queue.NewStatsCollector()
collector.Observe(context.Background(), queue.Event{
	Kind:   queue.EventEnqueueAccepted,
	Driver: queue.DriverSync,
	Queue:  "default",
	Time:   time.Now(),
})
collector.Observe(context.Background(), queue.Event{
	Kind:   queue.EventProcessStarted,
	Driver: queue.DriverSync,
	Queue:  "default",
	JobKey: "job-1",
	Time:   time.Now(),
})
collector.Observe(context.Background(), queue.Event{
	Kind:     queue.EventProcessSucceeded,
	Driver:   queue.DriverSync,
	Queue:    "default",
	JobKey:  "job-1",
	Duration: 12 * time.Millisecond,
	Time:     time.Now(),
})
snapshot := collector.Snapshot()
counters, _ := snapshot.Queue("default")
throughput, _ := snapshot.Throughput("default")
fmt.Printf("queues=%v\n", snapshot.Queues())
fmt.Printf("counters=%+v\n", counters)
fmt.Printf("hour=%+v\n", throughput.Hour)
// Output:
// queues=[default]
// counters={Pending:0 Active:0 Scheduled:0 Retry:0 Archived:0 Processed:1 Failed:0 Paused:0 AvgWait:0s AvgRun:12ms}
// hour={Processed:1 Failed:0}

type StatsProvider

type StatsProvider interface {
	Stats(ctx context.Context) (StatsSnapshot, error)
}

StatsProvider exposes driver-native queue snapshots. @group Observability

type StatsSnapshot

type StatsSnapshot struct {
	ByQueue           map[string]QueueCounters
	ThroughputByQueue map[string]QueueThroughput
}

StatsSnapshot is a point-in-time view of counters by queue. @group Observability

func Snapshot

func Snapshot(ctx context.Context, q any, collector *StatsCollector) (StatsSnapshot, error)

Snapshot returns driver-native stats, falling back to collector data. @group Observability

Example: snapshot from queue runtime

q, _ := queue.NewSync()
snapshot, _ := q.Stats(context.Background())
_, ok := snapshot.Queue("default")
fmt.Println(ok)
// Output: true

func (StatsSnapshot) Active

func (s StatsSnapshot) Active(name string) int64

Active returns active count for a queue. @group Observability

Example: active count getter

snapshot := queue.StatsSnapshot{
	ByQueue: map[string]queue.QueueCounters{
		"default": {Active: 2},
	},
}
fmt.Println(snapshot.Active("default"))
// Output: 2

func (StatsSnapshot) Archived

func (s StatsSnapshot) Archived(name string) int64

Archived returns archived count for a queue. @group Observability

Example: archived count getter

snapshot := queue.StatsSnapshot{
	ByQueue: map[string]queue.QueueCounters{
		"default": {Archived: 7},
	},
}
fmt.Println(snapshot.Archived("default"))
// Output: 7

func (StatsSnapshot) Failed

func (s StatsSnapshot) Failed(name string) int64

Failed returns failed count for a queue. @group Observability

Example: failed count getter

snapshot := queue.StatsSnapshot{
	ByQueue: map[string]queue.QueueCounters{
		"default": {Failed: 2},
	},
}
fmt.Println(snapshot.Failed("default"))
// Output: 2

func (StatsSnapshot) Paused

func (s StatsSnapshot) Paused(name string) int64

Paused returns the observed pause state for a queue as zero or one. @group Observability

Example: pause state getter

collector := queue.NewStatsCollector()
collector.Observe(context.Background(), queue.Event{
	Kind:   queue.EventQueuePaused,
	Driver: queue.DriverSync,
	Queue:  "default",
	Time:   time.Now(),
})
snapshot := collector.Snapshot()
fmt.Println(snapshot.Paused("default"))
// Output: 1

func (StatsSnapshot) Pending

func (s StatsSnapshot) Pending(name string) int64

Pending returns pending count for a queue. @group Observability

Example: pending count getter

snapshot := queue.StatsSnapshot{
	ByQueue: map[string]queue.QueueCounters{
		"default": {Pending: 3},
	},
}
fmt.Println(snapshot.Pending("default"))
// Output: 3

func (StatsSnapshot) Processed

func (s StatsSnapshot) Processed(name string) int64

Processed returns processed count for a queue. @group Observability

Example: processed count getter

snapshot := queue.StatsSnapshot{
	ByQueue: map[string]queue.QueueCounters{
		"default": {Processed: 11},
	},
}
fmt.Println(snapshot.Processed("default"))
// Output: 11

func (StatsSnapshot) Queue

func (s StatsSnapshot) Queue(name string) (QueueCounters, bool)

Queue returns queue counters for a queue name. @group Observability

Example: queue counters getter

collector := queue.NewStatsCollector()
collector.Observe(context.Background(), queue.Event{
	Kind:   queue.EventEnqueueAccepted,
	Driver: queue.DriverSync,
	Queue:  "default",
	Time:   time.Now(),
})
snapshot := collector.Snapshot()
counters, ok := snapshot.Queue("default")
fmt.Println(ok, counters.Pending)
// Output: true 1

func (StatsSnapshot) Queues

func (s StatsSnapshot) Queues() []string

Queues returns sorted queue names present in the snapshot. @group Observability

Example: list queues

collector := queue.NewStatsCollector()
collector.Observe(context.Background(), queue.Event{
	Kind:   queue.EventEnqueueAccepted,
	Driver: queue.DriverSync,
	Queue:  "critical",
	Time:   time.Now(),
})
snapshot := collector.Snapshot()
names := snapshot.Queues()
fmt.Println(len(names), names[0])
// Output: 1 critical

func (StatsSnapshot) RetryCount

func (s StatsSnapshot) RetryCount(name string) int64

RetryCount returns retry count for a queue. @group Observability

Example: retry count getter

snapshot := queue.StatsSnapshot{
	ByQueue: map[string]queue.QueueCounters{
		"default": {Retry: 1},
	},
}
fmt.Println(snapshot.RetryCount("default"))
// Output: 1

func (StatsSnapshot) Scheduled

func (s StatsSnapshot) Scheduled(name string) int64

Scheduled returns scheduled count for a queue. @group Observability

Example: scheduled count getter

snapshot := queue.StatsSnapshot{
	ByQueue: map[string]queue.QueueCounters{
		"default": {Scheduled: 4},
	},
}
fmt.Println(snapshot.Scheduled("default"))
// Output: 4

func (StatsSnapshot) Throughput

func (s StatsSnapshot) Throughput(name string) (QueueThroughput, bool)

Throughput returns rolling throughput windows for a queue name. @group Observability

Example: throughput getter

collector := queue.NewStatsCollector()
collector.Observe(context.Background(), queue.Event{
	Kind:   queue.EventProcessSucceeded,
	Driver: queue.DriverSync,
	Queue:  "default",
	Time:   time.Now(),
})
snapshot := collector.Snapshot()
throughput, ok := snapshot.Throughput("default")
fmt.Printf("ok=%v hour=%+v day=%+v week=%+v\n", ok, throughput.Hour, throughput.Day, throughput.Week)
// Output: ok=true hour={Processed:1 Failed:0} day={Processed:1 Failed:0} week={Processed:1 Failed:0}

type StoredJob added in v0.3.0

type StoredJob struct {
	Type    string           `json:"type"`
	Payload []byte           `json:"payload"`
	Options StoredJobOptions `json:"options"`
}

StoredJob is the stable logical-job shape persisted inside workflow records. @group Queue

type StoredJobOptions added in v0.3.0

type StoredJobOptions struct {
	Queue     string
	Delay     time.Duration
	Timeout   time.Duration
	Retry     int
	Backoff   time.Duration
	UniqueFor time.Duration
}

StoredJobOptions is the stable delivery-policy shape persisted inside workflow records. Field names intentionally retain their version-one JSON casing. @group Queue

type ThroughputWindow

type ThroughputWindow struct {
	Processed int64
	Failed    int64
}

ThroughputWindow captures processed vs failed counts in a fixed window. @group Observability

type WithoutOverlapping

type WithoutOverlapping struct {
	Key    func(ctx context.Context, message Message) string
	TTL    time.Duration
	Locker Locker
}

WithoutOverlapping serializes executions that resolve to the same key. @group Queue

func (WithoutOverlapping) Handle added in v0.3.0

func (w WithoutOverlapping) Handle(ctx context.Context, message Message, next Next) error

Handle acquires a lock and prevents concurrent overlap for the same key.

type WorkerpoolConfig

type WorkerpoolConfig struct {
	Workers           int
	QueueCapacity     int
	DefaultJobTimeout time.Duration
}

WorkerpoolConfig configures the in-memory workerpool q. @group Config

type WorkflowOutcomeStore added in v0.3.0

type WorkflowOutcomeStore interface {
	WorkflowStore

	// FailChainNode commits failure only while nodeID is the current unsettled node.
	// owned remains true on replay while that node's failure owns the chain.
	FailChainNode(ctx context.Context, chainID, nodeID string, cause error) (state ChainState, owned bool, err error)
	// SettleBatchJob returns the first committed outcome for one batch member.
	// owned remains true on same-outcome replay and false when the opposite outcome won.
	// Ownership covers the outcome category; BatchState does not retain a per-member cause.
	SettleBatchJob(ctx context.Context, batchID, jobID string, outcome BatchJobOutcome, cause error) (state BatchState, owned bool, err error)
}

WorkflowOutcomeStore strengthens WorkflowStore with first-writer ownership when duplicate physical deliveries disagree about a logical job outcome. Built-in stores implement this additive capability; established custom WorkflowStore implementations remain source-compatible. @group Queue

type WorkflowStore

type WorkflowStore interface {
	// CreateChain persists a newly accepted chain. ChainID and every NodeID must
	// be non-empty, Nodes must contain at least one entry, and NodeIDs must be unique.
	CreateChain(ctx context.Context, rec ChainRecord) error
	// AdvanceChain atomically claims completedNode and returns the current successor.
	// Repeating the same (chainID, completedNode) claim must not advance again.
	// When done is true, GetChain must immediately expose Completed or Failed state.
	AdvanceChain(ctx context.Context, chainID string, completedNode string) (next *ChainNode, done bool, err error)
	// FailChain commits terminal failure without replacing completed state.
	FailChain(ctx context.Context, chainID string, cause error) error
	// GetChain returns current chain state.
	GetChain(ctx context.Context, chainID string) (ChainState, error)

	// CreateBatch persists a newly accepted batch. BatchID and every JobID must
	// be non-empty, Jobs must contain at least one entry, and JobIDs must be unique.
	CreateBatch(ctx context.Context, rec BatchRecord) error
	// MarkBatchJobStarted records that one batch member began execution.
	MarkBatchJobStarted(ctx context.Context, batchID, jobID string) error
	// MarkBatchJobSucceeded commits the first outcome for (batchID, jobID).
	// Duplicate outcomes must return current state without changing counters.
	MarkBatchJobSucceeded(ctx context.Context, batchID, jobID string) (BatchState, bool, error)
	// MarkBatchJobFailed commits the first outcome for (batchID, jobID).
	// Duplicate outcomes must return current state without changing counters.
	MarkBatchJobFailed(ctx context.Context, batchID, jobID string, cause error) (BatchState, bool, error)
	// CancelBatch commits aggregate batch cancellation.
	CancelBatch(ctx context.Context, batchID string) error
	// GetBatch returns current batch state.
	GetBatch(ctx context.Context, batchID string) (BatchState, error)

	// MarkCallbackInvoked atomically claims one callback idempotency key.
	MarkCallbackInvoked(ctx context.Context, key string) (bool, error)
	// Prune removes terminal workflow state older than before.
	Prune(ctx context.Context, before time.Time) error
}

WorkflowStore persists chain, batch, and callback state for orchestration. Implement WorkflowOutcomeStore as well when a custom store must arbitrate contradictory physical deliveries atomically; built-in stores provide both. @group Queue

func NewMemoryStore added in v0.3.0

func NewMemoryStore() WorkflowStore

NewMemoryStore creates an in-memory workflow state store. It copies chain nodes and payload bytes on creation and return so callers retain independent ownership. @group Constructors

func NewSQLStore added in v0.3.0

func NewSQLStore(config SQLStoreConfig) (WorkflowStore, error)

NewSQLStore creates a SQL-backed workflow state store. @group Constructors

func NewSQLStoreWithManagedSchema added in v0.3.0

func NewSQLStoreWithManagedSchema(config SQLStoreConfig) (WorkflowStore, error)

NewSQLStoreWithManagedSchema creates a SQL-backed workflow state store without executing schema DDL. The supplied database must already contain the dialect-correct workflow tables, including transition receipts. @group Constructors

Directories

Path Synopsis
driver
mysqlqueue module
natsqueue module
postgresqueue module
rabbitmqqueue module
redisqueue module
sqlitequeue module
sqlqueuecore module
sqsqueue module
temporalqueue module
integration module
internal
jobidentity
Package jobidentity centralizes logical payload normalization and telemetry correlation shared by queue and workflow layers.
Package jobidentity centralizes logical payload normalization and telemetry correlation shared by queue and workflow layers.
observation
Package observation provides internal fan-out plumbing without depending on the queue package's public event model.
Package observation provides internal fan-out plumbing without depending on the queue package's public event model.
readmecheck
Package readmecheck contains CI-only compile checks for curated manual README snippets.
Package readmecheck contains CI-only compile checks for curated manual README snippets.
runtimehook
Package runtimehook provides a tiny internal hook registry used to avoid import cycles between the public queue package and internal bridge/test helpers introduced during API flattening.
Package runtimehook provides a tiny internal hook registry used to avoid import cycles between the public queue package and internal bridge/test helpers introduced during API flattening.
uniqueness
Package uniqueness provides shared identity-claim primitives for queue drivers.
Package uniqueness provides shared identity-claim primitives for queue drivers.
workflow
Package workflow owns the private workflow protocol and orchestration boundary.
Package workflow owns the private workflow protocol and orchestration boundary.
Package queueconfig contains shared configuration structs used by optional driver modules.
Package queueconfig contains shared configuration structs used by optional driver modules.
Package queuecore contains shared helper logic used by optional driver modules.
Package queuecore contains shared helper logic used by optional driver modules.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL