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

     1  package slavetask
     2  
     3  import (
     4  	"context"
     5  	"os"
     6  
     7  	model "github.com/cloudreve/Cloudreve/v3/models"
     8  	"github.com/cloudreve/Cloudreve/v3/pkg/cluster"
     9  	"github.com/cloudreve/Cloudreve/v3/pkg/filesystem"
    10  	"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/fsctx"
    11  	"github.com/cloudreve/Cloudreve/v3/pkg/mq"
    12  	"github.com/cloudreve/Cloudreve/v3/pkg/serializer"
    13  	"github.com/cloudreve/Cloudreve/v3/pkg/task"
    14  	"github.com/cloudreve/Cloudreve/v3/pkg/util"
    15  )
    16  
    17  // TransferTask 文件中转任务
    18  type TransferTask struct {
    19  	Err      *task.JobError
    20  	Req      *serializer.SlaveTransferReq
    21  	MasterID string
    22  }
    23  
    24  // Props 获取任务属性
    25  func (job *TransferTask) Props() string {
    26  	return ""
    27  }
    28  
    29  // Type 获取任务类型
    30  func (job *TransferTask) Type() int {
    31  	return 0
    32  }
    33  
    34  // Creator 获取创建者ID
    35  func (job *TransferTask) Creator() uint {
    36  	return 0
    37  }
    38  
    39  // Model 获取任务的数据库模型
    40  func (job *TransferTask) Model() *model.Task {
    41  	return nil
    42  }
    43  
    44  // SetStatus 设定状态
    45  func (job *TransferTask) SetStatus(status int) {
    46  }
    47  
    48  // SetError 设定任务失败信息
    49  func (job *TransferTask) SetError(err *task.JobError) {
    50  	job.Err = err
    51  
    52  }
    53  
    54  // SetErrorMsg 设定任务失败信息
    55  func (job *TransferTask) SetErrorMsg(msg string, err error) {
    56  	jobErr := &task.JobError{Msg: msg}
    57  	if err != nil {
    58  		jobErr.Error = err.Error()
    59  	}
    60  
    61  	job.SetError(jobErr)
    62  
    63  	notifyMsg := mq.Message{
    64  		TriggeredBy: job.MasterID,
    65  		Event:       serializer.SlaveTransferFailed,
    66  		Content: serializer.SlaveTransferResult{
    67  			Error: err.Error(),
    68  		},
    69  	}
    70  
    71  	if err := cluster.DefaultController.SendNotification(job.MasterID, job.Req.Hash(job.MasterID), notifyMsg); err != nil {
    72  		util.Log().Warning("Failed to send transfer failure notification to master node: %s", err)
    73  	}
    74  }
    75  
    76  // GetError 返回任务失败信息
    77  func (job *TransferTask) GetError() *task.JobError {
    78  	return job.Err
    79  }
    80  
    81  // Do 开始执行任务
    82  func (job *TransferTask) Do() {
    83  	fs, err := filesystem.NewAnonymousFileSystem()
    84  	if err != nil {
    85  		job.SetErrorMsg("Failed to initialize anonymous filesystem.", err)
    86  		return
    87  	}
    88  
    89  	fs.Policy = job.Req.Policy
    90  	if err := fs.DispatchHandler(); err != nil {
    91  		job.SetErrorMsg("Failed to dispatch policy.", err)
    92  		return
    93  	}
    94  
    95  	master, err := cluster.DefaultController.GetMasterInfo(job.MasterID)
    96  	if err != nil {
    97  		job.SetErrorMsg("Cannot found master node ID.", err)
    98  		return
    99  	}
   100  
   101  	fs.SwitchToShadowHandler(master.Instance, master.URL.String(), master.ID)
   102  	file, err := os.Open(util.RelativePath(job.Req.Src))
   103  	if err != nil {
   104  		job.SetErrorMsg("Failed to read source file.", err)
   105  		return
   106  	}
   107  
   108  	defer file.Close()
   109  
   110  	// 获取源文件大小
   111  	fi, err := file.Stat()
   112  	if err != nil {
   113  		job.SetErrorMsg("Failed to get source file size.", err)
   114  		return
   115  	}
   116  
   117  	size := fi.Size()
   118  
   119  	err = fs.Handler.Put(context.Background(), &fsctx.FileStream{
   120  		File:     file,
   121  		SavePath: job.Req.Dst,
   122  		Size:     uint64(size),
   123  	})
   124  	if err != nil {
   125  		job.SetErrorMsg("Upload failed.", err)
   126  		return
   127  	}
   128  
   129  	msg := mq.Message{
   130  		TriggeredBy: job.MasterID,
   131  		Event:       serializer.SlaveTransferSuccess,
   132  		Content:     serializer.SlaveTransferResult{},
   133  	}
   134  
   135  	if err := cluster.DefaultController.SendNotification(job.MasterID, job.Req.Hash(job.MasterID), msg); err != nil {
   136  		util.Log().Warning("Failed to send transfer success notification to master node: %s", err)
   137  	}
   138  }