Documentation
¶
Overview ¶
Package scheduler provides delayed job scheduling with distributed workers, retries, lease-based processing, and a pluggable storage abstraction.
Delivery semantics are at-least-once. Handlers should be idempotent.
Index ¶
- Variables
- type EnqueueOptions
- type Handler
- type Job
- type JobState
- type Lease
- type LeaseCompletion
- type LeaseRenewal
- type MemoryStore
- func (s *MemoryStore) Ack(_ context.Context, jobID, leaseID string, now time.Time) error
- func (s *MemoryStore) CompleteLeases(_ context.Context, completions []LeaseCompletion) error
- func (s *MemoryStore) Enqueue(_ context.Context, job *Job) error
- func (s *MemoryStore) Fail(_ context.Context, jobID, leaseID string, now, retryAt time.Time, ...) error
- func (s *MemoryStore) LeaseJobs(_ context.Context, queues []string, workerID string, now time.Time, limit int, ...) ([]*Lease, error)
- func (s *MemoryStore) PromoteDueJobs(_ context.Context, queues []string, now time.Time, limit int) (int, error)
- func (s *MemoryStore) RecoverExpiredLeases(_ context.Context, queues []string, now time.Time, limit int) (int, error)
- func (s *MemoryStore) RenewLease(_ context.Context, jobID, leaseID string, now time.Time, ...) error
- func (s *MemoryStore) RenewLeases(_ context.Context, renewals []LeaseRenewal, now time.Time, ...) error
- func (s *MemoryStore) Stats(_ context.Context, queues []string) ([]Stats, error)
- type Metrics
- type NopMetrics
- func (NopMetrics) RecordEnqueue(context.Context, *Job)
- func (NopMetrics) RecordFailure(context.Context, *Job, error, time.Duration)
- func (NopMetrics) RecordLease(context.Context, *Job)
- func (NopMetrics) RecordRetry(context.Context, *Job, time.Duration)
- func (NopMetrics) RecordSuccess(context.Context, *Job, time.Duration)
- type Producer
- type ProducerConfig
- type QueueTopology
- type QueueVersionConfig
- type RedisConfig
- type RedisStore
- func (s *RedisStore) Ack(ctx context.Context, jobID, leaseID string, now time.Time) error
- func (s *RedisStore) CompleteDrainingVersion(ctx context.Context, queue string, version int) (QueueTopology, error)
- func (s *RedisStore) CompleteLeases(ctx context.Context, completions []LeaseCompletion) error
- func (s *RedisStore) ConfigureQueue(ctx context.Context, queue string, active QueueVersionConfig, ...) error
- func (s *RedisStore) Enqueue(ctx context.Context, job *Job) error
- func (s *RedisStore) Fail(ctx context.Context, jobID, leaseID string, now, retryAt time.Time, ...) error
- func (s *RedisStore) LeaseJobs(ctx context.Context, queues []string, workerID string, now time.Time, ...) ([]*Lease, error)
- func (s *RedisStore) PromoteDueJobs(ctx context.Context, queues []string, now time.Time, limit int) (int, error)
- func (s *RedisStore) PromoteQueueVersion(ctx context.Context, queue string, nextVersion QueueVersionConfig) (QueueTopology, error)
- func (s *RedisStore) QueueTopology(ctx context.Context, queue string) (QueueTopology, error)
- func (s *RedisStore) RecoverExpiredLeases(ctx context.Context, queues []string, now time.Time, limit int) (int, error)
- func (s *RedisStore) RenewLease(ctx context.Context, jobID, leaseID string, now time.Time, ...) error
- func (s *RedisStore) RenewLeases(ctx context.Context, renewals []LeaseRenewal, now time.Time, ...) error
- func (s *RedisStore) Stats(ctx context.Context, queues []string) ([]Stats, error)
- type RetryPolicy
- type Stats
- type Store
- type Worker
- type WorkerConfig
Constants ¶
This section is empty.
Variables ¶
var ( // ErrJobNotFound indicates that a referenced job record does not exist. ErrJobNotFound = errors.New("job not found") // ErrLeaseConflict indicates that the caller does not own the current lease. ErrLeaseConflict = errors.New("lease conflict") // ErrHandlerNotFound indicates that no worker handler was registered for a job type. ErrHandlerNotFound = errors.New("handler not found") // ErrDuplicateJobID indicates that a job with the same ID already exists. ErrDuplicateJobID = errors.New("duplicate job id") // ErrInvalidJobState indicates that a job transition was attempted from an invalid state. ErrInvalidJobState = errors.New("invalid job state") // ErrDuplicateKey indicates that an idempotency key is already associated with another job. ErrDuplicateKey = errors.New("duplicate idempotency key") // ErrStoreRequired indicates that a producer or worker was created without a store. ErrStoreRequired = errors.New("store is required") )
Functions ¶
This section is empty.
Types ¶
type EnqueueOptions ¶
type EnqueueOptions struct {
ID string
Queue string
Type string
Payload []byte
Metadata map[string]string
IdempotencyKey string
RunAt time.Time
Timeout time.Duration
MaxRetries int
}
EnqueueOptions describes a job to be created by a Producer.
type Job ¶
type Job struct {
ID string `json:"id"`
Queue string `json:"queue"`
QueueVersion int `json:"queue_version"`
Partition int `json:"partition"`
Type string `json:"type"`
Payload json.RawMessage `json:"payload"`
Metadata map[string]string `json:"metadata,omitempty"`
IdempotencyKey string `json:"idempotency_key,omitempty"`
State JobState `json:"state"`
RunAt time.Time `json:"run_at"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Timeout time.Duration `json:"timeout"`
Attempts int `json:"attempts"`
MaxRetries int `json:"max_retries"`
LastError string `json:"last_error,omitempty"`
LeaseOwner string `json:"lease_owner,omitempty"`
LeaseExpiresAt time.Time `json:"lease_expires_at"`
LastFinishedAt time.Time `json:"last_finished_at"`
}
Job is the persisted unit of work handled by the scheduler.
type JobState ¶
type JobState string
JobState describes the lifecycle state of a job.
const ( // JobStateScheduled indicates a job is waiting for its run_at time. JobStateScheduled JobState = "scheduled" // JobStateReady indicates a job is available to be leased by a worker. JobStateReady JobState = "ready" // JobStateLeased indicates a worker currently owns the job lease. JobStateLeased JobState = "leased" // JobStateRetryWait indicates a job is waiting for its retry backoff window. JobStateRetryWait JobState = "retry_wait" // JobStateSucceeded indicates a job completed successfully. JobStateSucceeded JobState = "succeeded" // JobStateDead indicates a job exhausted retries and will not be retried automatically. JobStateDead JobState = "dead" )
type LeaseCompletion ¶
type LeaseCompletion struct {
JobID string
LeaseID string
FinishedAt time.Time
RetryAt time.Time
Failure string
Dead bool
}
LeaseCompletion describes the final outcome for a leased job.
type LeaseRenewal ¶
LeaseRenewal identifies a leased job that should have its lease extended.
type MemoryStore ¶
type MemoryStore struct {
// contains filtered or unexported fields
}
MemoryStore is an in-memory Store implementation for tests and local development.
func NewMemoryStore ¶
func NewMemoryStore() *MemoryStore
NewMemoryStore creates an empty in-memory scheduler store.
func (*MemoryStore) Ack ¶
Ack marks a single leased job as successful by delegating to CompleteLeases.
func (*MemoryStore) CompleteLeases ¶
func (s *MemoryStore) CompleteLeases(_ context.Context, completions []LeaseCompletion) error
CompleteLeases applies the final outcomes for multiple leased jobs.
func (*MemoryStore) Enqueue ¶
func (s *MemoryStore) Enqueue(_ context.Context, job *Job) error
Enqueue stores a new job in memory.
func (*MemoryStore) Fail ¶
func (s *MemoryStore) Fail(_ context.Context, jobID, leaseID string, now, retryAt time.Time, failure string, dead bool) error
Fail marks a single leased job as failed by delegating to CompleteLeases.
func (*MemoryStore) LeaseJobs ¶
func (s *MemoryStore) LeaseJobs(_ context.Context, queues []string, workerID string, now time.Time, limit int, leaseDuration time.Duration) ([]*Lease, error)
LeaseJobs leases ready jobs to the given worker.
func (*MemoryStore) PromoteDueJobs ¶
func (s *MemoryStore) PromoteDueJobs(_ context.Context, queues []string, now time.Time, limit int) (int, error)
PromoteDueJobs moves due jobs from scheduled or retry_wait to ready.
func (*MemoryStore) RecoverExpiredLeases ¶
func (s *MemoryStore) RecoverExpiredLeases(_ context.Context, queues []string, now time.Time, limit int) (int, error)
RecoverExpiredLeases returns expired leases back to the ready state.
func (*MemoryStore) RenewLease ¶
func (s *MemoryStore) RenewLease(_ context.Context, jobID, leaseID string, now time.Time, leaseDuration time.Duration) error
RenewLease renews a single lease by delegating to RenewLeases.
func (*MemoryStore) RenewLeases ¶
func (s *MemoryStore) RenewLeases(_ context.Context, renewals []LeaseRenewal, now time.Time, leaseDuration time.Duration) error
RenewLeases renews multiple active leases in memory.
type Metrics ¶
type Metrics interface {
// RecordEnqueue reports that a job was created.
RecordEnqueue(context.Context, *Job)
// RecordLease reports that a worker leased a job for execution.
RecordLease(context.Context, *Job)
// RecordSuccess reports a successful job completion and execution latency.
RecordSuccess(context.Context, *Job, time.Duration)
// RecordFailure reports a failed job completion and execution latency.
RecordFailure(context.Context, *Job, error, time.Duration)
// RecordRetry reports that a failed job was scheduled for another attempt.
RecordRetry(context.Context, *Job, time.Duration)
}
Metrics receives worker lifecycle events for observability integrations.
type NopMetrics ¶
type NopMetrics struct{}
NopMetrics discards all metric events.
func (NopMetrics) RecordEnqueue ¶
func (NopMetrics) RecordEnqueue(context.Context, *Job)
RecordEnqueue implements Metrics and discards the event.
func (NopMetrics) RecordFailure ¶
RecordFailure implements Metrics and discards the event.
func (NopMetrics) RecordLease ¶
func (NopMetrics) RecordLease(context.Context, *Job)
RecordLease implements Metrics and discards the event.
func (NopMetrics) RecordRetry ¶
RecordRetry implements Metrics and discards the event.
func (NopMetrics) RecordSuccess ¶
RecordSuccess implements Metrics and discards the event.
type Producer ¶
type Producer struct {
// contains filtered or unexported fields
}
Producer creates jobs in the configured scheduler store.
func NewProducer ¶
func NewProducer(store Store, config ProducerConfig) (*Producer, error)
NewProducer creates a Producer using the provided store and configuration.
type ProducerConfig ¶
type ProducerConfig struct {
DefaultQueue string
DefaultMaxRetries int
DefaultTimeout time.Duration
DefaultRetryPolicy RetryPolicy
}
ProducerConfig configures default values applied by a Producer when enqueueing jobs.
func DefaultProducerConfig ¶
func DefaultProducerConfig() ProducerConfig
DefaultProducerConfig returns a production-friendly default producer configuration.
func (ProducerConfig) Validate ¶
func (c ProducerConfig) Validate() error
Validate verifies that the producer configuration is internally consistent.
type QueueTopology ¶
type QueueTopology struct {
Active QueueVersionConfig
Draining []QueueVersionConfig
}
QueueTopology describes the active and draining versions for a logical queue.
func (QueueTopology) DrainingVersionNumbers ¶
func (q QueueTopology) DrainingVersionNumbers() []int
DrainingVersionNumbers returns the draining queue versions in ascending order.
type QueueVersionConfig ¶
QueueVersionConfig describes a versioned queue layout and its partition count.
type RedisConfig ¶
type RedisConfig struct {
Prefix string
Partitions int
ActiveVersion int
DrainingVersion []QueueVersionConfig
}
RedisConfig configures the Redis-backed store.
type RedisStore ¶
type RedisStore struct {
// contains filtered or unexported fields
}
RedisStore is a Redis-backed Store implementation with batched coordination operations.
func NewRedisStore ¶
func NewRedisStore(client *redis.Client, prefix string) *RedisStore
NewRedisStore creates a Redis store with a default single-version topology.
func NewRedisStoreWithConfig ¶
func NewRedisStoreWithConfig(client *redis.Client, cfg RedisConfig) *RedisStore
NewRedisStoreWithConfig creates a Redis store with explicit topology defaults.
func (*RedisStore) Ack ¶
Ack marks a single leased job as successful by delegating to CompleteLeases.
func (*RedisStore) CompleteDrainingVersion ¶
func (s *RedisStore) CompleteDrainingVersion(ctx context.Context, queue string, version int) (QueueTopology, error)
CompleteDrainingVersion removes a drained queue version from queue topology metadata.
func (*RedisStore) CompleteLeases ¶
func (s *RedisStore) CompleteLeases(ctx context.Context, completions []LeaseCompletion) error
CompleteLeases applies the final outcomes for multiple leased jobs in Redis.
func (*RedisStore) ConfigureQueue ¶
func (s *RedisStore) ConfigureQueue(ctx context.Context, queue string, active QueueVersionConfig, draining []QueueVersionConfig) error
ConfigureQueue writes queue topology metadata for a logical queue.
func (*RedisStore) Enqueue ¶
func (s *RedisStore) Enqueue(ctx context.Context, job *Job) error
Enqueue stores a new job in Redis using the active queue topology.
func (*RedisStore) Fail ¶
func (s *RedisStore) Fail(ctx context.Context, jobID, leaseID string, now, retryAt time.Time, failure string, dead bool) error
Fail marks a single leased job as failed by delegating to CompleteLeases.
func (*RedisStore) LeaseJobs ¶
func (s *RedisStore) LeaseJobs(ctx context.Context, queues []string, workerID string, now time.Time, limit int, leaseDuration time.Duration) ([]*Lease, error)
LeaseJobs leases ready jobs from Redis across active and draining queue versions.
func (*RedisStore) PromoteDueJobs ¶
func (s *RedisStore) PromoteDueJobs(ctx context.Context, queues []string, now time.Time, limit int) (int, error)
PromoteDueJobs moves due jobs from scheduled or retry_wait to ready across queue versions.
func (*RedisStore) PromoteQueueVersion ¶
func (s *RedisStore) PromoteQueueVersion(ctx context.Context, queue string, nextVersion QueueVersionConfig) (QueueTopology, error)
PromoteQueueVersion activates a new queue version and marks the previous active version as draining.
func (*RedisStore) QueueTopology ¶
func (s *RedisStore) QueueTopology(ctx context.Context, queue string) (QueueTopology, error)
QueueTopology returns the active and draining topology for a logical queue.
func (*RedisStore) RecoverExpiredLeases ¶
func (s *RedisStore) RecoverExpiredLeases(ctx context.Context, queues []string, now time.Time, limit int) (int, error)
RecoverExpiredLeases returns expired leases back to the ready state across queue versions.
func (*RedisStore) RenewLease ¶
func (s *RedisStore) RenewLease(ctx context.Context, jobID, leaseID string, now time.Time, leaseDuration time.Duration) error
RenewLease renews a single lease by delegating to RenewLeases.
func (*RedisStore) RenewLeases ¶
func (s *RedisStore) RenewLeases(ctx context.Context, renewals []LeaseRenewal, now time.Time, leaseDuration time.Duration) error
RenewLeases renews multiple active leases in Redis.
type RetryPolicy ¶
type RetryPolicy struct {
MaxRetries int
InitialBackoff time.Duration
MaxBackoff time.Duration
Multiplier float64
}
RetryPolicy controls retry backoff timing and attempt limits.
func (RetryPolicy) Backoff ¶
func (p RetryPolicy) Backoff(attempt int) time.Duration
Backoff returns the retry delay for the given attempt count.
func (RetryPolicy) Validate ¶
func (p RetryPolicy) Validate() error
Validate verifies that the retry policy is internally consistent.
type Stats ¶
type Stats struct {
Queue string
Scheduled int64
Ready int64
Leased int64
RetryWait int64
Succeeded int64
Dead int64
}
Stats contains queue-level job counts grouped by lifecycle state.
type Store ¶
type Store interface {
// Enqueue persists a new job record.
Enqueue(context.Context, *Job) error
// PromoteDueJobs moves due scheduled or retrying jobs into the ready state.
PromoteDueJobs(context.Context, []string, time.Time, int) (int, error)
// LeaseJobs claims up to limit ready jobs for a worker for the given lease duration.
LeaseJobs(context.Context, []string, string, time.Time, int, time.Duration) ([]*Lease, error)
// RenewLeases extends one or more active leases owned by a worker.
RenewLeases(context.Context, []LeaseRenewal, time.Time, time.Duration) error
// CompleteLeases records the final outcome for one or more leased jobs.
CompleteLeases(context.Context, []LeaseCompletion) error
// RenewLease extends a single active lease.
RenewLease(context.Context, string, string, time.Time, time.Duration) error
// Ack marks a leased job as successful.
Ack(context.Context, string, string, time.Time) error
// Fail marks a leased job as failed and optionally schedules a retry.
Fail(context.Context, string, string, time.Time, time.Time, string, bool) error
// RecoverExpiredLeases returns expired leases back to the ready state.
RecoverExpiredLeases(context.Context, []string, time.Time, int) (int, error)
// Stats returns queue-level lifecycle counts for the requested queues.
Stats(context.Context, []string) ([]Stats, error)
}
Store defines the persistence contract used by producers and workers.
type Worker ¶
type Worker struct {
// contains filtered or unexported fields
}
Worker executes leased jobs from a scheduler store using registered handlers.
func NewWorker ¶
func NewWorker(store Store, config WorkerConfig, logger *slog.Logger, metrics Metrics) (*Worker, error)
NewWorker creates a Worker using the provided store, configuration, logger, and metrics sink.
type WorkerConfig ¶
type WorkerConfig struct {
WorkerID string
Queues []string
Concurrency int
BatchSize int
QueueBuffer int
PollInterval time.Duration
LeaseDuration time.Duration
HeartbeatInterval time.Duration
MaxInFlight int
RetryPolicy RetryPolicy
}
WorkerConfig controls worker batching, concurrency, polling, leasing, and retries.
func DefaultWorkerConfig ¶
func DefaultWorkerConfig(workerID string) WorkerConfig
DefaultWorkerConfig returns a worker configuration with balanced defaults for general use.
func (WorkerConfig) Validate ¶
func (c WorkerConfig) Validate() error
Validate verifies that the worker configuration is internally consistent.