tusd/pkg/etcd3locker/lock.go

52 lines
1.1 KiB
Go

// Package etcd3locker provides a locking mechanism using an etcd3 cluster.
// Tested on etcd 3.1/3.2./3.3
package etcd3locker
import (
"context"
"time"
"github.com/tus/tusd/pkg/handler"
"go.etcd.io/etcd/clientv3/concurrency"
)
type etcd3Lock struct {
Id string
Mutex *concurrency.Mutex
Session *concurrency.Session
}
func newEtcd3Lock(session *concurrency.Session, id string) *etcd3Lock {
return &etcd3Lock{
Mutex: concurrency.NewMutex(session, id),
Session: session,
}
}
// Acquires a lock from etcd3
func (lock *etcd3Lock) Acquire() error {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// this is a blocking call; if we receive DeadlineExceeded
// the lock is most likely already taken
if err := lock.Mutex.Lock(ctx); err != nil {
if err == context.DeadlineExceeded {
return handler.ErrFileLocked
} else {
return err
}
}
return nil
}
// Releases a lock from etcd3
func (lock *etcd3Lock) Release() error {
return lock.Mutex.Unlock(context.Background())
}
// Closes etcd3 session
func (lock *etcd3Lock) CloseSession() error {
return lock.Session.Close()
}