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 }