fix(media): 视频任务 - 统一轮询超时并支持失败任务人工恢复
This commit is contained in:
1 parent
b763f62ec6
commit
96f99ea9d6
14 files changed
+510
-75
No files matched your search
@@ -159,10 +159,19 @@ func (r *Repository) APICallLogTasks(ids []string) ([]model.Task, error) {
|
||||
return []model.Task{}, nil
|
||||
}
|
||||
var tasks []model.Task
|
||||
err := r.db.Select("id", "user_id", "type", "result_json").Where("id IN ?", ids).Find(&tasks).Error
|
||||
err := r.db.Select("id", "user_id", "type", "status", "result_json").Where("id IN ?", ids).Find(&tasks).Error
|
||||
return tasks, err
|
||||
}
|
||||
|
||||
func (r *Repository) LatestProviderRequestIDForTask(taskID string) (string, error) {
|
||||
var log model.ApiCallLog
|
||||
err := r.db.Select("provider_request_id").
|
||||
Where("task_id = ? AND provider_request_id <> ''", taskID).
|
||||
Order("created_at desc").
|
||||
First(&log).Error
|
||||
return strings.TrimSpace(log.ProviderRequestID), err
|
||||
}
|
||||
|
||||
func visibleAPICallLogQuery(query *gorm.DB) *gorm.DB {
|
||||
// 视频轮询属于一次生成调用的内部阶段,管理端只展示聚合后的创建主记录。
|
||||
return query.Where("NOT (api_call_logs.capability = ? AND api_call_logs.request_kind IN ?)", "video", []string{"poll", "download"})
|
||||
|
||||
@@ -14,6 +14,8 @@ import (
|
||||
|
||||
var ErrDailyUploadLimitExceeded = errors.New("daily upload limit exceeded")
|
||||
|
||||
var ErrTaskProviderRecoveryConflict = errors.New("task provider recovery is already running")
|
||||
|
||||
type Repository struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
@@ -344,6 +346,36 @@ func (r *Repository) UpdateTaskProviderState(id string, providerRequestID string
|
||||
return r.db.Model(&model.Task{}).Where("id = ?", id).Updates(updates).Error
|
||||
}
|
||||
|
||||
// 人工恢复仅锁定失败任务;旧 worker 的租约可覆盖,但未过期的人工恢复租约不能并发抢占。
|
||||
func (r *Repository) ClaimFailedTaskProviderRecovery(id string, userID string, owner string, leaseDuration time.Duration) error {
|
||||
now := time.Now()
|
||||
query := r.db.Model(&model.Task{}).Where(
|
||||
"id = ? AND status = ? AND (lease_owner = '' OR lease_owner NOT LIKE ? OR lease_expires_at IS NULL OR lease_expires_at <= ?)",
|
||||
id, model.TaskStatusFailed, "manual-recovery:%", now,
|
||||
)
|
||||
if strings.TrimSpace(userID) != "" {
|
||||
query = query.Where("user_id = ?", userID)
|
||||
}
|
||||
result := query.Updates(map[string]any{
|
||||
"lease_owner": owner,
|
||||
"lease_expires_at": now.Add(leaseDuration),
|
||||
"updated_at": now,
|
||||
})
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
if result.RowsAffected != 1 {
|
||||
return ErrTaskProviderRecoveryConflict
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Repository) ReleaseTaskProviderRecovery(id string, owner string) error {
|
||||
return r.db.Model(&model.Task{}).
|
||||
Where("id = ? AND lease_owner = ?", id, owner).
|
||||
Updates(map[string]any{"lease_owner": "", "lease_expires_at": nil, "updated_at": time.Now()}).Error
|
||||
}
|
||||
|
||||
func (r *Repository) UpdateTaskProgress(id string, stage string, progress int) error {
|
||||
return r.db.Model(&model.Task{}).Where("id = ?", id).Updates(map[string]any{
|
||||
"stage": stage, "progress": progress, "updated_at": time.Now(),
|
||||
|
||||
Reference in new issue
Block a user