123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- package lock
- import (
- "fmt"
- "github.com/ente-io/museum/pkg/repo"
- "github.com/ente-io/stacktrace"
- log "github.com/sirupsen/logrus"
- )
- // LockController exposes functions to obtain locks before entering critical sections
- type LockController struct {
- TaskLockingRepo *repo.TaskLockRepository
- HostName string
- }
- // Try to obtain a lock with the given lockID.
- //
- // Return false if the lock is already taken.
- //
- // A call to this function should be matched by a call to ReleaseLock. A common
- // pattern is to put the ReleaseLock into a defer statement immediately
- // following the lock acquisition.
- //
- // However, it is also fine to omit the release. Such would be useful for cases
- // where we want to ensure the same job cannot run again until the expiry time
- // is past.
- func (c *LockController) TryLock(lockID string, lockUntil int64) bool {
- lockStatus, err := c.TaskLockingRepo.AcquireLock(lockID, lockUntil, c.HostName)
- if err != nil || !lockStatus {
- return false
- }
- return true
- }
- // ExtendLock refreshes an existing lock by updating its locked_at to now and
- // extending its lockUntil.
- //
- // It is only valid to call this method when holding an existing lock previously
- // obtained using TryLock.
- func (c *LockController) ExtendLock(lockID string, lockUntil int64) error {
- foundLock, err := c.TaskLockingRepo.ExtendLock(lockID, lockUntil, c.HostName)
- if err != nil {
- return stacktrace.Propagate(err, "Unable to extend lock %v", lockID)
- }
- if !foundLock {
- return fmt.Errorf("no existing lock for %v", lockID)
- }
- return nil
- }
- // Release a lock that was obtained earlier using TryLock.
- func (c *LockController) ReleaseLock(lockID string) {
- err := c.TaskLockingRepo.ReleaseLock(lockID)
- if err != nil {
- log.Errorf("Error while releasing lock %v: %s", lockID, err)
- }
- }
- func (c *LockController) ReleaseHostLock() {
- count, err := c.TaskLockingRepo.ReleaseLocksBy(c.HostName)
- if err != nil {
- log.Errorf("Error while releasing host lock: %s", err)
- }
- log.Infof("Released %d locks held by %s", *count, c.HostName)
- }
|