From ffd8131dfda8dcdd368fb511428c31e95c2ffa03 Mon Sep 17 00:00:00 2001 From: hexxa Date: Mon, 27 Sep 2021 22:24:22 +0800 Subject: [PATCH] fix(files): used space is incorrect --- src/client/web/src/worker/chunk_uploader.ts | 2 +- src/handlers/fileshdr/handlers.go | 29 ++++++++++----------- src/userstore/user_store.go | 22 ++++++++++++++++ 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/src/client/web/src/worker/chunk_uploader.ts b/src/client/web/src/worker/chunk_uploader.ts index 6669d82..3e30480 100644 --- a/src/client/web/src/worker/chunk_uploader.ts +++ b/src/client/web/src/worker/chunk_uploader.ts @@ -8,7 +8,7 @@ const defaultChunkLen = 1024 * 1024 * 1; const speedDownRatio = 0.5; const speedUpRatio = 1.1; const speedLimit = 1024 * 1024 * 10; // 10MB -const createRetryLimit = 3; +const createRetryLimit = 512; const uploadRetryLimit = 1024; const backoffMax = 2000; diff --git a/src/handlers/fileshdr/handlers.go b/src/handlers/fileshdr/handlers.go index bf2aa1f..bd1a245 100644 --- a/src/handlers/fileshdr/handlers.go +++ b/src/handlers/fileshdr/handlers.go @@ -145,26 +145,19 @@ func (h *FileHandlers) Create(c *gin.Context) { tmpFilePath := q.UploadPath(userName, req.Path) locker := h.NewAutoLocker(c, lockName(tmpFilePath)) locker.Exec(func() { - err = h.deps.Users().SetUsed(userIDInt, true, req.FileSize) + ok, err := h.deps.Users().CanIncrUsed(userIDInt, req.FileSize) if err != nil { - if userstore.IsReachedLimitErr(err) { - c.JSON(q.ErrResp(c, 429, err)) - } else { - c.JSON(q.ErrResp(c, 500, err)) - } + c.JSON(q.ErrResp(c, 500, err)) + return + } else if !ok { + c.JSON(q.ErrResp(c, 429, err)) return } err = h.deps.FS().Create(tmpFilePath) if err != nil { if os.IsExist(err) { - // avoid adding file size more than once - err = h.deps.Users().SetUsed(userIDInt, false, req.FileSize) - if err != nil { - c.JSON(q.ErrResp(c, 500, err)) - } else { - c.JSON(q.ErrResp(c, 304, fmt.Errorf("file(%s) exists", tmpFilePath))) - } + c.JSON(q.ErrResp(c, 304, fmt.Errorf("file(%s) exists", tmpFilePath))) } else { c.JSON(q.ErrResp(c, 500, err)) } @@ -182,6 +175,12 @@ func (h *FileHandlers) Create(c *gin.Context) { return } + err = h.deps.Users().SetUsed(userIDInt, true, req.FileSize) + if err != nil { + c.JSON(q.ErrResp(c, 500, err)) + return + } + c.JSON(q.Resp(200)) }) } @@ -800,13 +799,13 @@ func (h *FileHandlers) DelUploading(c *gin.Context) { return } - err = h.deps.Users().SetUsed(userIDInt, false, size) + err = h.uploadMgr.DelInfo(userID, tmpFilePath) if err != nil { c.JSON(q.ErrResp(c, 500, err)) return } - err = h.uploadMgr.DelInfo(userID, tmpFilePath) + err = h.deps.Users().SetUsed(userIDInt, false, size) if err != nil { c.JSON(q.ErrResp(c, 500, err)) return diff --git a/src/userstore/user_store.go b/src/userstore/user_store.go index 0a84af7..2a07ccd 100644 --- a/src/userstore/user_store.go +++ b/src/userstore/user_store.go @@ -66,6 +66,7 @@ type IUserStore interface { GetUser(id uint64) (*User, error) GetUserByName(name string) (*User, error) SetInfo(id uint64, user *User) error + CanIncrUsed(id uint64, capacity int64) (bool, error) SetUsed(id uint64, incr bool, capacity int64) error SetPwd(id uint64, pwd string) error ListUsers() ([]*User, error) @@ -275,6 +276,27 @@ func (us *KVUserStore) SetPwd(id uint64, pwd string) error { return us.store.SetStringIn(UsersNs, userID, string(infoBytes)) } +func (us *KVUserStore) CanIncrUsed(id uint64, capacity int64) (bool, error) { + us.mtx.Lock() + defer us.mtx.Unlock() + + userID := fmt.Sprint(id) + infoStr, ok := us.store.GetStringIn(UsersNs, userID) + if !ok { + return false, fmt.Errorf("user (%d) does not exist", id) + } + + gotUser := &User{} + err := json.Unmarshal([]byte(infoStr), gotUser) + if err != nil { + return false, err + } else if gotUser.ID != id { + return false, fmt.Errorf("user id key(%d) info(%d) does match", id, gotUser.ID) + } + + return gotUser.UsedSpace+capacity <= int64(gotUser.Quota.SpaceLimit), nil +} + func (us *KVUserStore) SetUsed(id uint64, incr bool, capacity int64) error { us.mtx.Lock() defer us.mtx.Unlock()