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 }