database: remove FindLock()
This commit is contained in:
parent
45ecf18815
commit
399deab100
@ -183,23 +183,16 @@ type Session interface {
|
|||||||
// FindKeyValue retrieves a value from the given key.
|
// FindKeyValue retrieves a value from the given key.
|
||||||
FindKeyValue(key string) (value string, found bool, err error)
|
FindKeyValue(key string) (value string, found bool, err error)
|
||||||
|
|
||||||
// Lock creates or renew a Lock in the database with the given name, owner
|
// Lock acquires or renews a lock in the database with the given name, owner
|
||||||
// and duration.
|
// and duration without blocking. After the specified duration, the lock
|
||||||
|
// expires if it hasn't already been unlocked in order to prevent a deadlock.
|
||||||
//
|
//
|
||||||
// After the specified duration, the Lock expires by itself if it hasn't been
|
// If the acquisition of a lock is not successful, expiration should be
|
||||||
// unlocked, and thus, let other users create a Lock with the same name.
|
// the time that existing lock expires.
|
||||||
// However, the owner can renew its Lock by setting renew to true.
|
|
||||||
// Lock should not block, it should instead returns whether the Lock has been
|
|
||||||
// successfully acquired/renewed. If it's the case, the expiration time of
|
|
||||||
// that Lock is returned as well.
|
|
||||||
Lock(name string, owner string, duration time.Duration, renew bool) (success bool, expiration time.Time, err error)
|
Lock(name string, owner string, duration time.Duration, renew bool) (success bool, expiration time.Time, err error)
|
||||||
|
|
||||||
// Unlock releases an existing Lock.
|
// Unlock releases an existing Lock.
|
||||||
Unlock(name, owner string) error
|
Unlock(name, owner string) error
|
||||||
|
|
||||||
// FindLock returns the owner of a Lock specified by the name, and its
|
|
||||||
// expiration time if it exists.
|
|
||||||
FindLock(name string) (owner string, expiration time.Time, found bool, err error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Datastore represents a persistent data store
|
// Datastore represents a persistent data store
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/deckarep/golang-set"
|
"github.com/deckarep/golang-set"
|
||||||
@ -351,24 +350,3 @@ func ReleaseLock(datastore Datastore, name, owner string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrLockNotFound is returned when FindLock succeeds, but cannot find a lock.
|
|
||||||
var ErrLockNotFound = errors.New("no lock was found")
|
|
||||||
|
|
||||||
// FindLock determines if a global lock with the provided name already exists.
|
|
||||||
func FindLock(datastore Datastore, updaterLockName string) (owner string, expiration time.Time, err error) {
|
|
||||||
var tx Session
|
|
||||||
tx, err = datastore.Begin()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer tx.Rollback()
|
|
||||||
|
|
||||||
var found bool
|
|
||||||
owner, expiration, found, err = tx.FindLock(updaterLockName)
|
|
||||||
if err != nil && !found {
|
|
||||||
err = ErrLockNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
@ -25,7 +25,7 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
soiLock = `INSERT INTO lock(name, owner, until) VALUES ($1, $2, $3)`
|
soiLock = `INSERT INTO lock(name, owner, until) VALUES ($1, $2, $3)`
|
||||||
searchLock = `SELECT owner, until FROM Lock WHERE name = $1`
|
searchLock = `SELECT until FROM Lock WHERE name = $1`
|
||||||
updateLock = `UPDATE Lock SET until = $3 WHERE name = $1 AND owner = $2`
|
updateLock = `UPDATE Lock SET until = $3 WHERE name = $1 AND owner = $2`
|
||||||
removeLock = `DELETE FROM Lock WHERE name = $1 AND owner = $2`
|
removeLock = `DELETE FROM Lock WHERE name = $1 AND owner = $2`
|
||||||
removeLockExpired = `DELETE FROM LOCK WHERE until < CURRENT_TIMESTAMP`
|
removeLockExpired = `DELETE FROM LOCK WHERE until < CURRENT_TIMESTAMP`
|
||||||
@ -67,7 +67,9 @@ func (tx *pgSession) Lock(name string, owner string, duration time.Duration, ren
|
|||||||
_, err := tx.Exec(soiLock, name, owner, until)
|
_, err := tx.Exec(soiLock, name, owner, until)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if isErrUniqueViolation(err) {
|
if isErrUniqueViolation(err) {
|
||||||
return false, until, nil
|
// Return the existing locks expiration.
|
||||||
|
err := tx.QueryRow(searchLock, name).Scan(&until)
|
||||||
|
return false, until, handleError("searchLock", err)
|
||||||
}
|
}
|
||||||
return false, until, handleError("insertLock", err)
|
return false, until, handleError("insertLock", err)
|
||||||
}
|
}
|
||||||
@ -86,25 +88,6 @@ func (tx *pgSession) Unlock(name, owner string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindLock returns the owner of a lock specified by its name and its
|
|
||||||
// expiration time.
|
|
||||||
func (tx *pgSession) FindLock(name string) (string, time.Time, bool, error) {
|
|
||||||
if name == "" {
|
|
||||||
return "", time.Time{}, false, commonerr.NewBadRequestError("could not find an invalid lock")
|
|
||||||
}
|
|
||||||
|
|
||||||
defer observeQueryTime("FindLock", "all", time.Now())
|
|
||||||
|
|
||||||
var owner string
|
|
||||||
var until time.Time
|
|
||||||
err := tx.QueryRow(searchLock, name).Scan(&owner, &until)
|
|
||||||
if err != nil {
|
|
||||||
return owner, until, false, handleError("searchLock", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return owner, until, true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// pruneLocks removes every expired locks from the database
|
// pruneLocks removes every expired locks from the database
|
||||||
func (tx *pgSession) pruneLocks() error {
|
func (tx *pgSession) pruneLocks() error {
|
||||||
defer observeQueryTime("pruneLocks", "all", time.Now())
|
defer observeQueryTime("pruneLocks", "all", time.Now())
|
||||||
|
@ -26,7 +26,6 @@ func TestLock(t *testing.T) {
|
|||||||
defer datastore.Close()
|
defer datastore.Close()
|
||||||
|
|
||||||
var l bool
|
var l bool
|
||||||
var et time.Time
|
|
||||||
|
|
||||||
// Create a first lock.
|
// Create a first lock.
|
||||||
l, _, err := tx.Lock("test1", "owner1", time.Minute, false)
|
l, _, err := tx.Lock("test1", "owner1", time.Minute, false)
|
||||||
@ -62,19 +61,11 @@ func TestLock(t *testing.T) {
|
|||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
tx = restartSession(t, datastore, tx, true)
|
tx = restartSession(t, datastore, tx, true)
|
||||||
|
|
||||||
l, et, err = tx.Lock("test1", "owner2", time.Minute, false)
|
l, _, err = tx.Lock("test1", "owner2", time.Minute, false)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.True(t, l)
|
assert.True(t, l)
|
||||||
tx = restartSession(t, datastore, tx, true)
|
tx = restartSession(t, datastore, tx, true)
|
||||||
|
|
||||||
// LockInfo
|
|
||||||
o, et2, ok, err := tx.FindLock("test1")
|
|
||||||
assert.True(t, ok)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, "owner2", o)
|
|
||||||
assert.Equal(t, et.Second(), et2.Second())
|
|
||||||
tx = restartSession(t, datastore, tx, true)
|
|
||||||
|
|
||||||
// Create a second lock which is actually already expired ...
|
// Create a second lock which is actually already expired ...
|
||||||
l, _, err = tx.Lock("test2", "owner1", -time.Minute, false)
|
l, _, err = tx.Lock("test2", "owner1", -time.Minute, false)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
Loading…
Reference in New Issue
Block a user