tusd/filestore/filelock.go

66 lines
1.6 KiB
Go
Raw Normal View History

2015-12-18 23:02:11 +00:00
package filestore
import (
"os"
"path/filepath"
"github.com/nightlyone/lockfile"
"github.com/tus/tusd"
)
2015-12-25 20:33:58 +00:00
// FileLocker provides an exclusive upload locking mechansim using lock files
// which are stored on disk. Each of them stores the PID of the process which
// aquired the lock. This allows locks to be automatically freed when a process
// is unable to release it on its own because the process is not alive anymore.
//
// Please consult the package lockingstore for instructions on how to use this
// locker.
2015-12-18 23:02:11 +00:00
type FileLocker struct {
// Relative or absolute path to store the locks in.
Path string
}
func (locker FileLocker) LockUpload(id string) error {
lock, err := locker.newLock(id)
if err != nil {
return err
}
err = lock.TryLock()
if err == lockfile.ErrBusy {
return tusd.ErrFileLocked
}
return err
}
func (locker FileLocker) UnlockUpload(id string) error {
lock, err := locker.newLock(id)
if err != nil {
return err
}
err = lock.Unlock()
// A "no such file or directory" will be returned if no lockfile was found.
// Since this means that the file has never been locked, we drop the error
// and continue as if nothing happend.
if os.IsNotExist(err) {
err = nil
}
return nil
}
func (locker FileLocker) newLock(id string) (lockfile.Lockfile, error) {
path, err := filepath.Abs(locker.Path + "/" + id + ".lock")
if err != nil {
return lockfile.Lockfile(""), err
}
// We use Lockfile directly instead of lockfile.New to bypass the unnecessary
// check whether the provided path is absolute since we just resolved it
// on our own.
return lockfile.Lockfile(path), nil
}