queue

package
v0.0.27 Latest Latest
Warning

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

Go to latest
Published: May 28, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package queue provides foxhound.Queue implementations. The memory package offers an in-process, priority-ordered queue suitable for single-node scraping runs.

Index

Constants

This section is empty.

Variables

View Source
var ErrQueueClosed = errors.New("queue: queue is closed")

ErrQueueClosed is returned when operating on a closed queue.

Functions

func NewMemoryQueue

func NewMemoryQueue() foxhound.Queue

NewMemoryQueue creates a thread-safe, priority-ordered in-memory queue.

Pop blocks until a job is available or the context is cancelled. Close unblocks all waiting Pop callers.

Types

type RedisQueue

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

RedisQueue implements foxhound.Queue using a Redis sorted set.

Jobs are scored so that higher priority always surfaces first. Within a priority tier, FIFO order is preserved by incorporating a microsecond timestamp into the score:

score = -(priority * 1_000_000_000) + created_at_micros

ZPOPMIN selects the member with the lowest score. Negating the priority component ensures higher-priority jobs have a more-negative base score and are therefore selected first. Adding (not subtracting) the microsecond timestamp as a positive offset means an older job (smaller micros) produces a lower overall score than a newer job within the same priority tier, giving correct FIFO ordering. Distributed workers can safely share the same key because ZPOPMIN is atomic.

func NewRedis

func NewRedis(addr, password string, db int, queueKey string) (*RedisQueue, error)

NewRedis creates a RedisQueue that connects to the given Redis address. The connection is tested with a PING; an error is returned if Redis is unavailable.

func NewRedisFromClient

func NewRedisFromClient(client *redis.Client, queueKey string) *RedisQueue

NewRedisFromClient creates a RedisQueue from an existing redis.Client. Ownership of the client is transferred to the queue; Close will close it.

func (*RedisQueue) Close

func (q *RedisQueue) Close() error

Close releases the underlying Redis client.

func (*RedisQueue) Len

func (q *RedisQueue) Len() int

Len returns the number of jobs in the sorted set.

func (*RedisQueue) Pop

func (q *RedisQueue) Pop(ctx context.Context) (*foxhound.Job, error)

Pop atomically removes and returns the highest-priority job. It polls every 100 ms when the queue is empty, respecting context cancellation.

func (*RedisQueue) Push

func (q *RedisQueue) Push(ctx context.Context, job *foxhound.Job) error

Push serialises the job as JSON and adds it to the sorted set with a score that encodes priority and FIFO order.

type ReliableConfig

type ReliableConfig struct {
	// MaxRetries is the maximum number of times a job can fail before moving to DLQ.
	// Default: 3
	MaxRetries int
	// AckTimeout is how long a job can be "in-flight" before being re-queued.
	// Default: 5 minutes
	AckTimeout time.Duration
	// StaleCheckInterval is how often to check for stale in-flight jobs.
	// Default: 30 seconds
	StaleCheckInterval time.Duration
}

ReliableConfig configures the reliable queue wrapper.

func DefaultReliableConfig

func DefaultReliableConfig() ReliableConfig

DefaultReliableConfig returns sensible defaults.

type ReliableQueue

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

ReliableQueue wraps any foxhound.Queue with acknowledgment, retry, and dead-letter queue semantics. Jobs that fail multiple times are moved to the DLQ instead of being retried forever.

func NewReliable

func NewReliable(inner foxhound.Queue, cfg ReliableConfig) *ReliableQueue

NewReliable wraps an existing Queue with reliable delivery semantics.

func (*ReliableQueue) Ack

func (rq *ReliableQueue) Ack(job *foxhound.Job)

Ack acknowledges successful processing of a job.

func (*ReliableQueue) Close

func (rq *ReliableQueue) Close() error

Close stops the stale recovery goroutine and closes the inner queue.

func (*ReliableQueue) DLQ

func (rq *ReliableQueue) DLQ() []*foxhound.Job

DLQ returns all jobs in the dead letter queue.

func (*ReliableQueue) DLQLen

func (rq *ReliableQueue) DLQLen() int

DLQLen returns the number of jobs in the dead letter queue.

func (*ReliableQueue) InFlightLen

func (rq *ReliableQueue) InFlightLen() int

InFlightLen returns the number of jobs currently being processed.

func (*ReliableQueue) Len

func (rq *ReliableQueue) Len() int

Len returns the number of pending jobs in the inner queue.

func (*ReliableQueue) Nack

func (rq *ReliableQueue) Nack(ctx context.Context, job *foxhound.Job)

Nack signals that job processing failed. The job is re-queued or moved to DLQ.

func (*ReliableQueue) Pop

func (rq *ReliableQueue) Pop(ctx context.Context) (*foxhound.Job, error)

Pop returns the next job and tracks it as in-flight.

func (*ReliableQueue) Push

func (rq *ReliableQueue) Push(ctx context.Context, job *foxhound.Job) error

Push delegates to the inner queue.

func (*ReliableQueue) RetryDLQ

func (rq *ReliableQueue) RetryDLQ(ctx context.Context) (int, error)

RetryDLQ moves all DLQ jobs back to the main queue.

type SQLiteQueue

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

SQLiteQueue implements foxhound.Queue using SQLite for durability.

Jobs survive process restarts, making this queue suitable for the resume capability described in the architecture docs. Jobs are stored in a single table and moved from status='pending' to status='processing' on Pop so that concurrent callers each see a distinct job.

func NewSQLite

func NewSQLite(dbPath string) (*SQLiteQueue, error)

NewSQLite opens (or creates) a SQLite database at dbPath and initialises the jobs table.

func (*SQLiteQueue) Close

func (q *SQLiteQueue) Close() error

Close closes the underlying database connection.

func (*SQLiteQueue) Len

func (q *SQLiteQueue) Len() int

Len returns the number of pending jobs (status='pending').

func (*SQLiteQueue) Pop

func (q *SQLiteQueue) Pop(ctx context.Context) (*foxhound.Job, error)

Pop atomically selects the highest-priority pending job and marks it 'processing'. It polls every 100 ms while the queue is empty, and returns when the context is cancelled.

func (*SQLiteQueue) Push

func (q *SQLiteQueue) Push(_ context.Context, job *foxhound.Job) error

Push serialises the job as JSON and inserts it into the jobs table. Duplicate IDs are rejected via the PRIMARY KEY constraint.

Jump to

Keyboard shortcuts

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