Documentation
¶
Overview ¶
Package gopherqueue is an open-source, high-performance distributed task processing library and background job engine for Go.
GopherQueue supports Dual-Mode deployment: 1. Embedded Mode: Imported directly as a Go package (`go get github.com/balramadan/gopherqueue`) inside monolith or microservice Go applications. 2. Standalone Mode: Executed as a standalone worker daemon (`cmd/gopherq-server`) and web dashboard (`cmd/gopherq-dashboard`).
Key Features:
- At-Least-Once Atomic Delivery: Powered by Redis BLMOVE operations to prevent job loss during worker crashes.
- First-Class Rate Limiting Synergy: Native integration with distlimit (`github.com/balramadan/distlimit`). Rate-limited jobs are gracefully deferred to the delayed queue without consuming retry budgets.
- HTTP-Style Middleware Pipeline: Expressive Chi-like middleware chaining (`Use(...)`) supporting structured logging (`slog`), panic recovery, and rate-limiting.
- Zero-Dependency Telemetry: Server-Sent Events (SSE) broadcaster delivering real-time queue metrics to a Vue.js web dashboard.
Basic Usage:
package main
import (
"context"
"fmt"
"log"
"github.com/balramadan/gopherqueue"
gopherqredis "github.com/balramadan/gopherqueue/storage/redis"
"github.com/redis/go-redis/v9"
)
func main() {
rdb := redis.NewClient(&redis.Options{Addr: "localhost:6379"})
store := gopherqredis.NewStore(rdb)
server := gopherqueue.NewServer(
gopherqueue.WithStorage(store),
gopherqueue.WithQueue("default"),
gopherqueue.WithConcurrency(5),
)
server.Register("email:send", func(ctx context.Context, job *gopherqueue.Job) error {
fmt.Printf("Processing job %s\n", job.ID)
return nil
})
if err := server.Run(context.Background()); err != nil {
log.Fatalf("Server error: %v", err)
}
}
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrJobNotFound indicates that the requested job ID does not exist in storage. ErrJobNotFound = errors.New("gopherqueue: job not found") // ErrQueueEmpty indicates that no pending job is available for fetching. ErrQueueEmpty = errors.New("gopherqueue: queue is empty") // ErrInvalidJobData indicates missing required fields when creating or processing a job. ErrInvalidJobData = errors.New("gopherqueue: invalid job data or metadata") // ErrServerClosed indicates operations were attempted on a closed server. ErrServerClosed = errors.New("gopherqueue: server is closed") )
Functions ¶
This section is empty.
Types ¶
type Chain ¶
type Chain struct {
// contains filtered or unexported fields
}
Chain manages an ordered slice of MiddlewareFunc and compiles them into a single Handler.
func NewChain ¶
func NewChain(middlewares ...MiddlewareFunc) Chain
NewChain creates a new Chain instance with the provided middlewares.
func (Chain) Append ¶
func (c Chain) Append(middlewares ...MiddlewareFunc) Chain
Append creates a new Chain by appending additional middlewares to the existing chain.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client provides a producer API for submitting jobs to GopherQueue.
func NewClient ¶
NewClient initializes a new Client instance with functional options.
Example ¶
ExampleNewClient demonstrates how to enqueue immediate and delayed jobs.
store := &mockRootStorage{}
client, err := gopherqueue.NewClient(
gopherqueue.WithStorage(store),
gopherqueue.WithQueue("default"),
)
if err != nil {
fmt.Printf("Failed to create client: %v\n", err)
return
}
job, _ := gopherqueue.NewJob("job-101", "default", "email:send", map[string]any{
"to": "user@example.com",
})
_ = client.Enqueue(context.Background(), job)
_ = client.EnqueueAt(context.Background(), job, time.Now().Add(5*time.Minute))
fmt.Println("Job enqueued successfully")
Output: Job enqueued successfully
type Config ¶
type Config struct {
QueueName string
Concurrency int
PollInterval time.Duration
DefaultTimeout time.Duration
Storage Storage
}
Config holds configuration parameters for Server and Client instances.
type ErrRateLimited ¶
ErrRateLimited is a custom error returned by rate limiting middleware to signal that execution was rate limited and the job should be deferred to the delayed queue.
func IsRateLimited ¶
func IsRateLimited(err error) (*ErrRateLimited, bool)
IsRateLimited inspects an error chain and returns *ErrRateLimited if present.
func (*ErrRateLimited) Error ¶
func (e *ErrRateLimited) Error() string
Error returns a formatted error message.
type HandlerFunc ¶
HandlerFunc is an adapter type allowing ordinary functions to act as a Handler.
func (HandlerFunc) ProcessJob ¶
func (f HandlerFunc) ProcessJob(ctx context.Context, job *Job) error
ProcessJob calls the underlying HandlerFunc.
type HandlerRegistry ¶
type HandlerRegistry struct {
// contains filtered or unexported fields
}
HandlerRegistry maintains a thread-safe mapping of job types to JobHandlers.
func NewHandlerRegistry ¶
func NewHandlerRegistry() *HandlerRegistry
NewHandlerRegistry initializes a new HandlerRegistry instance.
func (*HandlerRegistry) Execute ¶
func (r *HandlerRegistry) Execute(ctx context.Context, job *Job) error
Execute looks up and invokes the registered handler for the job type.
func (*HandlerRegistry) Register ¶
func (r *HandlerRegistry) Register(jobType string, handler JobHandler)
Register registers a handler function for a given job type.
type Job ¶
type Job struct {
ID string `json:"id"`
Queue string `json:"queue"`
Type string `json:"type"`
Payload map[string]any `json:"payload"`
Status JobStatus `json:"status"`
MaxRetries int `json:"max_retries"`
CurrentRetry int `json:"current_retry"`
TimeoutSeconds int `json:"timeout_seconds"`
ExecuteAt int64 `json:"execute_at"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
LastError string `json:"last_error,omitempty"`
}
Job represents a unit of work submitted to GopherQueue.
func UnmarshalJob ¶
UnmarshalJob deserializes a JSON string into a Job instance.
func (*Job) CalculateNextRetryDelay ¶
CalculateNextRetryDelay calculates an exponential backoff delay based on CurrentRetry.
type JobExecutor ¶
JobExecutor defines an interface for executing a job.
type JobHandler ¶
JobHandler represents a handler function signature for processing a job.
type JobStatus ¶
type JobStatus string
JobStatus represents the state of a job in the queue lifecycle.
const ( // StatusEnqueued indicates the job has been submitted to the queue. StatusEnqueued JobStatus = "ENQUEUED" // StatusPending indicates the job is ready to be fetched by a worker. StatusPending JobStatus = "PENDING" // StatusDelayed indicates the job is scheduled to run at a future timestamp. StatusDelayed JobStatus = "DELAYED" // StatusProcessing indicates a worker is actively processing the job. StatusProcessing JobStatus = "PROCESSING" // StatusCompleted indicates the job finished successfully and was ACKed. StatusCompleted JobStatus = "COMPLETED" // StatusFailed indicates job execution failed. StatusFailed JobStatus = "FAILED" // StatusRetrying indicates the job failed and is scheduled for a retry. StatusRetrying JobStatus = "RETRYING" // StatusDeadLetter indicates the job exceeded its maximum retry budget and was moved to DLQ. StatusDeadLetter JobStatus = "DEAD_LETTER" // StatusRateLimited indicates job execution was rate-limited and deferred without incrementing retry count. StatusRateLimited JobStatus = "RATE_LIMITED" )
type MiddlewareFunc ¶
MiddlewareFunc defines a middleware function wrapper around a Handler.
type Option ¶
type Option func(*Config)
Option represents a functional option for configuring Server or Client.
func WithConcurrency ¶
WithConcurrency sets the number of concurrent worker goroutines.
func WithPollInterval ¶
WithPollInterval sets the interval between worker queue polling calls.
func WithStorage ¶
WithStorage sets the storage engine implementation (e.g. redis.Store).
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server represents the main GopherQueue worker engine orchestrator.
func NewServer ¶
NewServer initializes a new Server instance with functional options.
Example ¶
ExampleNewServer demonstrates how to initialize and run a GopherQueue worker server.
store := &mockRootStorage{}
server := gopherqueue.NewServer(
gopherqueue.WithStorage(store),
gopherqueue.WithQueue("default"),
gopherqueue.WithConcurrency(2),
)
server.Register("email:send", func(ctx context.Context, job *gopherqueue.Job) error {
fmt.Printf("Executing job %s of type %s\n", job.ID, job.Type)
return nil
})
// Server is ready to run with server.Run(ctx)
fmt.Println("Server initialized successfully")
Output: Server initialized successfully
func (*Server) Run ¶
Run starts the worker pool and blocks until the context is cancelled or Shutdown is called.
func (*Server) Use ¶
func (s *Server) Use(middlewares ...MiddlewareFunc)
Use appends one or more middlewares to the server's global middleware pipeline.
type Storage ¶
type Storage interface {
Enqueue(ctx context.Context, job *Job) error
Fetch(ctx context.Context, queue string, timeout time.Duration) (*Job, error)
Ack(ctx context.Context, job *Job) error
Nack(ctx context.Context, job *Job, execErr error) error
Reschedule(ctx context.Context, job *Job, delay time.Duration) error
GetPendingCount(ctx context.Context, queue string) (int64, error)
GetProcessingCount(ctx context.Context, queue string) (int64, error)
GetDelayedCount(ctx context.Context, queue string) (int64, error)
GetDLQCount(ctx context.Context, queue string) (int64, error)
}
Storage defines the pluggable storage driver interface required by GopherQueue.
type WorkerPool ¶
type WorkerPool struct {
// contains filtered or unexported fields
}
WorkerPool manages worker goroutines that fetch and process jobs concurrently.
func NewWorkerPool ¶
func NewWorkerPool(queueName string, numWorkers int, pollInterval time.Duration, store Storage, exec JobExecutor) *WorkerPool
NewWorkerPool initializes a new WorkerPool instance.
func (*WorkerPool) Start ¶
func (wp *WorkerPool) Start(ctx context.Context)
Start launches worker goroutines.
func (*WorkerPool) Stop ¶
func (wp *WorkerPool) Stop()
Stop signals all workers to stop and waits for them to finish.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
_examples
|
|
|
basic
command
|
|
|
middleware
command
|
|
|
rate_limited
command
|
|
|
cmd
|
|
|
gopherq-dashboard
command
|
|
|
gopherq-server
command
|
|
|
middleware
|
|