All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m20s
54 lines
1.7 KiB
Go
54 lines
1.7 KiB
Go
package asynctask
|
|
|
|
import (
|
|
stderrors "errors"
|
|
"time"
|
|
)
|
|
|
|
// LeaseState 是业务任务持久化层应保存的最小状态与租约事实。
|
|
type LeaseState struct {
|
|
Status int
|
|
LeaseOwner string
|
|
LeaseExpiresAt *time.Time
|
|
}
|
|
|
|
// ClaimResult 表示条件领取后的新事实。
|
|
type ClaimResult struct {
|
|
State LeaseState
|
|
Claimed bool
|
|
}
|
|
|
|
// Claim 按统一语义判断待处理或租约过期任务能否被领取。
|
|
//
|
|
// 业务持久化 Adapter 必须把同样的条件放进 PostgreSQL UPDATE 的 WHERE 中;
|
|
// 本函数用于跨业务共享状态判定,不能替代数据库条件更新。
|
|
func Claim(current LeaseState, owner string, now time.Time, leaseDuration time.Duration) (ClaimResult, error) {
|
|
if owner == "" || leaseDuration <= 0 {
|
|
return ClaimResult{}, stderrors.New("任务租约所有者和时长不能为空")
|
|
}
|
|
claimable := current.Status == StatusPending
|
|
if current.Status == StatusProcessing && current.LeaseExpiresAt != nil && !current.LeaseExpiresAt.After(now) {
|
|
claimable = true
|
|
}
|
|
if !claimable {
|
|
return ClaimResult{State: current}, nil
|
|
}
|
|
expiresAt := now.Add(leaseDuration)
|
|
return ClaimResult{
|
|
State: LeaseState{Status: StatusProcessing, LeaseOwner: owner, LeaseExpiresAt: &expiresAt},
|
|
Claimed: true,
|
|
}, nil
|
|
}
|
|
|
|
// CanFinish 判断当前租约所有者能否从处理中进入终态。
|
|
func CanFinish(current LeaseState, owner string, now time.Time) bool {
|
|
return current.Status == StatusProcessing &&
|
|
current.LeaseOwner == owner &&
|
|
current.LeaseExpiresAt != nil && current.LeaseExpiresAt.After(now)
|
|
}
|
|
|
|
// CanCancel 判断业务支持取消时是否可用预期状态条件更新。
|
|
func CanCancel(status int) bool {
|
|
return status == StatusPending || status == StatusProcessing
|
|
}
|