Documentation
¶
Overview ¶
Package timertask 提供延迟任务队列的通用类型与本地(纯内存)后端。
模块边界 ¶
本包(module github.com/oekit/timertask)是**零 Redis 依赖**的:
- 本包 LocalBackend:基于内存的本地延迟任务(单实例场景), 依赖面只有标准库 + github.com/oekit/pkg(仅 local 子包的 cron 解析用);
- github.com/oekit/timertask/local:本地 cron 调度器(子包,同模块), 按 cron 表达式触发任务,同样零 Redis;
- github.com/oekit/timertask/redis:基于 Redis ZSet 的分布式延迟任务 (**独立 module**,需要显式引入才会拉进 go-redis)。
拆分动因:Go 按包编译,此前 Redis 后端与本地后端同处一个 package, 导致「import timertask」必然拉进 go-redis——纯 Go 嵌入式服务形态 (CGO_ENABLED=0 静态链接、SQLite 落盘、零外部中间件)根本用不了本库。 现在本地形态的依赖面里没有 redis。
迁移路径(破坏性变更) ¶
Redis 后端从本包迁出到独立 module github.com/oekit/timertask/redis:
import (
"github.com/oekit/timertask" // 通用类型 + LocalBackend
"github.com/oekit/timertask/redis" // RedisBackend(原 timertask.NewRedisBackend)
)
// 旧:b := timertask.NewRedisBackend("order", client, handler)
// 新:b := redis.NewRedisBackend("order", client, handler)
选项函数仍留在本包(timertask.WithWorkers(4) 等),写法不变; 本包的 NewLocalBackend / Task / Handler / TimerTask 接口用法完全不变。
消费语义 ¶
LocalBackend 为纯内存实现,进程退出即丢失所有未处理任务,不适合承载不可丢任务。
Redis 后端(github.com/oekit/timertask/redis)支持两种投递模式 (WithDeliveryMode / WithAtLeastOnce):
- DeliveryAtMostOnce(默认,与历史行为一致):消费流程先通过 Lua 脚本 原子删除 ZSet 中的任务条目,再推入本地 worker 队列处理。进程在删除后、 处理前崩溃,任务永久丢失。应用层需自行保证幂等性。
- DeliveryAtLeastOnce(可靠模式):claim 时把条目移入 processing 租约集 (score=租约到期),handler 成功后 Ack 删除;租约超时由回扫按 RetryCount 重投。kill -9 后未 Ack 任务会在 visibility timeout 后被重投(可容忍重复, 由调用方幂等)。
兜底路径:
- 优雅停机(ctx 取消)时,本地队列中尚未处理的任务会回灌 Redis, 重启后继续消费;
- 重试耗尽的任务会写入持久死信 ZSet({timertask.<buzType>}.dead, score 为失败时间戳,默认保留最近 10000 条);WithOnFailure 回调 只是死信之外的进程内通知手段,不构成持久化。
哪种任务选哪种模式:
- 提醒/审计/计费等不可丢事件 → DeliveryAtLeastOnce + 调用方幂等;
- 可丢弃的指标/通知/缓存预热 → DeliveryAtMostOnce(更省 Redis 往返)。
Index ¶
- type BackendConfig
- type DeliveryMode
- type Handler
- type LocalBackend
- type Task
- type TimerTask
- type TimerTaskOption
- func WithAtLeastOnce(visibilityTimeout time.Duration) TimerTaskOption
- func WithBuckets(n int) TimerTaskOption
- func WithDeliveryMode(m DeliveryMode) TimerTaskOption
- func WithOnFailure(fn func(task *Task, err error)) TimerTaskOption
- func WithRetry(count int, delay time.Duration) TimerTaskOption
- func WithVisibilityTimeout(d time.Duration) TimerTaskOption
- func WithWorkers(n int) TimerTaskOption
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BackendConfig ¶ added in v0.2.0
type BackendConfig struct {
// Workers worker 数量。
Workers int
// RetryCount 任务重试次数。
RetryCount int
// RetryDelay 任务重试间隔。
RetryDelay time.Duration
// Buckets 分片桶数(仅 Redis 后端有效,本地后端忽略)。
Buckets int
// OnFailure 任务最终失败回调(可为 nil)。
OnFailure func(*Task, error)
// Delivery 投递语义。
Delivery DeliveryMode
// VisibilityTimeout at-least-once 模式的租约时长。
VisibilityTimeout time.Duration
}
BackendConfig 是选项解析后的后端配置。
存在原因:TimerTaskOption 的底层类型 config 是未导出的,嵌套后端模块 (github.com/oekit/timertask/redis,独立 module)无法直接解析选项。 通过本结构把解析结果交给嵌套模块,下游调用方只需改 import 路径, 选项写法(timertask.WithWorkers(4) 等)保持不变。
func ResolveOptions ¶ added in v0.2.0
func ResolveOptions(opts ...TimerTaskOption) BackendConfig
ResolveOptions 解析选项并返回后端配置。
供嵌套后端模块使用;普通调用方用 NewLocalBackend 等构造函数即可, 无需直接调用本函数。
type DeliveryMode ¶ added in v0.1.5
type DeliveryMode int
DeliveryMode 是任务投递语义。
const ( // DeliveryAtMostOnce 默认:claim 时从 ZSet 原子删除后处理。 // 删除后、处理前崩溃 = 任务永久丢失(仅优雅停机回灌兜底)。 DeliveryAtMostOnce DeliveryMode = iota // DeliveryAtLeastOnce 可靠模式:claim 时移入 processing 租约集, // handler 成功后 Ack 删除;租约超时由回扫重投。可容忍重复,调用方幂等。 DeliveryAtLeastOnce )
type LocalBackend ¶
type LocalBackend struct {
// contains filtered or unexported fields
}
LocalBackend 是基于内存的本地延迟任务实现。 适用于单实例场景或开发测试环境。
func NewLocalBackend ¶
func NewLocalBackend(handler Handler, opts ...TimerTaskOption) *LocalBackend
NewLocalBackend 创建基于内存的本地延迟任务后端。
- handler: 任务处理函数
func (*LocalBackend) LocalPendingCount ¶
func (b *LocalBackend) LocalPendingCount() int
LocalPendingCount 返回本地队列中待处理任务数。
func (*LocalBackend) PendingCount ¶
func (b *LocalBackend) PendingCount(ctx context.Context) (int64, error)
PendingCount 返回队列中待处理任务数。
type Task ¶
type Task struct {
ID string `json:"task_id"` // 任务唯一 ID
CreateTime int64 `json:"create_time"` // 创建时间(Unix 秒)
EndTime int64 `json:"end_time"` // 执行时间(Unix 秒)
Action string `json:"action"` // 任务类型/动作名
Param string `json:"param"` // 业务参数(JSON 字符串)
Extra string `json:"extra"` // 扩展字段
RetryCount int `json:"retry_count"` // 已重试次数
MaxRetry int `json:"max_retry"` // 最大重试次数
}
Task 是一个延迟任务。
type TimerTask ¶
type TimerTask interface {
// Send 提交一个延迟任务。
// task.EndTime(Unix 秒)决定任务何时被执行。
Send(ctx context.Context, task *Task) error
// Start 启动任务消费(阻塞)。
// ctx 取消时所有 goroutine 退出。
Start(ctx context.Context) error
// PendingCount 返回队列中待处理任务数。
PendingCount(ctx context.Context) (int64, error)
// LocalPendingCount 返回本地队列中待处理任务数。
LocalPendingCount() int
}
TimerTask 是延迟任务队列接口。 支持多种后端实现:
- 本包 LocalBackend:基于内存的本地延迟任务(零第三方依赖,零 Redis)
- github.com/oekit/timertask/redis:基于 Redis ZSet 的分布式延迟任务
type TimerTaskOption ¶
type TimerTaskOption func(*config)
TimerTaskOption 配置延迟任务的可选参数(函数选项模式)。
func WithAtLeastOnce ¶ added in v0.1.5
func WithAtLeastOnce(visibilityTimeout time.Duration) TimerTaskOption
WithAtLeastOnce 开启可靠投递(等价 WithDeliveryMode(DeliveryAtLeastOnce)), visibilityTimeout 为 processing 租约时长(<=0 取默认 60s)。 claim 后任务进入租约集,成功 Ack 删除;超时未 Ack 由回扫按 RetryCount 重投。
func WithBuckets ¶
func WithBuckets(n int) TimerTaskOption
WithBuckets 设置任务桶数量(仅 Redis 后端 github.com/oekit/timertask/redis 有效),默认 128。
func WithDeliveryMode ¶ added in v0.1.5
func WithDeliveryMode(m DeliveryMode) TimerTaskOption
WithDeliveryMode 设置投递语义。默认 DeliveryAtMostOnce(与历史行为一致)。 DeliveryAtLeastOnce 时可用 WithVisibilityTimeout 调整租约时长。 仅 Redis 后端(github.com/oekit/timertask/redis)生效;LocalBackend 为纯内存, 无持久投递语义。
func WithOnFailure ¶
func WithOnFailure(fn func(task *Task, err error)) TimerTaskOption
WithOnFailure 设置任务最终失败回调。 当任务重试次数用完后调用,可用于告警、埋点等;注意这是进程内的同步回调, 不是持久死信——Redis 后端(github.com/oekit/timertask/redis)会自动把最终 失败的任务写入 Redis 死信 ZSet,LocalBackend 没有持久死信。 默认仅记录日志。
func WithRetry ¶
func WithRetry(count int, delay time.Duration) TimerTaskOption
WithRetry 设置任务重试次数和延迟,默认 3 次,5 秒延迟。
func WithVisibilityTimeout ¶ added in v0.1.5
func WithVisibilityTimeout(d time.Duration) TimerTaskOption
WithVisibilityTimeout 设置 at-least-once 模式的租约时长(<=0 取默认 60s)。