Add filestore.FileLocker

This commit is contained in:
Marius 2015-12-19 00:02:11 +01:00
parent 8d94d55320
commit 83587ca0f8
2 changed files with 93 additions and 0 deletions

58
filestore/filelock.go Normal file
View File

@ -0,0 +1,58 @@
package filestore
import (
"os"
"path/filepath"
"github.com/nightlyone/lockfile"
"github.com/tus/tusd"
)
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
}

View File

@ -0,0 +1,35 @@
package filestore
import (
"io/ioutil"
"testing"
"github.com/tus/tusd"
"github.com/tus/tusd/lockingstore"
)
func TestFileLocker(t *testing.T) {
dir, err := ioutil.TempDir("", "tusd-file-locker")
if err != nil {
t.Fatal(err)
}
var locker lockingstore.Locker
locker = FileLocker{dir}
if err := locker.LockUpload("one"); err != nil {
t.Errorf("unexpected error when locking file: %s", err)
}
if err := locker.LockUpload("one"); err != tusd.ErrFileLocked {
t.Errorf("expected error when locking locked file: %s", err)
}
if err := locker.UnlockUpload("one"); err != nil {
t.Errorf("unexpected error when unlocking file: %s", err)
}
if err := locker.UnlockUpload("one"); err != nil {
t.Errorf("unexpected error when unlocking file again: %s", err)
}
}