scheduler

package
v1.9.9 Latest Latest
Warning

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

Go to latest
Published: Jun 24, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Index

Constants

View Source
const SemaphoreKey = "semaphore"

SemaphoreKey is the key used in scheduler_meta for the semaphore state.

View Source
const SemaphoreValueGreen = "green"

SemaphoreValueGreen is the stored value for a green semaphore.

View Source
const SemaphoreValueRed = "red"

SemaphoreValueRed is the stored value for a red semaphore.

Variables

This section is empty.

Functions

This section is empty.

Types

type HandlerFunc

type HandlerFunc func(ctx context.Context, item *QueueItem) error

HandlerFunc processes a single queue item. Return a non-nil error to mark the item as processed with error status.

type PersistedSemaphore

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

PersistedSemaphore implements Semaphore and persists every state change to the database via the Store, so the state survives application restarts.

func NewPersistedSemaphore

func NewPersistedSemaphore(store *Store, startGreen bool) *PersistedSemaphore

NewPersistedSemaphore creates a PersistedSemaphore with an initial state.

func (*PersistedSemaphore) IsGreen

func (ps *PersistedSemaphore) IsGreen() bool

IsGreen reports whether execution is currently allowed.

func (*PersistedSemaphore) SetGreen

func (ps *PersistedSemaphore) SetGreen()

SetGreen allows task execution and persists the state.

func (*PersistedSemaphore) SetRed

func (ps *PersistedSemaphore) SetRed()

SetRed blocks task execution and persists the state.

type ProcessedItem

type ProcessedItem struct {
	ID          uint            `gorm:"primaryKey;autoIncrement"`
	QueueItemID uint            `gorm:"not null;index"` // FK → queue_items.id (soft ref)
	TaskType    string          `gorm:"not null;index"`
	Payload     string          `gorm:"type:text"`
	Status      ProcessedStatus `gorm:"not null;index"`
	ErrorMsg    string          `gorm:"type:text"` // empty when Status == "ok"
	StartedAt   time.Time       `gorm:"not null"`
	FinishedAt  time.Time       `gorm:"not null"`
	DurationMs  int64           `gorm:"not null"` // FinishedAt - StartedAt in ms
	CreatedAt   time.Time
}

ProcessedItem is an immutable record of a completed execution. Rows are never updated — only inserted.

func (ProcessedItem) TableName

func (ProcessedItem) TableName() string

TableName overrides the GORM default.

type ProcessedStatus

type ProcessedStatus string

ProcessedStatus is the final outcome recorded in processed_items.

const (
	ProcessedOK    ProcessedStatus = "ok"
	ProcessedError ProcessedStatus = "error"
)

type QueueItem

type QueueItem struct {
	ID        uint        `gorm:"primaryKey;autoIncrement"`
	TaskType  string      `gorm:"not null;index"` // e.g. "send_email", "sync_records"
	Payload   string      `gorm:"type:text"`      // JSON or plain string, interpreted by the handler
	Status    QueueStatus `gorm:"not null;default:'pending';index"`
	Priority  int         `gorm:"not null;default:0;index"` // higher = runs first within a tick
	MaxRuns   int         `gorm:"not null;default:1"`       // 1 = run once, -1 = repeat indefinitely, N = run N times
	Thread    int         `gorm:"not null;default:0"`       // 0 = sequential, 1 = concurrent per type
	CreatedAt time.Time
	UpdatedAt time.Time
}

QueueItem is a task waiting to be executed. Any external program can insert a row into this table to enqueue work.

INSERT INTO queue_items (task_type, payload, priority, max_runs, thread) VALUES (?, ?, ?, ?, ?);

func (QueueItem) TableName

func (QueueItem) TableName() string

TableName overrides the GORM default.

type QueueStatus

type QueueStatus string

QueueStatus represents the lifecycle state of a queued item.

const (
	StatusPending    QueueStatus = "pending"
	StatusProcessing QueueStatus = "processing" // claimed by a scheduler tick
)

type Registry

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

Registry maps task types to their handlers. Register all handlers before calling Scheduler.Start.

func NewRegistry

func NewRegistry() *Registry

