mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-30 06:16:37 +08:00
132 lines
4.5 KiB
Go
132 lines
4.5 KiB
Go
// Copyright 2025 linux.do
|
|
// Copyright 2026 Arctel.net
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package model
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/Rain-kl/Wavelet/internal/db"
|
|
"github.com/Rain-kl/Wavelet/internal/db/idgen"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// TaskExecutionStatus 任务执行状态
|
|
type TaskExecutionStatus string
|
|
|
|
// 任务执行状态
|
|
const (
|
|
TaskExecutionStatusPending TaskExecutionStatus = "pending"
|
|
TaskExecutionStatusRunning TaskExecutionStatus = "running"
|
|
TaskExecutionStatusSucceeded TaskExecutionStatus = "succeeded"
|
|
TaskExecutionStatusFailed TaskExecutionStatus = "failed"
|
|
)
|
|
|
|
// TaskExecution 任务执行记录
|
|
type TaskExecution struct {
|
|
ID uint64 `json:"id,string" gorm:"primaryKey"`
|
|
TaskID string `json:"task_id" gorm:"size:128;uniqueIndex;not null"`
|
|
TaskType string `json:"task_type" gorm:"size:64;index;not null"`
|
|
TaskName string `json:"task_name" gorm:"size:128"`
|
|
Status TaskExecutionStatus `json:"status" gorm:"size:32;index;not null"`
|
|
Retryable bool `json:"retryable" gorm:"not null;default:false"`
|
|
MaxRetry int `json:"max_retry" gorm:"not null;default:0"`
|
|
RetryCount int `json:"retry_count" gorm:"not null;default:0"`
|
|
Log string `json:"log" gorm:"type:text"`
|
|
ErrorMessage string `json:"error_message" gorm:"type:text"`
|
|
Result string `json:"result" gorm:"type:text"`
|
|
StartedAt *time.Time `json:"started_at" gorm:"index"`
|
|
FinishedAt *time.Time `json:"finished_at"`
|
|
Duration int64 `json:"duration" gorm:"comment:耗时毫秒"`
|
|
Payload string `json:"payload" gorm:"type:text"`
|
|
TriggeredBy string `json:"triggered_by" gorm:"size:32;not null;default:system"`
|
|
CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime;index"`
|
|
UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime"`
|
|
}
|
|
|
|
// TableName 表名
|
|
func (TaskExecution) TableName() string {
|
|
return "w_task_executions"
|
|
}
|
|
|
|
// CreateTaskExecution 创建任务执行记录
|
|
func CreateTaskExecution(ctx context.Context, execution *TaskExecution) error {
|
|
execution.ID = idgen.NextUint64ID()
|
|
return db.DB(ctx).Create(execution).Error
|
|
}
|
|
|
|
// UpdateTaskExecution 更新任务执行记录,忽略 log 字段以防覆写正在追加的日志
|
|
func UpdateTaskExecution(ctx context.Context, execution *TaskExecution) error {
|
|
return db.DB(ctx).Omit("log").Save(execution).Error
|
|
}
|
|
|
|
// GetTaskExecutionByTaskID 根据 TaskID 获取执行记录
|
|
func GetTaskExecutionByTaskID(ctx context.Context, taskID string) (*TaskExecution, error) {
|
|
var execution TaskExecution
|
|
if err := db.DB(ctx).Where("task_id = ?", taskID).First(&execution).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return &execution, nil
|
|
}
|
|
|
|
// GetTaskExecutionByID 根据 ID 获取执行记录
|
|
func GetTaskExecutionByID(ctx context.Context, id uint64) (*TaskExecution, error) {
|
|
var execution TaskExecution
|
|
if err := db.DB(ctx).Where("id = ?", id).First(&execution).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return &execution, nil
|
|
}
|
|
|
|
// AppendTaskExecutionLog 追加日志到执行记录
|
|
func AppendTaskExecutionLog(ctx context.Context, taskID string, logLine string) error {
|
|
now := time.Now().Format("15:04:05")
|
|
line := fmt.Sprintf("[%s] %s\n", now, logLine)
|
|
return db.DB(ctx).Model(&TaskExecution{}).
|
|
Where("task_id = ?", taskID).
|
|
Update("log", gorm.Expr("COALESCE(log, '') || ?", line)).Error
|
|
}
|
|
|
|
// ListTaskExecutionsRequest 查询任务执行记录列表请求
|
|
type ListTaskExecutionsRequest struct {
|
|
Status string `form:"status"`
|
|
TaskType string `form:"task_type"`
|
|
Page int `form:"page"`
|
|
PageSize int `form:"page_size"`
|
|
}
|
|
|
|
// ListTaskExecutions 分页查询任务执行记录
|
|
func ListTaskExecutions(ctx context.Context, req ListTaskExecutionsRequest) ([]TaskExecution, int64, error) {
|
|
if req.Page <= 0 {
|
|
req.Page = 1
|
|
}
|
|
if req.PageSize <= 0 {
|
|
req.PageSize = 20
|
|
}
|
|
|
|
query := db.DB(ctx).Model(&TaskExecution{})
|
|
|
|
if req.Status != "" {
|
|
query = query.Where("status = ?", req.Status)
|
|
}
|
|
if req.TaskType != "" {
|
|
query = query.Where("task_type = ?", req.TaskType)
|
|
}
|
|
|
|
var total int64
|
|
if err := query.Count(&total).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
var executions []TaskExecution
|
|
offset := (req.Page - 1) * req.PageSize
|
|
if err := query.Order("id DESC").Offset(offset).Limit(req.PageSize).Find(&executions).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
return executions, total, nil
|
|
}
|