59eb34976a
iotlcm-admin-svr:管理后台服务。 - Go module:iotlcm → git.5iot.com/iotlcm-public/iotlcm-admin-svr(729 文件) - 凭据与地址脱敏:JWT signingKey(含代码里的 MustGet 默认值)、 MySQL DSN、Redis 口令、告警邮件发件人邮箱全部改为占位; 私网 IP → 文档地址段;库名 xiujie_admin → iotlcm - 真实手机号/邮箱 → 合法 11 位编造号 / example.com - 移除内部资产:CI 触发器、过时 DDL(sql/db_iotlcm.sql)、 私有依赖 go get 行、明文 registry 登录口令 - 启动 banner 统一 IOTLCM 方块字 + 社区惯例署名 - Dockerfile 改用公共基础镜像 - 拼错的 RADEME.md → README.md,README 重写 - 需要真实数据库的用例改为可用 IOTLCM_TEST_WITH_DB=1 显式启用 - 补 Apache-2.0 LICENSE,LF 行尾 + .gitattributes 数据库 schema 不随本仓发布(生产 DDL 已过时),README 已说明。
226 lines
6.2 KiB
Go
226 lines
6.2 KiB
Go
// Package worker
|
|
// @Link https://github.com/xiujiecn/xiu-admin
|
|
// @Copyright Copyright (c) 2025 LiXiujie
|
|
// @Author Lxj <li@xiujie.cn>
|
|
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
|
|
package worker
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/gogf/gf/v2/frame/g"
|
|
)
|
|
|
|
type Payload struct {
|
|
IsAggregate bool `json:"isAggregate"`
|
|
Group string `json:"group"`
|
|
Uid string `json:"uid"`
|
|
Payload []byte `json:"payload"`
|
|
}
|
|
|
|
type AggregatorOptions struct {
|
|
GroupGracePeriod int // 组的优雅延迟时间(秒)
|
|
GroupMaxDelay int // 组的最大延迟时间(秒)
|
|
GroupMaxSize int // 组的最大大小
|
|
}
|
|
|
|
type WorkerOptions struct {
|
|
group string //任务处理器的组名
|
|
redisAddr string //redis地址
|
|
redisUser string //redis用户名
|
|
redisPassword string //redis密码
|
|
redisDB int //redis数据库
|
|
handler func(ctx context.Context, p Payload) error //任务处理函数
|
|
maxRetry int //任务最大重试次数
|
|
clearArchived int //清除已归档任务的时间间隔
|
|
timeout int //任务超时时间
|
|
redisPeriodKey string //redis周期任务键
|
|
aggregator *AggregatorOptions //聚合器选项
|
|
}
|
|
|
|
func GetDefaultWorkerOptions(ops *WorkerOptions) *WorkerOptions {
|
|
if ops != nil {
|
|
return ops
|
|
}
|
|
addr := g.Cfg().MustGet(context.Background(), "queue.asynq.redis.address").String()
|
|
pass := g.Cfg().MustGet(context.Background(), "queue.asynq.redis.pass").String()
|
|
db := g.Cfg().MustGet(context.Background(), "queue.asynq.redis.db").Int()
|
|
user := g.Cfg().MustGet(context.Background(), "queue.asynq.redis.user").String()
|
|
if user == "" {
|
|
user = "default"
|
|
}
|
|
return &WorkerOptions{
|
|
group: "task",
|
|
redisAddr: addr,
|
|
redisPassword: pass,
|
|
redisDB: db,
|
|
redisUser: user,
|
|
}
|
|
}
|
|
|
|
func WithWorkerGroup(group string) func(*WorkerOptions) {
|
|
return func(o *WorkerOptions) {
|
|
GetDefaultWorkerOptions(o).group = group
|
|
}
|
|
}
|
|
|
|
func WithWorkerRedisAddr(addr string) func(*WorkerOptions) {
|
|
return func(o *WorkerOptions) {
|
|
GetDefaultWorkerOptions(o).redisAddr = addr
|
|
}
|
|
}
|
|
|
|
func WithWorkerRedisUser(user string) func(*WorkerOptions) {
|
|
return func(o *WorkerOptions) {
|
|
GetDefaultWorkerOptions(o).redisUser = user
|
|
}
|
|
}
|
|
|
|
func WithWorkerRedisPassword(pass string) func(*WorkerOptions) {
|
|
return func(o *WorkerOptions) {
|
|
GetDefaultWorkerOptions(o).redisPassword = pass
|
|
}
|
|
}
|
|
|
|
func WithWorkerRedisDB(db int) func(*WorkerOptions) {
|
|
return func(o *WorkerOptions) {
|
|
GetDefaultWorkerOptions(o).redisDB = db
|
|
}
|
|
}
|
|
|
|
func WithWorkerHandler(handler func(ctx context.Context, p Payload) error) func(*WorkerOptions) {
|
|
return func(o *WorkerOptions) {
|
|
GetDefaultWorkerOptions(o).handler = handler
|
|
}
|
|
}
|
|
|
|
func WithWorkerMaxRetry(maxRetry int) func(*WorkerOptions) {
|
|
return func(o *WorkerOptions) {
|
|
GetDefaultWorkerOptions(o).maxRetry = maxRetry
|
|
}
|
|
}
|
|
|
|
func WithWorkerClearArchived(clearArchived int) func(*WorkerOptions) {
|
|
return func(o *WorkerOptions) {
|
|
GetDefaultWorkerOptions(o).clearArchived = clearArchived
|
|
}
|
|
}
|
|
|
|
func WithWorkerTimeout(timeout int) func(*WorkerOptions) {
|
|
return func(o *WorkerOptions) {
|
|
GetDefaultWorkerOptions(o).timeout = timeout
|
|
}
|
|
}
|
|
|
|
func WithWorkerRedisPeriodKey(redisPeriodKey string) func(*WorkerOptions) {
|
|
return func(o *WorkerOptions) {
|
|
GetDefaultWorkerOptions(o).redisPeriodKey = redisPeriodKey
|
|
}
|
|
}
|
|
|
|
func WithWorkerAggregator(aggregator *AggregatorOptions) func(*WorkerOptions) {
|
|
return func(o *WorkerOptions) {
|
|
GetDefaultWorkerOptions(o).aggregator = aggregator
|
|
}
|
|
}
|
|
|
|
type TaskOptions struct {
|
|
uid string
|
|
group string
|
|
payload []byte
|
|
expr string // 仅周期任务
|
|
in *time.Duration // 仅一次性任务 当前时间的延迟
|
|
at *time.Time // 仅一次性任务 指定时间
|
|
now bool // 仅一次性任务 当前时间
|
|
retention int // 仅一次性任务 任务保留时间 在这个时间内任务会被保留为已完成状态,过了这个时间后,任务将被自动删除。
|
|
replace bool // 仅一次性任务 是否替换已存在的任务
|
|
ctx context.Context // 仅一次性任务
|
|
maxRetry int
|
|
timeout int
|
|
}
|
|
|
|
func GetDefaultTaskOptions(opt *TaskOptions) *TaskOptions {
|
|
if opt != nil {
|
|
return opt
|
|
}
|
|
return &TaskOptions{
|
|
group: "group",
|
|
maxRetry: 3,
|
|
timeout: 120,
|
|
}
|
|
}
|
|
|
|
func WithTaskUid(uid string) func(*TaskOptions) {
|
|
|
|
return func(o *TaskOptions) {
|
|
GetDefaultTaskOptions(o).uid = uid
|
|
}
|
|
}
|
|
|
|
func WithTaskGroup(group string) func(*TaskOptions) {
|
|
return func(o *TaskOptions) {
|
|
GetDefaultTaskOptions(o).group = group
|
|
}
|
|
}
|
|
|
|
func WithTaskPayload(payload []byte) func(*TaskOptions) {
|
|
return func(o *TaskOptions) {
|
|
GetDefaultTaskOptions(o).payload = payload
|
|
}
|
|
}
|
|
|
|
func WithTaskExpr(expr string) func(*TaskOptions) {
|
|
return func(o *TaskOptions) {
|
|
GetDefaultTaskOptions(o).expr = expr
|
|
}
|
|
}
|
|
|
|
func WithTaskIn(in *time.Duration) func(*TaskOptions) {
|
|
return func(o *TaskOptions) {
|
|
GetDefaultTaskOptions(o).in = in
|
|
}
|
|
}
|
|
|
|
func WithTaskAt(at *time.Time) func(*TaskOptions) {
|
|
return func(o *TaskOptions) {
|
|
GetDefaultTaskOptions(o).at = at
|
|
}
|
|
}
|
|
|
|
func WithTaskNow(now bool) func(*TaskOptions) {
|
|
return func(o *TaskOptions) {
|
|
GetDefaultTaskOptions(o).now = now
|
|
}
|
|
}
|
|
|
|
func WithTaskRetention(retention int) func(*TaskOptions) {
|
|
return func(o *TaskOptions) {
|
|
GetDefaultTaskOptions(o).retention = retention
|
|
}
|
|
}
|
|
|
|
func WithTaskReplace(replace bool) func(*TaskOptions) {
|
|
return func(o *TaskOptions) {
|
|
GetDefaultTaskOptions(o).replace = replace
|
|
}
|
|
}
|
|
|
|
func WithTaskCtx(ctx context.Context) func(*TaskOptions) {
|
|
return func(o *TaskOptions) {
|
|
GetDefaultTaskOptions(o).ctx = ctx
|
|
}
|
|
}
|
|
|
|
func WithTaskMaxRetry(maxRetry int) func(*TaskOptions) {
|
|
return func(o *TaskOptions) {
|
|
GetDefaultTaskOptions(o).maxRetry = maxRetry
|
|
}
|
|
}
|
|
|
|
func WithTaskTimeout(timeout int) func(*TaskOptions) {
|
|
return func(o *TaskOptions) {
|
|
GetDefaultTaskOptions(o).timeout = timeout
|
|
}
|
|
}
|