fix(files): avoid overwriting lock failed error
This commit is contained in:
parent
f68b5532ec
commit
cc9355d630
1 changed files with 67 additions and 35 deletions
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue