github.com/cloudreve/Cloudreve/v3@v3.0.0-20240224133659-3edb00a6484c/pkg/task/job.go (about)

     1  package task
     2  
     3  import (
     4  	model "github.com/cloudreve/Cloudreve/v3/models"
     5  	"github.com/cloudreve/Cloudreve/v3/pkg/util"
     6  )
     7  
     8  // 任务类型
     9  const (
    10  	// CompressTaskType 压缩任务
    11  	CompressTaskType = iota
    12  	// DecompressTaskType 解压缩任务
    13  	DecompressTaskType
    14  	// TransferTaskType 中转任务
    15  	TransferTaskType
    16  	// ImportTaskType 导入任务
    17  	ImportTaskType
    18  	// RecycleTaskType 回收任务
    19  	RecycleTaskType
    20  )
    21  
    22  // 任务状态
    23  const (
    24  	// Queued 排队中
    25  	Queued = iota
    26  	// Processing 处理中
    27  	Processing
    28  	// Error 失败
    29  	Error
    30  	// Canceled 取消
    31  	Canceled
    32  	// Complete 完成
    33  	Complete
    34  )
    35  
    36  // 任务进度
    37  const (
    38  	// PendingProgress 等待中
    39  	PendingProgress = iota
    40  	// Compressing 压缩中
    41  	CompressingProgress
    42  	// Decompressing 解压缩中
    43  	DecompressingProgress
    44  	// Downloading 下载中
    45  	DownloadingProgress
    46  	// Transferring 转存中
    47  	TransferringProgress
    48  	// ListingProgress 索引中
    49  	ListingProgress
    50  	// InsertingProgress 插入中
    51  	InsertingProgress
    52  )
    53  
    54  // Job 任务接口
    55  type Job interface {
    56  	Type() int           // 返回任务类型
    57  	Creator() uint       // 返回创建者ID
    58  	Props() string       // 返回序列化后的任务属性
    59  	Model() *model.Task  // 返回对应的数据库模型
    60  	SetStatus(int)       // 设定任务状态
    61  	Do()                 // 开始执行任务
    62  	SetError(*JobError)  // 设定任务失败信息
    63  	GetError() *JobError // 获取任务执行结果,返回nil表示成功完成执行
    64  }
    65  
    66  // JobError 任务失败信息
    67  type JobError struct {
    68  	Msg   string `json:"msg,omitempty"`
    69  	Error string `json:"error,omitempty"`
    70  }
    71  
    72  // Record 将任务记录到数据库中
    73  func Record(job Job) (*model.Task, error) {
    74  	record := model.Task{
    75  		Status:   Queued,
    76  		Type:     job.Type(),
    77  		UserID:   job.Creator(),
    78  		Progress: 0,
    79  		Error:    "",
    80  		Props:    job.Props(),
    81  	}
    82  	_, err := record.Create()
    83  	return &record, err
    84  }
    85  
    86  // Resume 从数据库中恢复未完成任务
    87  func Resume(p Pool) {
    88  	tasks := model.GetTasksByStatus(Queued, Processing)
    89  	if len(tasks) == 0 {
    90  		return
    91  	}
    92  	util.Log().Info("Resume %d unfinished task(s) from database.", len(tasks))
    93  
    94  	for i := 0; i < len(tasks); i++ {
    95  		job, err := GetJobFromModel(&tasks[i])
    96  		if err != nil {
    97  			util.Log().Warning("Failed to resume task: %s", err)
    98  			continue
    99  		}
   100  
   101  		if job != nil {
   102  			p.Submit(job)
   103  		}
   104  	}
   105  }
   106  
   107  // GetJobFromModel 从数据库给定模型获取任务
   108  func GetJobFromModel(task *model.Task) (Job, error) {
   109  	switch task.Type {
   110  	case CompressTaskType:
   111  		return NewCompressTaskFromModel(task)
   112  	case DecompressTaskType:
   113  		return NewDecompressTaskFromModel(task)
   114  	case TransferTaskType:
   115  		return NewTransferTaskFromModel(task)
   116  	case ImportTaskType:
   117  		return NewImportTaskFromModel(task)
   118  	case RecycleTaskType:
   119  		return NewRecycleTaskFromModel(task)
   120  	default:
   121  		return nil, ErrUnknownTaskType
   122  	}
   123  }