fix(189pc): transfer rename (#7958)
* fix(189pc): transfer rename * fix: OverwriteUpload * fix: change search method * fix * fix
This commit is contained in:
parent
36b4204623
commit
399336b33c
@ -1,8 +1,8 @@
|
|||||||
package _189pc
|
package _189pc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"container/ring"
|
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -14,6 +14,7 @@ import (
|
|||||||
"github.com/alist-org/alist/v3/internal/model"
|
"github.com/alist-org/alist/v3/internal/model"
|
||||||
"github.com/alist-org/alist/v3/pkg/utils"
|
"github.com/alist-org/alist/v3/pkg/utils"
|
||||||
"github.com/go-resty/resty/v2"
|
"github.com/go-resty/resty/v2"
|
||||||
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Cloud189PC struct {
|
type Cloud189PC struct {
|
||||||
@ -29,7 +30,7 @@ type Cloud189PC struct {
|
|||||||
|
|
||||||
uploadThread int
|
uploadThread int
|
||||||
|
|
||||||
familyTransferFolder *ring.Ring
|
familyTransferFolder *Cloud189Folder
|
||||||
cleanFamilyTransferFile func()
|
cleanFamilyTransferFile func()
|
||||||
|
|
||||||
storageConfig driver.Config
|
storageConfig driver.Config
|
||||||
@ -48,9 +49,18 @@ func (y *Cloud189PC) GetAddition() driver.Additional {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (y *Cloud189PC) Init(ctx context.Context) (err error) {
|
func (y *Cloud189PC) Init(ctx context.Context) (err error) {
|
||||||
// 兼容旧上传接口
|
y.storageConfig = config
|
||||||
y.storageConfig.NoOverwriteUpload = y.isFamily() && (y.Addition.RapidUpload || y.Addition.UploadMethod == "old")
|
if y.isFamily() {
|
||||||
|
// 兼容旧上传接口
|
||||||
|
if y.Addition.RapidUpload || y.Addition.UploadMethod == "old" {
|
||||||
|
y.storageConfig.NoOverwriteUpload = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 家庭云转存,不支持覆盖上传
|
||||||
|
if y.Addition.FamilyTransfer {
|
||||||
|
y.storageConfig.NoOverwriteUpload = true
|
||||||
|
}
|
||||||
|
}
|
||||||
// 处理个人云和家庭云参数
|
// 处理个人云和家庭云参数
|
||||||
if y.isFamily() && y.RootFolderID == "-11" {
|
if y.isFamily() && y.RootFolderID == "-11" {
|
||||||
y.RootFolderID = ""
|
y.RootFolderID = ""
|
||||||
@ -91,13 +101,14 @@ func (y *Cloud189PC) Init(ctx context.Context) (err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建中转文件夹,防止重名文件
|
// 创建中转文件夹
|
||||||
if y.FamilyTransfer {
|
if y.FamilyTransfer {
|
||||||
if y.familyTransferFolder, err = y.createFamilyTransferFolder(32); err != nil {
|
if err := y.createFamilyTransferFolder(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 清理转存文件节流
|
||||||
y.cleanFamilyTransferFile = utils.NewThrottle2(time.Minute, func() {
|
y.cleanFamilyTransferFile = utils.NewThrottle2(time.Minute, func() {
|
||||||
if err := y.cleanFamilyTransfer(context.TODO()); err != nil {
|
if err := y.cleanFamilyTransfer(context.TODO()); err != nil {
|
||||||
utils.Log.Errorf("cleanFamilyTransferFolderError:%s", err)
|
utils.Log.Errorf("cleanFamilyTransferFolderError:%s", err)
|
||||||
@ -327,35 +338,49 @@ func (y *Cloud189PC) Put(ctx context.Context, dstDir model.Obj, stream model.Fil
|
|||||||
if !isFamily && y.FamilyTransfer {
|
if !isFamily && y.FamilyTransfer {
|
||||||
// 修改上传目标为家庭云文件夹
|
// 修改上传目标为家庭云文件夹
|
||||||
transferDstDir := dstDir
|
transferDstDir := dstDir
|
||||||
dstDir = (y.familyTransferFolder.Value).(*Cloud189Folder)
|
dstDir = y.familyTransferFolder
|
||||||
y.familyTransferFolder = y.familyTransferFolder.Next()
|
|
||||||
|
|
||||||
|
// 使用临时文件名
|
||||||
|
srcName := stream.GetName()
|
||||||
|
stream = &WrapFileStreamer{
|
||||||
|
FileStreamer: stream,
|
||||||
|
Name: fmt.Sprintf("0%s.transfer", uuid.NewString()),
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用家庭云上传
|
||||||
isFamily = true
|
isFamily = true
|
||||||
overwrite = false
|
overwrite = false
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if newObj != nil {
|
if newObj != nil {
|
||||||
// 批量任务有概率删不掉
|
|
||||||
y.cleanFamilyTransferFile()
|
|
||||||
|
|
||||||
// 转存家庭云文件到个人云
|
// 转存家庭云文件到个人云
|
||||||
err = y.SaveFamilyFileToPersonCloud(context.TODO(), y.FamilyID, newObj, transferDstDir, true)
|
err = y.SaveFamilyFileToPersonCloud(context.TODO(), y.FamilyID, newObj, transferDstDir, true)
|
||||||
|
// 删除家庭云源文件
|
||||||
task := BatchTaskInfo{
|
go y.Delete(context.TODO(), y.FamilyID, newObj)
|
||||||
FileId: newObj.GetID(),
|
// 批量任务有概率删不掉
|
||||||
FileName: newObj.GetName(),
|
go y.cleanFamilyTransferFile()
|
||||||
IsFolder: BoolToNumber(newObj.IsDir()),
|
// 转存失败返回错误
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除源文件
|
// 查找转存文件
|
||||||
if resp, err := y.CreateBatchTask("DELETE", y.FamilyID, "", nil, task); err == nil {
|
var file *Cloud189File
|
||||||
y.WaitBatchTask("DELETE", resp.TaskID, time.Second)
|
file, err = y.findFileByName(context.TODO(), newObj.GetName(), transferDstDir.GetID(), false)
|
||||||
// 永久删除
|
if err != nil {
|
||||||
if resp, err := y.CreateBatchTask("CLEAR_RECYCLE", y.FamilyID, "", nil, task); err == nil {
|
if err == errs.ObjectNotFound {
|
||||||
y.WaitBatchTask("CLEAR_RECYCLE", resp.TaskID, time.Second)
|
err = fmt.Errorf("unknown error: No transfer file obtained %s", newObj.GetName())
|
||||||
}
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
newObj = nil
|
|
||||||
|
// 重命名转存文件
|
||||||
|
newObj, err = y.Rename(context.TODO(), file, srcName)
|
||||||
|
if err != nil {
|
||||||
|
// 重命名失败删除源文件
|
||||||
|
_ = y.Delete(context.TODO(), "", file)
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/alist-org/alist/v3/internal/model"
|
||||||
"github.com/alist-org/alist/v3/pkg/utils/random"
|
"github.com/alist-org/alist/v3/pkg/utils/random"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -208,3 +209,12 @@ func IF[V any](o bool, t V, f V) V {
|
|||||||
}
|
}
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type WrapFileStreamer struct {
|
||||||
|
model.FileStreamer
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WrapFileStreamer) GetName() string {
|
||||||
|
return w.Name
|
||||||
|
}
|
||||||
|
@ -2,7 +2,6 @@ package _189pc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"container/ring"
|
|
||||||
"context"
|
"context"
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
@ -23,6 +22,7 @@ import (
|
|||||||
"github.com/alist-org/alist/v3/drivers/base"
|
"github.com/alist-org/alist/v3/drivers/base"
|
||||||
"github.com/alist-org/alist/v3/internal/conf"
|
"github.com/alist-org/alist/v3/internal/conf"
|
||||||
"github.com/alist-org/alist/v3/internal/driver"
|
"github.com/alist-org/alist/v3/internal/driver"
|
||||||
|
"github.com/alist-org/alist/v3/internal/errs"
|
||||||
"github.com/alist-org/alist/v3/internal/model"
|
"github.com/alist-org/alist/v3/internal/model"
|
||||||
"github.com/alist-org/alist/v3/internal/op"
|
"github.com/alist-org/alist/v3/internal/op"
|
||||||
"github.com/alist-org/alist/v3/internal/setting"
|
"github.com/alist-org/alist/v3/internal/setting"
|
||||||
@ -185,39 +185,9 @@ func (y *Cloud189PC) put(ctx context.Context, url string, headers map[string]str
|
|||||||
return body, nil
|
return body, nil
|
||||||
}
|
}
|
||||||
func (y *Cloud189PC) getFiles(ctx context.Context, fileId string, isFamily bool) ([]model.Obj, error) {
|
func (y *Cloud189PC) getFiles(ctx context.Context, fileId string, isFamily bool) ([]model.Obj, error) {
|
||||||
fullUrl := API_URL
|
res := make([]model.Obj, 0, 100)
|
||||||
if isFamily {
|
|
||||||
fullUrl += "/family/file"
|
|
||||||
}
|
|
||||||
fullUrl += "/listFiles.action"
|
|
||||||
|
|
||||||
res := make([]model.Obj, 0, 130)
|
|
||||||
for pageNum := 1; ; pageNum++ {
|
for pageNum := 1; ; pageNum++ {
|
||||||
var resp Cloud189FilesResp
|
resp, err := y.getFilesWithPage(ctx, fileId, isFamily, pageNum, 1000, y.OrderBy, y.OrderDirection)
|
||||||
_, err := y.get(fullUrl, func(r *resty.Request) {
|
|
||||||
r.SetContext(ctx)
|
|
||||||
r.SetQueryParams(map[string]string{
|
|
||||||
"folderId": fileId,
|
|
||||||
"fileType": "0",
|
|
||||||
"mediaAttr": "0",
|
|
||||||
"iconOption": "5",
|
|
||||||
"pageNum": fmt.Sprint(pageNum),
|
|
||||||
"pageSize": "130",
|
|
||||||
})
|
|
||||||
if isFamily {
|
|
||||||
r.SetQueryParams(map[string]string{
|
|
||||||
"familyId": y.FamilyID,
|
|
||||||
"orderBy": toFamilyOrderBy(y.OrderBy),
|
|
||||||
"descending": toDesc(y.OrderDirection),
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
r.SetQueryParams(map[string]string{
|
|
||||||
"recursive": "0",
|
|
||||||
"orderBy": y.OrderBy,
|
|
||||||
"descending": toDesc(y.OrderDirection),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}, &resp, isFamily)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -236,6 +206,63 @@ func (y *Cloud189PC) getFiles(ctx context.Context, fileId string, isFamily bool)
|
|||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (y *Cloud189PC) getFilesWithPage(ctx context.Context, fileId string, isFamily bool, pageNum int, pageSize int, orderBy string, orderDirection string) (*Cloud189FilesResp, error) {
|
||||||
|
fullUrl := API_URL
|
||||||
|
if isFamily {
|
||||||
|
fullUrl += "/family/file"
|
||||||
|
}
|
||||||
|
fullUrl += "/listFiles.action"
|
||||||
|
|
||||||
|
var resp Cloud189FilesResp
|
||||||
|
_, err := y.get(fullUrl, func(r *resty.Request) {
|
||||||
|
r.SetContext(ctx)
|
||||||
|
r.SetQueryParams(map[string]string{
|
||||||
|
"folderId": fileId,
|
||||||
|
"fileType": "0",
|
||||||
|
"mediaAttr": "0",
|
||||||
|
"iconOption": "5",
|
||||||
|
"pageNum": fmt.Sprint(pageNum),
|
||||||
|
"pageSize": fmt.Sprint(pageSize),
|
||||||
|
})
|
||||||
|
if isFamily {
|
||||||
|
r.SetQueryParams(map[string]string{
|
||||||
|
"familyId": y.FamilyID,
|
||||||
|
"orderBy": toFamilyOrderBy(orderBy),
|
||||||
|
"descending": toDesc(orderDirection),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
r.SetQueryParams(map[string]string{
|
||||||
|
"recursive": "0",
|
||||||
|
"orderBy": orderBy,
|
||||||
|
"descending": toDesc(orderDirection),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, &resp, isFamily)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (y *Cloud189PC) findFileByName(ctx context.Context, searchName string, folderId string, isFamily bool) (*Cloud189File, error) {
|
||||||
|
for pageNum := 1; ; pageNum++ {
|
||||||
|
resp, err := y.getFilesWithPage(ctx, folderId, isFamily, pageNum, 10, "filename", "asc")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// 获取完毕跳出
|
||||||
|
if resp.FileListAO.Count == 0 {
|
||||||
|
return nil, errs.ObjectNotFound
|
||||||
|
}
|
||||||
|
for i := 0; i < len(resp.FileListAO.FileList); i++ {
|
||||||
|
file := resp.FileListAO.FileList[i]
|
||||||
|
if file.Name == searchName {
|
||||||
|
return &file, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (y *Cloud189PC) login() (err error) {
|
func (y *Cloud189PC) login() (err error) {
|
||||||
// 初始化登陆所需参数
|
// 初始化登陆所需参数
|
||||||
if y.loginParam == nil {
|
if y.loginParam == nil {
|
||||||
@ -902,8 +929,7 @@ func (y *Cloud189PC) isLogin() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 创建家庭云中转文件夹
|
// 创建家庭云中转文件夹
|
||||||
func (y *Cloud189PC) createFamilyTransferFolder(count int) (*ring.Ring, error) {
|
func (y *Cloud189PC) createFamilyTransferFolder() error {
|
||||||
folders := ring.New(count)
|
|
||||||
var rootFolder Cloud189Folder
|
var rootFolder Cloud189Folder
|
||||||
_, err := y.post(API_URL+"/family/file/createFolder.action", func(req *resty.Request) {
|
_, err := y.post(API_URL+"/family/file/createFolder.action", func(req *resty.Request) {
|
||||||
req.SetQueryParams(map[string]string{
|
req.SetQueryParams(map[string]string{
|
||||||
@ -912,81 +938,61 @@ func (y *Cloud189PC) createFamilyTransferFolder(count int) (*ring.Ring, error) {
|
|||||||
})
|
})
|
||||||
}, &rootFolder, true)
|
}, &rootFolder, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
y.familyTransferFolder = &rootFolder
|
||||||
folderCount := 0
|
return nil
|
||||||
|
|
||||||
// 获取已有目录
|
|
||||||
files, err := y.getFiles(context.TODO(), rootFolder.GetID(), true)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for _, file := range files {
|
|
||||||
if folder, ok := file.(*Cloud189Folder); ok {
|
|
||||||
folders.Value = folder
|
|
||||||
folders = folders.Next()
|
|
||||||
folderCount++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建新的目录
|
|
||||||
for folderCount < count {
|
|
||||||
var newFolder Cloud189Folder
|
|
||||||
_, err := y.post(API_URL+"/family/file/createFolder.action", func(req *resty.Request) {
|
|
||||||
req.SetQueryParams(map[string]string{
|
|
||||||
"folderName": uuid.NewString(),
|
|
||||||
"familyId": y.FamilyID,
|
|
||||||
"parentId": rootFolder.GetID(),
|
|
||||||
})
|
|
||||||
}, &newFolder, true)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
folders.Value = &newFolder
|
|
||||||
folders = folders.Next()
|
|
||||||
folderCount++
|
|
||||||
}
|
|
||||||
return folders, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清理中转文件夹
|
// 清理中转文件夹
|
||||||
func (y *Cloud189PC) cleanFamilyTransfer(ctx context.Context) error {
|
func (y *Cloud189PC) cleanFamilyTransfer(ctx context.Context) error {
|
||||||
var tasks []BatchTaskInfo
|
transferFolderId := y.familyTransferFolder.GetID()
|
||||||
r := y.familyTransferFolder
|
for pageNum := 1; ; pageNum++ {
|
||||||
for p := r.Next(); p != r; p = p.Next() {
|
resp, err := y.getFilesWithPage(ctx, transferFolderId, true, pageNum, 100, "lastOpTime", "asc")
|
||||||
folder := p.Value.(*Cloud189Folder)
|
|
||||||
|
|
||||||
files, err := y.getFiles(ctx, folder.GetID(), true)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, file := range files {
|
// 获取完毕跳出
|
||||||
|
if resp.FileListAO.Count == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
var tasks []BatchTaskInfo
|
||||||
|
for i := 0; i < len(resp.FileListAO.FolderList); i++ {
|
||||||
|
folder := resp.FileListAO.FolderList[i]
|
||||||
|
tasks = append(tasks, BatchTaskInfo{
|
||||||
|
FileId: folder.GetID(),
|
||||||
|
FileName: folder.GetName(),
|
||||||
|
IsFolder: BoolToNumber(folder.IsDir()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
for i := 0; i < len(resp.FileListAO.FileList); i++ {
|
||||||
|
file := resp.FileListAO.FileList[i]
|
||||||
tasks = append(tasks, BatchTaskInfo{
|
tasks = append(tasks, BatchTaskInfo{
|
||||||
FileId: file.GetID(),
|
FileId: file.GetID(),
|
||||||
FileName: file.GetName(),
|
FileName: file.GetName(),
|
||||||
IsFolder: BoolToNumber(file.IsDir()),
|
IsFolder: BoolToNumber(file.IsDir()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if len(tasks) > 0 {
|
if len(tasks) > 0 {
|
||||||
// 删除
|
// 删除
|
||||||
resp, err := y.CreateBatchTask("DELETE", y.FamilyID, "", nil, tasks...)
|
resp, err := y.CreateBatchTask("DELETE", y.FamilyID, "", nil, tasks...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = y.WaitBatchTask("DELETE", resp.TaskID, time.Second)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// 永久删除
|
||||||
|
resp, err = y.CreateBatchTask("CLEAR_RECYCLE", y.FamilyID, "", nil, tasks...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = y.WaitBatchTask("CLEAR_RECYCLE", resp.TaskID, time.Second)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = y.WaitBatchTask("DELETE", resp.TaskID, time.Second)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// 永久删除
|
|
||||||
resp, err = y.CreateBatchTask("CLEAR_RECYCLE", y.FamilyID, "", nil, tasks...)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = y.WaitBatchTask("CLEAR_RECYCLE", resp.TaskID, time.Second)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -1063,6 +1069,34 @@ func (y *Cloud189PC) SaveFamilyFileToPersonCloud(ctx context.Context, familyId s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 永久删除文件
|
||||||
|
func (y *Cloud189PC) Delete(ctx context.Context, familyId string, srcObj model.Obj) error {
|
||||||
|
task := BatchTaskInfo{
|
||||||
|
FileId: srcObj.GetID(),
|
||||||
|
FileName: srcObj.GetName(),
|
||||||
|
IsFolder: BoolToNumber(srcObj.IsDir()),
|
||||||
|
}
|
||||||
|
// 删除源文件
|
||||||
|
resp, err := y.CreateBatchTask("DELETE", familyId, "", nil, task)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = y.WaitBatchTask("DELETE", resp.TaskID, time.Second)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// 清除回收站
|
||||||
|
resp, err = y.CreateBatchTask("CLEAR_RECYCLE", familyId, "", nil, task)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = y.WaitBatchTask("CLEAR_RECYCLE", resp.TaskID, time.Second)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (y *Cloud189PC) CreateBatchTask(aType string, familyID string, targetFolderId string, other map[string]string, taskInfos ...BatchTaskInfo) (*CreateBatchTaskResp, error) {
|
func (y *Cloud189PC) CreateBatchTask(aType string, familyID string, targetFolderId string, other map[string]string, taskInfos ...BatchTaskInfo) (*CreateBatchTaskResp, error) {
|
||||||
var resp CreateBatchTaskResp
|
var resp CreateBatchTaskResp
|
||||||
_, err := y.post(API_URL+"/batch/createBatchTask.action", func(req *resty.Request) {
|
_, err := y.post(API_URL+"/batch/createBatchTask.action", func(req *resty.Request) {
|
||||||
|
@ -34,31 +34,36 @@ func NewDebounce2(interval time.Duration, f func()) func() {
|
|||||||
if timer == nil {
|
if timer == nil {
|
||||||
timer = time.AfterFunc(interval, f)
|
timer = time.AfterFunc(interval, f)
|
||||||
}
|
}
|
||||||
(*time.Timer)(timer).Reset(interval)
|
timer.Reset(interval)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewThrottle(interval time.Duration) func(func()) {
|
func NewThrottle(interval time.Duration) func(func()) {
|
||||||
var lastCall time.Time
|
var lastCall time.Time
|
||||||
|
var lock sync.Mutex
|
||||||
return func(fn func()) {
|
return func(fn func()) {
|
||||||
|
lock.Lock()
|
||||||
|
defer lock.Unlock()
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
if now.Sub(lastCall) < interval {
|
if now.Sub(lastCall) >= interval {
|
||||||
return
|
lastCall = now
|
||||||
|
go fn()
|
||||||
}
|
}
|
||||||
time.AfterFunc(interval, fn)
|
|
||||||
lastCall = now
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewThrottle2(interval time.Duration, fn func()) func() {
|
func NewThrottle2(interval time.Duration, fn func()) func() {
|
||||||
var lastCall time.Time
|
var lastCall time.Time
|
||||||
|
var lock sync.Mutex
|
||||||
return func() {
|
return func() {
|
||||||
|
lock.Lock()
|
||||||
|
defer lock.Unlock()
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
if now.Sub(lastCall) < interval {
|
if now.Sub(lastCall) >= interval {
|
||||||
return
|
lastCall = now
|
||||||
|
go fn()
|
||||||
}
|
}
|
||||||
time.AfterFunc(interval, fn)
|
|
||||||
lastCall = now
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user