Overview
The queue package provides three main abstractions:- Processor: Manages a pool of workers that process jobs
- Handler: Defines how to process jobs of a specific type
- Provider: Abstracts the underlying queue implementation (Redis, RabbitMQ, etc.)
Handler Interface
Implement theHandler[T] interface to define job processing logic:
Creating a Handler
Using a Struct
Using a Function
For simple handlers, useHandlerFunc[T]:
Provider Interface
TheProvider[T] interface abstracts the queue implementation:
Creating a Processor
Create a processor with your handler, provider, and configuration:Enqueuing Jobs
Add jobs to the queue using theEnqueue method:
Enqueue method is type-safe - the compiler ensures you only enqueue jobs matching the processor’s type.
Running the Processor
Start the processor to begin processing jobs:Run method:
- Opens the queue provider connection
- Starts the configured number of worker goroutines
- Blocks until the context is cancelled
- Performs graceful shutdown
- Closes the provider connection
Worker Pools
The processor manages a pool of concurrent workers. Each worker:- Runs in its own goroutine
- Has a unique worker ID in the context (
log.WorkerIDKey) - Processes jobs from a shared channel
- Recovers from panics and logs them
- Participates in graceful shutdown
Graceful Shutdown
When the context is cancelled, the processor performs graceful shutdown:1
Stop accepting new jobs
Workers check
ctx.Done() before accepting new jobs from the channel.2
Drain remaining jobs
Workers continue processing jobs already in the channel until the shutdown timeout expires.
3
Log shutdown progress
Workers log when they detect shutdown, when they finish draining, and when timeout expires:
Context-Aware Logging
Each worker has a unique worker ID injected into the context:Complete Example
Error Handling
Handlers should handle errors internally - theHandle method doesn’t return an error. Log errors using the context-aware logger:
Best Practices
Make handlers idempotent
Jobs may be processed more than once due to failures. Design handlers to be safe when re-run.
Use appropriate worker counts
Match worker count to job characteristics: CPU-bound (1x cores), I/O-bound (10-100+).
Set reasonable timeouts
Shutdown timeout should exceed typical job duration to avoid cutting off work.
Log liberally with context
Use
InfoContext and ErrorContext to maintain correlation via worker IDs.