fix(files): avoid overwriting lock failed error

This commit is contained in:
hexxa 2022-08-19 20:52:15 +08:00 committed by Hexxa
parent f68b5532ec
commit cc9355d630

View file

@ -70,7 +70,7 @@ func (h *FileHandlers) NewAutoLocker(c *gin.Context, key string) *AutoLocker {
} }
} }
func (lk *AutoLocker) Exec(handler func()) { func (lk *AutoLocker) Exec(handler func()) error {
var err error var err error
kv := lk.h.deps.KV() kv := lk.h.deps.KV()
locked := false locked := false
@ -87,12 +87,12 @@ func (lk *AutoLocker) Exec(handler func()) {
}() }()
if err = kv.TryLock(lk.key); err != nil { if err = kv.TryLock(lk.key); err != nil {
lk.c.JSON(q.ErrResp(lk.c, 500, errors.New("fail to lock the file"))) return errors.New("fail to lock the file")
return
} }
locked = true locked = true
handler() handler()
return nil
} }
// related elements: role, user, action(listing, downloading)/sharing // related elements: role, user, action(listing, downloading)/sharing
@ -235,14 +235,18 @@ func (h *FileHandlers) Create(c *gin.Context) {
return return
} }
var txErr error
locker := h.NewAutoLocker(c, lockName(tmpFilePath)) locker := h.NewAutoLocker(c, lockName(tmpFilePath))
locker.Exec(func() { lockErr := locker.Exec(func() {
err = h.deps.FS().Create(tmpFilePath) err = h.deps.FS().Create(tmpFilePath)
if err != nil { if err != nil {
if os.IsExist(err) { if os.IsExist(err) {
c.JSON(q.ErrResp(c, 304, fmt.Errorf("file(%s) exists", tmpFilePath))) createErr := fmt.Errorf("file(%s) exists", tmpFilePath)
c.JSON(q.ErrResp(c, 304, createErr))
txErr = createErr
} else { } else {
c.JSON(q.ErrResp(c, 500, err)) c.JSON(q.ErrResp(c, 500, err))
txErr = err
} }
return return
} }
@ -250,11 +254,19 @@ func (h *FileHandlers) Create(c *gin.Context) {
err = h.deps.FS().MkdirAll(filepath.Dir(req.Path)) err = h.deps.FS().MkdirAll(filepath.Dir(req.Path))
if err != nil { if err != nil {
c.JSON(q.ErrResp(c, 500, err)) c.JSON(q.ErrResp(c, 500, err))
txErr = err
return return
} }
c.JSON(q.Resp(200))
}) })
if lockErr != nil {
c.JSON(q.ErrResp(c, 500, lockErr))
return
}
if txErr != nil {
c.JSON(q.ErrResp(c, 500, txErr))
return
}
c.JSON(q.Resp(200))
} }
func (h *FileHandlers) Delete(c *gin.Context) { func (h *FileHandlers) Delete(c *gin.Context) {
@ -281,7 +293,7 @@ func (h *FileHandlers) Delete(c *gin.Context) {
var txErr error var txErr error
locker := h.NewAutoLocker(c, lockName(filePath)) locker := h.NewAutoLocker(c, lockName(filePath))
locker.Exec(func() { lockErr := locker.Exec(func() {
err = h.deps.FS().Remove(filePath) err = h.deps.FS().Remove(filePath)
if err != nil { if err != nil {
txErr = err txErr = err
@ -300,7 +312,10 @@ func (h *FileHandlers) Delete(c *gin.Context) {
return return
} }
}) })
if lockErr != nil {
c.JSON(q.ErrResp(c, 500, lockErr))
return
}
if txErr != nil { if txErr != nil {
c.JSON(q.ErrResp(c, 500, txErr)) c.JSON(q.ErrResp(c, 500, txErr))
return return
@ -490,10 +505,11 @@ func (h *FileHandlers) UploadChunk(c *gin.Context) {
var statusCode int var statusCode int
tmpFilePath := q.UploadPath(userName, filePath) tmpFilePath := q.UploadPath(userName, filePath)
locker := h.NewAutoLocker(c, lockName(tmpFilePath)) locker := h.NewAutoLocker(c, lockName(tmpFilePath))
locker.Exec(func() { fsFilePath, fileSize, uploaded, wrote := "", int64(0), int64(0), 0
lockErr := locker.Exec(func() {
var err error var err error
fsFilePath, fileSize, uploaded, err := h.deps.FileInfos().GetUploadInfo(userID, tmpFilePath) fsFilePath, fileSize, uploaded, err = h.deps.FileInfos().GetUploadInfo(userID, tmpFilePath)
if err != nil { if err != nil {
txErr, statusCode = err, 500 txErr, statusCode = err, 500
return return
@ -508,7 +524,7 @@ func (h *FileHandlers) UploadChunk(c *gin.Context) {
return return
} }
wrote, err := h.deps.FS().WriteAt(tmpFilePath, []byte(content), req.Offset) wrote, err = h.deps.FS().WriteAt(tmpFilePath, []byte(content), req.Offset)
if err != nil { if err != nil {
txErr, statusCode = err, 500 txErr, statusCode = err, 500
return return
@ -560,17 +576,19 @@ func (h *FileHandlers) UploadChunk(c *gin.Context) {
return return
} }
} }
})
if txErr != nil { if lockErr != nil {
c.JSON(q.ErrResp(c, statusCode, txErr)) c.JSON(q.ErrResp(c, 500, err))
return }
} if txErr != nil {
c.JSON(200, &UploadStatusResp{ c.JSON(q.ErrResp(c, statusCode, txErr))
Path: fsFilePath, return
IsDir: false, }
FileSize: fileSize, c.JSON(200, &UploadStatusResp{
Uploaded: uploaded + int64(wrote), Path: fsFilePath,
}) IsDir: false,
FileSize: fileSize,
Uploaded: uploaded + int64(wrote),
}) })
} }
@ -635,23 +653,35 @@ func (h *FileHandlers) UploadStatus(c *gin.Context) {
userID := c.MustGet(q.UserIDParam).(string) userID := c.MustGet(q.UserIDParam).(string)
tmpFilePath := q.UploadPath(userName, filePath) tmpFilePath := q.UploadPath(userName, filePath)
locker := h.NewAutoLocker(c, lockName(tmpFilePath)) locker := h.NewAutoLocker(c, lockName(tmpFilePath))
locker.Exec(func() { fileSize, uploaded := int64(0), int64(0)
_, fileSize, uploaded, err := h.deps.FileInfos().GetUploadInfo(userID, tmpFilePath) var txErr error
lockErr := locker.Exec(func() {
var err error
_, fileSize, uploaded, err = h.deps.FileInfos().GetUploadInfo(userID, tmpFilePath)
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
c.JSON(q.ErrResp(c, 404, err)) c.JSON(q.ErrResp(c, 404, err))
txErr = err
} else { } else {
c.JSON(q.ErrResp(c, 500, err)) c.JSON(q.ErrResp(c, 500, err))
txErr = err
} }
return return
} }
})
c.JSON(200, &UploadStatusResp{ if lockErr != nil {
Path: filePath, c.JSON(q.ErrResp(c, 500, lockErr))
IsDir: false, return
FileSize: fileSize, }
Uploaded: uploaded, if txErr != nil {
}) c.JSON(q.ErrResp(c, 500, txErr))
return
}
c.JSON(200, &UploadStatusResp{
Path: filePath,
IsDir: false,
FileSize: fileSize,
Uploaded: uploaded,
}) })
} }
@ -930,7 +960,7 @@ func (h *FileHandlers) DelUploading(c *gin.Context) {
var statusCode int var statusCode int
tmpFilePath := q.UploadPath(userName, filePath) tmpFilePath := q.UploadPath(userName, filePath)
locker := h.NewAutoLocker(c, lockName(tmpFilePath)) locker := h.NewAutoLocker(c, lockName(tmpFilePath))
locker.Exec(func() { lockErr := locker.Exec(func() {
_, err = h.deps.FS().Stat(tmpFilePath) _, err = h.deps.FS().Stat(tmpFilePath)
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
@ -947,17 +977,19 @@ func (h *FileHandlers) DelUploading(c *gin.Context) {
} }
} }
}) })
if lockErr != nil {
c.JSON(q.ErrResp(c, 500, lockErr))
return
}
if txErr != nil { if txErr != nil {
c.JSON(q.ErrResp(c, statusCode, txErr)) c.JSON(q.ErrResp(c, statusCode, txErr))
return return
} }
err = h.deps.BoltStore().DelUploadingInfos(userIDInt, tmpFilePath) err = h.deps.BoltStore().DelUploadingInfos(userIDInt, tmpFilePath)
if err != nil { if err != nil {
c.JSON(q.ErrResp(c, 500, err)) c.JSON(q.ErrResp(c, 500, err))
return return
} }
c.JSON(q.Resp(200)) c.JSON(q.Resp(200))
} }