aliyunpan/internal/syncdrive/sync_task_mgr.go

236 lines
6.0 KiB
Go
Raw Normal View History

2022-05-24 19:56:06 +08:00
package syncdrive
import (
"encoding/json"
"fmt"
2022-06-14 21:05:40 +08:00
"github.com/tickstep/aliyunpan/internal/config"
2022-12-19 20:41:05 +08:00
"github.com/tickstep/aliyunpan/internal/log"
2022-05-24 19:56:06 +08:00
"github.com/tickstep/aliyunpan/internal/utils"
"github.com/tickstep/library-go/logger"
"io/ioutil"
"path"
"strings"
2022-06-09 19:58:16 +08:00
"time"
2022-05-24 19:56:06 +08:00
)
type (
2022-08-13 16:54:42 +08:00
// SyncOption 同步选项
SyncOption struct {
FileDownloadParallel int // 文件下载并发数
FileUploadParallel int // 文件上传并发数
FileDownloadBlockSize int64 // 文件下载分片大小
FileUploadBlockSize int64 // 文件上传分片大小
MaxDownloadRate int64 // 限制最大下载速度
MaxUploadRate int64 // 限制最大上传速度
// 优先级选项
SyncPriority SyncPriorityOption
// 本地文件修改检测间隔
LocalFileModifiedCheckIntervalSec int
2022-12-19 20:41:05 +08:00
// 文件记录器
FileRecorder *log.FileRecorder
2022-08-13 16:54:42 +08:00
}
2022-05-24 19:56:06 +08:00
// SyncTaskManager 同步任务管理器
SyncTaskManager struct {
2022-08-13 16:54:42 +08:00
syncDriveConfig *SyncDriveConfig
syncOption SyncOption
2022-06-14 21:05:40 +08:00
PanUser *config.PanUser
2024-03-03 10:12:44 +08:00
PanClient *config.PanClient
2022-05-24 19:56:06 +08:00
SyncConfigFolderPath string
2022-06-17 10:27:53 +08:00
// useConfigFile 是否使用配置文件启动
useConfigFile bool
2022-05-24 19:56:06 +08:00
}
// SyncDriveConfig 同步盘配置文件
SyncDriveConfig struct {
ConfigVer string `json:"configVer"`
SyncTaskList []*SyncTask `json:"syncTaskList"`
}
)
var (
ErrSyncTaskListEmpty error = fmt.Errorf("no sync task")
)
func NewSyncTaskManager(user *config.PanUser, panClient *config.PanClient, syncConfigFolderPath string,
2022-08-13 16:54:42 +08:00
option SyncOption) *SyncTaskManager {
2022-05-24 19:56:06 +08:00
return &SyncTaskManager{
2022-06-14 21:05:40 +08:00
PanUser: user,
2022-05-24 19:56:06 +08:00
PanClient: panClient,
SyncConfigFolderPath: syncConfigFolderPath,
2022-08-13 16:54:42 +08:00
syncOption: option,
2022-05-24 19:56:06 +08:00
}
}
func (m *SyncTaskManager) parseConfigFile() error {
/** 样例
{
"configVer": "1.0",
"syncTaskList": [
{
"name": "NS游戏备份",
"id": "5b2d7c10-e927-4e72-8f9d-5abb3bb04814",
"driveId": "19519111",
"localFolderPath": "D:\\smb\\datadisk\\game",
"panFolderPath": "/sync_drive/game",
"mode": "sync",
"driveName": "backup",
2022-05-24 19:56:06 +08:00
"lastSyncTime": ""
}
]
}
*/
2022-06-10 22:48:29 +08:00
configFilePath := m.ConfigFilePath()
2022-05-24 19:56:06 +08:00
r := &SyncDriveConfig{
ConfigVer: "1.0",
SyncTaskList: []*SyncTask{},
}
m.syncDriveConfig = r
if b, _ := utils.PathExists(configFilePath); b != true {
2022-06-09 19:58:16 +08:00
//text := utils.ObjectToJsonStr(r, true)
2022-06-16 22:30:12 +08:00
//ioutil.WriteFile(ConfigFilePath, []byte(text), 0755)
2022-06-10 22:48:29 +08:00
return fmt.Errorf("备份配置文件不存在:" + m.ConfigFilePath())
2022-05-24 19:56:06 +08:00
}
data, e := ioutil.ReadFile(configFilePath)
if e != nil {
return e
}
if len(data) > 0 {
if err2 := json.Unmarshal(data, m.syncDriveConfig); err2 != nil {
logger.Verboseln("parse sync drive config json error ", err2)
return err2
}
}
return nil
}
2022-06-10 22:48:29 +08:00
func (m *SyncTaskManager) ConfigFilePath() string {
2022-05-24 19:56:06 +08:00
return path.Join(m.SyncConfigFolderPath, "sync_drive_config.json")
}
// Start 启动同步进程
2024-04-21 11:32:49 +08:00
func (m *SyncTaskManager) Start(tasks []*SyncTask, cycleMode CycleMode) (bool, error) {
2022-06-17 10:27:53 +08:00
if tasks != nil && len(tasks) > 0 {
m.syncDriveConfig = &SyncDriveConfig{
ConfigVer: "1.0",
SyncTaskList: []*SyncTask{},
}
m.syncDriveConfig.SyncTaskList = tasks
m.useConfigFile = false
} else {
if er := m.parseConfigFile(); er != nil {
return false, er
}
m.useConfigFile = true
2022-05-24 19:56:06 +08:00
}
if m.syncDriveConfig.SyncTaskList == nil || len(m.syncDriveConfig.SyncTaskList) == 0 {
return false, ErrSyncTaskListEmpty
}
// start the sync task one by one
for _, task := range m.syncDriveConfig.SyncTaskList {
if len(task.Id) == 0 {
task.Id = utils.UuidStr()
}
2024-04-21 11:32:49 +08:00
// cycle mode
task.CycleModeType = cycleMode
// check driveId
if strings.ToLower(task.DriveName) == "backup" {
task.DriveId = m.PanUser.DriveList.GetFileDriveId()
} else if strings.ToLower(task.DriveName) == "resource" {
task.DriveId = m.PanUser.DriveList.GetResourceDriveId()
}
if len(task.DriveId) == 0 {
task.DriveId = m.PanUser.DriveList.GetFileDriveId()
}
2022-10-28 10:40:59 +08:00
// check userId
if len(task.UserId) > 0 {
if task.UserId != m.PanUser.UserId {
// not this user task, skip
logger.Verboseln("skip sync task: " + task.NameLabel())
continue
}
} else {
task.UserId = m.PanUser.UserId
}
// check pan path
if !utils.IsPanAbsPath(task.PanFolderPath) {
task.PanFolderPath = "/" + task.PanFolderPath
}
// check local path
if !utils.IsLocalAbsPath(task.LocalFolderPath) {
fmt.Println("任务启动失败,本地路径不是绝对路径: ", task.LocalFolderPath)
continue
}
2022-06-14 21:05:40 +08:00
task.panUser = m.PanUser
2022-05-24 19:56:06 +08:00
task.syncDbFolderPath = m.SyncConfigFolderPath
task.panClient = m.PanClient
2022-08-13 16:54:42 +08:00
task.syncOption = m.syncOption
2022-08-13 18:38:29 +08:00
if task.Priority != "" {
task.syncOption.SyncPriority = task.Priority
} else {
task.Priority = SyncPriorityTimestampFirst
task.syncOption.SyncPriority = SyncPriorityTimestampFirst
}
if task.Policy == "" {
task.Policy = SyncPolicyIncrement
}
task.LocalFolderPath = path.Clean(task.LocalFolderPath)
task.PanFolderPath = path.Clean(task.PanFolderPath)
2024-03-13 15:31:28 +08:00
if e := task.Start(); e != nil {
2022-05-24 19:56:06 +08:00
logger.Verboseln(e)
fmt.Printf("启动同步任务[%s]出错: %s\n", task.Id, e.Error())
2022-05-24 19:56:06 +08:00
continue
}
fmt.Println("\n启动同步任务")
fmt.Println(task)
2022-06-09 19:58:16 +08:00
time.Sleep(200 * time.Millisecond)
2022-05-24 19:56:06 +08:00
}
// save config file
2022-06-17 10:27:53 +08:00
if m.useConfigFile {
ioutil.WriteFile(m.ConfigFilePath(), []byte(utils.ObjectToJsonStr(m.syncDriveConfig, true)), 0755)
}
2022-05-24 19:56:06 +08:00
return true, nil
}
// Stop 停止同步进程
2024-03-13 15:31:28 +08:00
func (m *SyncTaskManager) Stop() (bool, error) {
2022-05-24 19:56:06 +08:00
// stop task one by one
for _, task := range m.syncDriveConfig.SyncTaskList {
var e error
2024-03-13 15:31:28 +08:00
e = task.Stop()
if e != nil {
2022-05-24 19:56:06 +08:00
logger.Verboseln(e)
2022-05-24 23:01:08 +08:00
fmt.Println("stop sync task error: ", task.NameLabel())
2022-05-24 19:56:06 +08:00
continue
}
fmt.Println("正在停止同步任务: ", task.NameLabel())
2022-05-24 19:56:06 +08:00
}
// save config file
2022-06-17 10:27:53 +08:00
if m.useConfigFile {
ioutil.WriteFile(m.ConfigFilePath(), []byte(utils.ObjectToJsonStr(m.syncDriveConfig, true)), 0755)
}
2022-05-24 19:56:06 +08:00
return true, nil
}
2024-04-21 11:32:49 +08:00
func (m *SyncTaskManager) IsAllTaskCompletely() bool {
for _, task := range m.syncDriveConfig.SyncTaskList {
if !task.IsTaskCompletely() {
return false
}
}
return true
}