queue

package
v1.0.0-beta.1 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package queue runs background jobs: producers add jobs to a named queue, and processors handle them in workers with retries. A Driver stores the jobs; NewMemory keeps them in the process (lost on restart, for development and tests), and the separate module github.com/dygoframework/dygo/queue/asynq keeps them in Redis.

A provider with a Process method is a processor:

type WelcomeEmail struct{ UserID string }

func (m *Mailer) Process(r *queue.Registry) {
	queue.Handle(r, "welcome-email", m.sendWelcome) // func(ctx, WelcomeEmail) error
}

and producers inject *queue.Queue:

_, err := s.queue.Add(ctx, "welcome-email", WelcomeEmail{UserID: id}, queue.Delay(time.Minute))

Payloads are JSON. A handler error retries the job, up to its attempts (3 by default), with the driver's backoff. dygo generate job writes a processor.

Index

Constants

View Source
const DefaultQueue = "default"

DefaultQueue is the queue of jobs added without On.

Variables

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

ErrDuplicate is returned when a job ID is already queued.

View Source
var ErrSkipRetry = errors.New("queue: skip retry")

ErrSkipRetry marks an error that must not be retried; see SkipRetry.

Functions

func Handle

func Handle[T any](r *Registry, name string, fn func(ctx context.Context, payload T) error, opts ...HandleOption)

Handle registers fn for jobs named name, on DefaultQueue unless the handler options say otherwise. The payload is decoded into a T; a payload that does not decode fails without a retry.

func Module

func Module(o Options) *dygo.Module

Module provides *Queue. It is global; import it once in the root module.

func SkipRetry

func SkipRetry(err error) error

SkipRetry wraps err so the job fails without more attempts.

func WithJob

func WithJob(ctx context.Context, j *Job) context.Context

WithJob returns ctx carrying j. Handlers get it already set.

Types

type AddOption

type AddOption func(*Job)

AddOption configures one job.

func At

func At(t time.Time) AddOption

At runs the job no earlier than t.

func Attempts

func Attempts(n int) AddOption

Attempts sets how many times the job may run (at least 1).

func Delay

func Delay(d time.Duration) AddOption

Delay runs the job no earlier than d from now.

func ID

func ID(id string) AddOption

ID sets the job ID, to deduplicate jobs.

func On

func On(name string) AddOption

On puts the job on queue name instead of DefaultQueue.

type Driver

type Driver interface {
	// Enqueue stores j. It sets j.ID when empty; a driver may reject an ID
	// that is already queued with [ErrDuplicate].
	Enqueue(ctx context.Context, j *Job) error
	// Work delivers jobs of the given queues to handle, at most concurrency
	// at a time, until ctx is cancelled; then it waits for running handlers
	// and returns. When handle returns an error the driver retries the job
	// until MaxAttempts, then keeps it as failed. An error wrapped with
	// [SkipRetry] fails the job at once.
	Work(ctx context.Context, queues []string, concurrency int, handle func(ctx context.Context, j *Job) error) error
}

Driver stores and delivers jobs.

type FailedJob

type FailedJob struct {
	Job *Job
	Err error
	At  time.Time
}

FailedJob is a job that used all its attempts.

type HandleOption

type HandleOption func(*handler)

HandleOption configures a handler.

func FromQueue

func FromQueue(name string) HandleOption

FromQueue makes the handler consume queue name.

type Job

type Job struct {
	ID      string
	Queue   string
	Name    string
	Payload []byte
	// Attempt is 1 on the first run.
	Attempt     int
	MaxAttempts int
	// RunAt is when the job may run first; zero means now.
	RunAt time.Time
}

Job is one unit of work, as a driver stores it.

func JobFrom

func JobFrom(ctx context.Context) (*Job, bool)

JobFrom returns the job being handled, for its ID and attempt.

type Memory

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

Memory is a Driver that keeps jobs in the process. Jobs are lost when the process stops.

func NewMemory

func NewMemory(o MemoryOptions) *Memory

NewMemory returns an in-memory driver.

func (*Memory) Enqueue

func (m *Memory) Enqueue(_ context.Context, j *Job) error

Enqueue implements Driver.

func (*Memory) Failed

func (m *Memory) Failed() []FailedJob

Failed returns the latest jobs that used all their attempts, oldest first.

func (*Memory) Pending

func (m *Memory) Pending() int

Pending returns the number of jobs queued, waiting for a retry or delay, or running.

func (*Memory) Wait

func (m *Memory) Wait(ctx context.Context) error

Wait blocks until no job is pending, or ctx is done. Tests use it after adding jobs.

func (*Memory) Work

func (m *Memory) Work(ctx context.Context, queues []string, concurrency int, handle func(context.Context, *Job) error) error

Work implements Driver. Running handlers get a context that is not cancelled with ctx, so they finish after Work is asked to stop.

type MemoryOptions

type MemoryOptions struct {
	// Backoff is the wait before attempt n+1 after attempt n failed. The
	// default doubles from one second up to one minute.
	Backoff func(attempt int) time.Duration
	// KeepFailed bounds how many failed jobs Failed returns (100 by default).
	KeepFailed int
}

MemoryOptions configures NewMemory.

type Options

type Options struct {
	// Driver stores the jobs. The default is NewMemory(MemoryOptions{}).
	Driver Driver
	// Concurrency is how many jobs run at once (10 by default).
	Concurrency int
	// Attempts is the default number of attempts (3 by default).
	Attempts int
	// NoWorker only produces jobs; another process handles them.
	NoWorker bool
	// OnError gets every failed attempt; the default ignores them.
	OnError func(ctx context.Context, j *Job, err error)
}

Options configures Module.

type Processor

type Processor interface {
	Process(r *Registry)
}

Processor is a provider that handles jobs. Process is called once, during OnModuleInit of the queue.

type Queue

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

Queue adds jobs and, unless Options.NoWorker is set, runs a worker for the registered handlers from OnApplicationBootstrap until BeforeApplicationShutdown, which waits for running jobs.

func New

func New(o Options) *Queue

New returns a queue outside of a module. Use Register, Start and Stop.

func (*Queue) Add

func (q *Queue) Add(ctx context.Context, name string, payload any, opts ...AddOption) (string, error)

Add enqueues a job named name with payload encoded as JSON and returns its ID.

func (*Queue) BeforeApplicationShutdown

func (q *Queue) BeforeApplicationShutdown(ctx context.Context, _ string) error

BeforeApplicationShutdown stops the worker and waits for running jobs.

func (*Queue) Driver

func (q *Queue) Driver() Driver

Driver returns the queue's driver.

func (*Queue) OnApplicationBootstrap

func (q *Queue) OnApplicationBootstrap(context.Context) error

OnApplicationBootstrap starts the worker.

func (*Queue) OnModuleInit

func (q *Queue) OnModuleInit(context.Context) error

OnModuleInit registers every Processor.

func (*Queue) Register

func (q *Queue) Register(p Processor) error

Register adds the handlers of p.

func (*Queue) Start

func (q *Queue) Start() error

Start runs the worker in the background for the queues that have handlers.

func (*Queue) Stop

func (q *Queue) Stop(ctx context.Context) error

Stop ends the worker and waits for running jobs until ctx is done.

type Registry

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

Registry is what a Processor registers its handlers through.

Jump to

Keyboard shortcuts

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