Documentation
¶
Overview ¶
Package store defines the persistence contract shared by the SQLite and Postgres backends. All methods take an explicit `now` where time matters so timing behavior is fully deterministic under a fake clock.
Index ¶
- Constants
- Variables
- func RunMigrations(ctx context.Context, db *sql.DB, dir fs.FS) error
- type Attempt
- type ClaimBudget
- type Event
- type EventKind
- type HTTPTarget
- type ListQueuesOpts
- type ListTasksOpts
- type NewTask
- type Outcome
- type Queue
- type QueuePatch
- type QueueSeed
- type QueueState
- type QueueStats
- type QueueUpsert
- type RateLimits
- type RetryConfig
- type RetryOverride
- type Store
- type Task
- type TaskResult
- type TaskState
- type UpsertOutcome
- type View
Constants ¶
const ( ErrKindTimeout = "timeout" ErrKindConnect = "connect" ErrKindDNS = "dns" ErrKindTLS = "tls" ErrKindNon2xx = "non_2xx" ErrKindLeaseLost = "lease_lost" ErrKindConfig = "config" )
Attempt error kinds.
Variables ¶
Functions ¶
Types ¶
type EventKind ¶
type EventKind int
Event kinds emitted by the store for dispatcher wakeup. Events are a latency optimization only — the dispatcher's periodic reconcile is the correctness backstop.
type HTTPTarget ¶
type HTTPTarget struct {
BaseURL string // resolves relative task paths; "" = tasks must use absolute URLs
Method string // "" = no override
HeaderOverrides map[string]string // merged over task headers; queue wins
SigningSecret string // Standard Webhooks secret ("whsec_..."); "" = unsigned
}
HTTPTarget is queue-level routing/override config applied at dispatch time.
type ListQueuesOpts ¶
type ListTasksOpts ¶
type Queue ¶
type Queue struct {
ID int64
Name string
State QueueState
RateLimits RateLimits
Retry RetryConfig
Target HTTPTarget
DeadLetterQueue string
PurgedAt *time.Time
ConfigVersion int64
CreatedAt time.Time
UpdatedAt time.Time
}
type QueuePatch ¶
type QueuePatch struct {
State *QueueState
MaxDispatchesPerSecond *float64
MaxBurstSize *int
MaxConcurrentDispatches *int
RetryMaxAttempts *int
RetryMaxRetryDuration *time.Duration
RetryMinBackoff *time.Duration
RetryMaxBackoff *time.Duration
RetryMaxDoublings *int
TargetBaseURL *string
TargetMethod *string
TargetHeaderOverrides *map[string]string
SigningSecret *string
DeadLetterQueue *string
}
QueuePatch applies only non-nil fields.
type QueueState ¶
type QueueState string
const ( QueueRunning QueueState = "running" QueuePaused QueueState = "paused" QueueDisabled QueueState = "disabled" )
type QueueStats ¶
type QueueUpsert ¶
type QueueUpsert struct {
Name string
RateLimits RateLimits
Retry RetryConfig
Target HTTPTarget
KeepSecret bool // true = leave stored signing secret untouched (secret omitted from request)
DeadLetterQueue string
}
QueueUpsert is the full desired configuration for PUT semantics. State is intentionally absent: upserts never flip running/paused/disabled, so a config upsert on every enqueue cannot accidentally resume a paused queue.
type RateLimits ¶
type RateLimits struct {
MaxDispatchesPerSecond float64
MaxBurstSize int // 0 = auto: clamp(ceil(rate), 1, 500)
MaxConcurrentDispatches int
}
RateLimits mirrors GCP Cloud Tasks queue rate limits.
func DefaultRateLimits ¶
func DefaultRateLimits() RateLimits
DefaultRateLimits / DefaultRetryConfig mirror GCP Cloud Tasks queue defaults.
func (RateLimits) EffectiveBurst ¶
func (r RateLimits) EffectiveBurst() int
EffectiveBurst resolves MaxBurstSize=0 (auto) the way GCP derives it.
type RetryConfig ¶
type RetryConfig struct {
MaxAttempts int // includes the first attempt; -1 = unlimited
MaxRetryDuration time.Duration // measured from the first attempt; 0 = unlimited
MinBackoff time.Duration
MaxBackoff time.Duration
MaxDoublings int
}
RetryConfig mirrors GCP Cloud Tasks retry semantics.
func DefaultRetryConfig ¶
func DefaultRetryConfig() RetryConfig
type RetryOverride ¶
type RetryOverride struct {
MaxAttempts *int `json:"max_attempts,omitempty"`
MaxRetryDuration *time.Duration `json:"max_retry_duration_ms,omitempty"`
MinBackoff *time.Duration `json:"min_backoff_ms,omitempty"`
MaxBackoff *time.Duration `json:"max_backoff_ms,omitempty"`
MaxDoublings *int `json:"max_doublings,omitempty"`
}
RetryOverride is a per-task partial override of the queue RetryConfig.
func (*RetryOverride) Merge ¶
func (o *RetryOverride) Merge(base RetryConfig) RetryConfig
Merge applies the override on top of a queue RetryConfig.
type Store ¶
type Store interface {
Migrate(ctx context.Context) error
Ping(ctx context.Context) error
Close() error
Dialect() string
// Events streams dispatcher wakeup hints (task ready, queue config
// changed, force-run). Best-effort: events may be dropped under load;
// the dispatcher reconcile loop is the correctness backstop.
Events() <-chan Event
// Queues
UpsertQueue(ctx context.Context, u QueueUpsert, now time.Time) (Queue, UpsertOutcome, error)
CreateQueue(ctx context.Context, u QueueUpsert, now time.Time) (Queue, error)
PatchQueue(ctx context.Context, name string, p QueuePatch, now time.Time) (Queue, error)
GetQueue(ctx context.Context, name string) (Queue, error)
GetQueuesByID(ctx context.Context, ids []int64) ([]Queue, error)
ListQueues(ctx context.Context, opts ListQueuesOpts) ([]Queue, string, error)
DeleteQueue(ctx context.Context, name string) error
// SetQueueState is used by pause/resume; disabled is set via PatchQueue.
SetQueueState(ctx context.Context, name string, state QueueState, now time.Time) (Queue, error)
PurgeQueue(ctx context.Context, name string, now time.Time) (Queue, error)
QueueStats(ctx context.Context, name, idPrefix string, now time.Time) (QueueStats, error)
// Tasks
CreateTask(ctx context.Context, t NewTask, now time.Time) (Task, error)
CreateTasks(ctx context.Context, ts []NewTask, now time.Time) ([]TaskResult, error)
GetTask(ctx context.Context, queue, taskID string, view View) (Task, error)
ListTasks(ctx context.Context, opts ListTasksOpts) ([]Task, string, error)
// DeleteTask tombstones the row (state=deleted) for the dedup window.
DeleteTask(ctx context.Context, queue, taskID string, now time.Time) error
// ForceRun moves a pending task's schedule_time to now and emits
// EventRunTask. The dispatcher dispatches it immediately, bypassing
// rate limits and PAUSED state (GCP parity).
ForceRun(ctx context.Context, queue, taskID string, now time.Time) (Task, error)
ListAttempts(ctx context.Context, queue, taskID string) ([]Attempt, error)
// Dispatcher
SeedDispatch(ctx context.Context) ([]QueueSeed, error)
// ClaimTasks atomically leases up to budget.N due pending tasks per
// queue, incrementing dispatch_count and stamping first_attempt_at.
ClaimTasks(ctx context.Context, now time.Time, leaseToken string, leaseGrace time.Duration, budgets []ClaimBudget) ([]Task, error)
// ClaimTaskForRun leases one specific task regardless of schedule_time
// or queue pause state (still refuses disabled queues).
ClaimTaskForRun(ctx context.Context, now time.Time, leaseToken string, leaseGrace time.Duration, taskPK int64) (Task, bool, error)
// NextPending returns the min schedule_time among pending tasks.
NextPending(ctx context.Context, queueID int64, now time.Time) (*time.Time, error)
// FinishAttempt records the attempt and applies the outcome, fenced on
// (taskPK, leaseToken, state=leased). Returns false when the fence
// fails (lease expired/stolen or task deleted/purged) — the result is
// then discarded.
FinishAttempt(ctx context.Context, now time.Time, taskPK int64, leaseToken string, att Attempt, outcome Outcome, nextSchedule time.Time) (bool, error)
ListExpiredLeases(ctx context.Context, now time.Time, limit int) ([]Task, error)
// CleanupTerminal hard-deletes terminal rows older than their TTL
// (floored by the dedup window). Returns rows deleted.
CleanupTerminal(ctx context.Context, now time.Time, succeededTTL, failedTTL, dedupWindow time.Duration, limit int) (int64, error)
// HardDeletePurged removes pending tasks superseded by a purge watermark.
HardDeletePurged(ctx context.Context, limit int) (int64, error)
}
type Task ¶
type Task struct {
PK int64
QueueID int64
Queue string // queue name (joined for convenience)
ID string
State TaskState
URL string // absolute URL or path starting with "/" (resolved at dispatch)
Method string
Headers map[string]string
Body []byte
DispatchDeadline time.Duration
RetryOverride *RetryOverride
ScheduleTime time.Time
CreatedAt time.Time
FirstAttemptAt *time.Time
FinishedAt *time.Time
DispatchCount int
ResponseCount int
LeaseToken string
LeaseExpiresAt *time.Time
LastAttemptAt *time.Time
LastStatus int // 0 = none
LastError string
}
type TaskResult ¶
type TaskState ¶
type TaskState string
const ( TaskPending TaskState = "pending" TaskLeased TaskState = "leased" TaskSucceeded TaskState = "succeeded" TaskFailed TaskState = "failed" // TaskDeleted rows are invisible through the API; they persist only as // dedup tombstones until retention cleanup removes them. TaskDeleted TaskState = "deleted" )
type UpsertOutcome ¶
type UpsertOutcome int
const ( UpsertCreated UpsertOutcome = iota UpsertUpdated UpsertNoop )
Directories
¶
| Path | Synopsis |
|---|---|
|
Package postgres implements store.Store on PostgreSQL via pgx.
|
Package postgres implements store.Store on PostgreSQL via pgx. |
|
Package sqlite implements store.Store on SQLite via the pure-Go modernc.org/sqlite driver.
|
Package sqlite implements store.Store on SQLite via the pure-Go modernc.org/sqlite driver. |
|
Package storetest is the conformance suite every store backend must pass.
|
Package storetest is the conformance suite every store backend must pass. |