Skip to content

Commit

Permalink
database: remove FindLock()
Browse files Browse the repository at this point in the history
  • Loading branch information
jzelinskie committed Jan 10, 2019
1 parent 45ecf18 commit 399deab
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 65 deletions.
17 changes: 5 additions & 12 deletions database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,23 +183,16 @@ type Session interface {
// FindKeyValue retrieves a value from the given key.
FindKeyValue(key string) (value string, found bool, err error)

// Lock creates or renew a Lock in the database with the given name, owner
// and duration.
// Lock acquires or renews a lock in the database with the given name, owner
// 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
// unlocked, and thus, let other users create a Lock with the same name.
// 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.
// If the acquisition of a lock is not successful, expiration should be
// the time that existing lock expires.
Lock(name string, owner string, duration time.Duration, renew bool) (success bool, expiration time.Time, err error)

// Unlock releases an existing Lock.
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
Expand Down
22 changes: 0 additions & 22 deletions database/dbutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
package database

import (
"errors"
"time"

"github.com/deckarep/golang-set"
Expand Down Expand Up @@ -351,24 +350,3 @@ func ReleaseLock(datastore Datastore, name, owner string) {
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 changes: 4 additions & 21 deletions database/pgsql/lock.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (

const (
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`
removeLock = `DELETE FROM Lock WHERE name = $1 AND owner = $2`
removeLockExpired = `DELETE FROM LOCK WHERE until < CURRENT_TIMESTAMP`
Expand Down Expand Up @@ -67,7 +67,9 @@ func (tx *pgSession) Lock(name string, owner string, duration time.Duration, ren
_, err := tx.Exec(soiLock, name, owner, until)
if err != nil {
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)
}
Expand All @@ -86,25 +88,6 @@ func (tx *pgSession) Unlock(name, owner string) error {
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
func (tx *pgSession) pruneLocks() error {
defer observeQueryTime("pruneLocks", "all", time.Now())
Expand Down
11 changes: 1 addition & 10 deletions database/pgsql/lock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ func TestLock(t *testing.T) {
defer datastore.Close()

var l bool
var et time.Time

// Create a first lock.
l, _, err := tx.Lock("test1", "owner1", time.Minute, false)
Expand Down Expand Up @@ -62,19 +61,11 @@ func TestLock(t *testing.T) {
assert.Nil(t, err)
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.True(t, l)
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 ...
l, _, err = tx.Lock("test2", "owner1", -time.Minute, false)
assert.Nil(t, err)
Expand Down

0 comments on commit 399deab

Please sign in to comment.