NewRegistry creates an empty handler registry.

func (*Registry) Register

func (r *Registry) Register(taskType string, h HandlerFunc)

Register associates a task type with a handler. Panics on duplicate registration to catch misconfiguration at startup.

type Scheduler

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

Scheduler polls the database every interval and executes pending tasks.

func NewScheduler

func NewScheduler(cfg SchedulerConfig, sem Semaphore, st *Store, reg *Registry) *Scheduler

NewScheduler creates a Scheduler.

func (*Scheduler) Start

func (s *Scheduler) Start(ctx context.Context)

Start launches the scheduler goroutine.

func (*Scheduler) Stop

func (s *Scheduler) Stop()

Stop signals the scheduler and waits for it to exit cleanly.

type SchedulerConfig

type SchedulerConfig struct {
	Interval  time.Duration
	RateLimit int // 0 = unlimited
}

SchedulerConfig holds constructor options.

type SchedulerMeta

type SchedulerMeta struct {
	Key   string `gorm:"primaryKey;size:64"`
	Value string `gorm:"size:16;not null"`
}

SchedulerMeta stores key-value metadata for the scheduler, such as the semaphore state. This table persists across restarts so the scheduler can recover its previous state.

func (SchedulerMeta) TableName

func (SchedulerMeta) TableName() string

TableName overrides the GORM default.

type Semaphore

type Semaphore interface {
	SetGreen()
	SetRed()
	IsGreen() bool
}

Semaphore is the interface for the scheduler kill switch. Green (true) means tasks can run; Red (false) means tasks are blocked.

func NewSemaphore

func NewSemaphore(startGreen bool) Semaphore

NewSemaphore creates a Semaphore. Pass true to start green, false to start red.

type Store

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

Store handles all database operations for the scheduler.

func NewStore

func NewStore(db *gorm.DB) (*Store, error)

NewStore creates a Store. Tables (queue_items, processed_items)

func (*Store) ClaimBatch

func (s *Store) ClaimBatch(ctx context.Context, limit int) ([]*QueueItem, error)

ClaimBatch atomically claims up to `limit` pending tasks and marks them as "processing" so that concurrent scheduler instances never double-execute.

func (*Store) DB

func (s *Store) DB() *gorm.DB

DB returns the underlying *gorm.DB used by the store.

func (*Store) Enqueue

func (s *Store) Enqueue(ctx context.Context, taskType, payload string, priority, maxRuns, thread int) (*QueueItem, error)

Enqueue inserts a new pending task. maxRuns controls how many times the task executes: 1 = once (default), -1 = repeat indefinitely. thread controls concurrency: 0 = sequential per type, 1 = concurrent per type. Any value of maxRuns < -1 is clamped to 1.

func (*Store) GetSemaphore

func (s *Store) GetSemaphore(ctx context.Context) bool

GetSemaphore reads the persisted semaphore state from the database. Returns true if green, false if red or not found.

func (*Store) PendingCount

func (s *Store) PendingCount(ctx context.Context) (int64, error)

PendingCount returns the number of tasks currently in pending or processing state.

func (*Store) RecentProcessed

func (s *Store) RecentProcessed(ctx context.Context, n int) ([]*ProcessedItem, error)

RecentProcessed returns the last `n` processed items ordered by newest first.

func (*Store) RecordResult

func (s *Store) RecordResult(ctx context.Context, item *QueueItem, startedAt time.Time, execErr error) error

RecordResult writes a ProcessedItem, then either deletes the QueueItem (if MaxRuns is exhausted) or decrements MaxRuns and resets the status to pending for re-execution on the next tick. A maxRuns of -1 means repeat indefinitely.

func (*Store) RecoverStuck

func (s *Store) RecoverStuck(ctx context.Context) (int64, error)

RecoverStuck resets any items stuck in "processing" state (e.g. after a crash) back to "pending" so they can be re-claimed on the next tick. Call this once at startup.

func (*Store) SetSemaphore

func (s *Store) SetSemaphore(ctx context.Context, green bool) error

SetSemaphore persists the semaphore state to the database.

Jump to

Keyboard shortcuts

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