memorylocker: Implement new locker interface
This commit is contained in:
parent
8e1dce1dcb
commit
65072acb79
|
@ -35,6 +35,8 @@ func New(path string) FileLocker {
|
||||||
return FileLocker{path}
|
return FileLocker{path}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Add UseIn method
|
||||||
|
|
||||||
func (locker FileLocker) NewLock(id string) (handler.Lock, error) {
|
func (locker FileLocker) NewLock(id string) (handler.Lock, error) {
|
||||||
path, err := filepath.Abs(filepath.Join(locker.Path, id+".lock"))
|
path, err := filepath.Abs(filepath.Join(locker.Path, id+".lock"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -33,32 +33,42 @@ func New() *MemoryLocker {
|
||||||
|
|
||||||
// UseIn adds this locker to the passed composer.
|
// UseIn adds this locker to the passed composer.
|
||||||
func (locker *MemoryLocker) UseIn(composer *handler.StoreComposer) {
|
func (locker *MemoryLocker) UseIn(composer *handler.StoreComposer) {
|
||||||
composer.UseLocker(locker)
|
// TOOD: Add back
|
||||||
|
//composer.UseLocker(locker)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (locker *MemoryLocker) NewLock(id string) (handler.Lock, error) {
|
||||||
|
return memoryLock{locker, id}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type memoryLock struct {
|
||||||
|
locker *MemoryLocker
|
||||||
|
id string
|
||||||
}
|
}
|
||||||
|
|
||||||
// LockUpload tries to obtain the exclusive lock.
|
// LockUpload tries to obtain the exclusive lock.
|
||||||
func (locker *MemoryLocker) LockUpload(id string) error {
|
func (lock memoryLock) Lock() error {
|
||||||
locker.mutex.Lock()
|
lock.locker.mutex.Lock()
|
||||||
defer locker.mutex.Unlock()
|
defer lock.locker.mutex.Unlock()
|
||||||
|
|
||||||
// Ensure file is not locked
|
// Ensure file is not locked
|
||||||
if _, ok := locker.locks[id]; ok {
|
if _, ok := lock.locker.locks[lock.id]; ok {
|
||||||
return handler.ErrFileLocked
|
return handler.ErrFileLocked
|
||||||
}
|
}
|
||||||
|
|
||||||
locker.locks[id] = struct{}{}
|
lock.locker.locks[lock.id] = struct{}{}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnlockUpload releases a lock. If no such lock exists, no error will be returned.
|
// UnlockUpload releases a lock. If no such lock exists, no error will be returned.
|
||||||
func (locker *MemoryLocker) UnlockUpload(id string) error {
|
func (lock memoryLock) Unlock() error {
|
||||||
locker.mutex.Lock()
|
lock.locker.mutex.Lock()
|
||||||
|
|
||||||
// Deleting a non-existing key does not end in unexpected errors or panic
|
// Deleting a non-existing key does not end in unexpected errors or panic
|
||||||
// since this operation results in a no-op
|
// since this operation results in a no-op
|
||||||
delete(locker.locks, id)
|
delete(lock.locker.locks, lock.id)
|
||||||
|
|
||||||
locker.mutex.Unlock()
|
lock.locker.mutex.Unlock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,14 +8,23 @@ import (
|
||||||
"github.com/tus/tusd/pkg/handler"
|
"github.com/tus/tusd/pkg/handler"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var _ handler.Locker = &MemoryLocker{}
|
||||||
|
|
||||||
func TestMemoryLocker(t *testing.T) {
|
func TestMemoryLocker(t *testing.T) {
|
||||||
a := assert.New(t)
|
a := assert.New(t)
|
||||||
|
|
||||||
var locker handler.LockerDataStore
|
locker := New()
|
||||||
locker = New()
|
|
||||||
|
|
||||||
a.NoError(locker.LockUpload("one"))
|
lock1, err := locker.NewLock("one")
|
||||||
a.Equal(handler.ErrFileLocked, locker.LockUpload("one"))
|
a.NoError(err)
|
||||||
a.NoError(locker.UnlockUpload("one"))
|
|
||||||
a.NoError(locker.UnlockUpload("one"))
|
a.NoError(lock1.Lock())
|
||||||
|
a.Equal(handler.ErrFileLocked, lock1.Lock())
|
||||||
|
|
||||||
|
lock2, err := locker.NewLock("one")
|
||||||
|
a.NoError(err)
|
||||||
|
a.Equal(handler.ErrFileLocked, lock2.Lock())
|
||||||
|
|
||||||
|
a.NoError(lock1.Unlock())
|
||||||
|
a.NoError(lock1.Unlock())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue