|
@ -7,6 +7,11 @@ import ( |
|
|
"time" |
|
|
"time" |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
var LockErrorNonEmptyTokenOnNewLock = fmt.Errorf("lock: non-empty token on a new lock") |
|
|
|
|
|
var LockErrorNonEmptyTokenOnExpiredLock = fmt.Errorf("lock: non-empty token on an expired lock") |
|
|
|
|
|
var LockErrorTokenMismatch = fmt.Errorf("lock: token mismatch") |
|
|
|
|
|
var UnlockErrorTokenMismatch = fmt.Errorf("unlock: token mismatch") |
|
|
|
|
|
|
|
|
// LockManager lock manager
|
|
|
// LockManager lock manager
|
|
|
type LockManager struct { |
|
|
type LockManager struct { |
|
|
locks *xsync.MapOf[string, *Lock] |
|
|
locks *xsync.MapOf[string, *Lock] |
|
@ -31,7 +36,7 @@ func (lm *LockManager) Lock(path string, expiredAtNs int64, token string) (renew |
|
|
if oldValue.ExpiredAtNs > 0 && oldValue.ExpiredAtNs < time.Now().UnixNano() { |
|
|
if oldValue.ExpiredAtNs > 0 && oldValue.ExpiredAtNs < time.Now().UnixNano() { |
|
|
// lock is expired, set to a new lock
|
|
|
// lock is expired, set to a new lock
|
|
|
if token != "" { |
|
|
if token != "" { |
|
|
err = fmt.Errorf("lock: non-empty token on an expired lock") |
|
|
|
|
|
|
|
|
err = LockErrorNonEmptyTokenOnExpiredLock |
|
|
return nil, false |
|
|
return nil, false |
|
|
} else { |
|
|
} else { |
|
|
// new lock
|
|
|
// new lock
|
|
@ -45,7 +50,7 @@ func (lm *LockManager) Lock(path string, expiredAtNs int64, token string) (renew |
|
|
renewToken = uuid.New().String() |
|
|
renewToken = uuid.New().String() |
|
|
return &Lock{Token: renewToken, ExpiredAtNs: expiredAtNs}, false |
|
|
return &Lock{Token: renewToken, ExpiredAtNs: expiredAtNs}, false |
|
|
} else { |
|
|
} else { |
|
|
err = fmt.Errorf("lock: token mismatch") |
|
|
|
|
|
|
|
|
err = LockErrorTokenMismatch |
|
|
return oldValue, false |
|
|
return oldValue, false |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
@ -54,7 +59,7 @@ func (lm *LockManager) Lock(path string, expiredAtNs int64, token string) (renew |
|
|
renewToken = uuid.New().String() |
|
|
renewToken = uuid.New().String() |
|
|
return &Lock{Token: renewToken, ExpiredAtNs: expiredAtNs}, false |
|
|
return &Lock{Token: renewToken, ExpiredAtNs: expiredAtNs}, false |
|
|
} else { |
|
|
} else { |
|
|
err = fmt.Errorf("lock: non-empty token on a new lock") |
|
|
|
|
|
|
|
|
err = LockErrorNonEmptyTokenOnNewLock |
|
|
return nil, false |
|
|
return nil, false |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -79,7 +84,7 @@ func (lm *LockManager) Unlock(path string, token string) (isUnlocked bool, err e |
|
|
return oldValue, false |
|
|
return oldValue, false |
|
|
} else { |
|
|
} else { |
|
|
isUnlocked = false |
|
|
isUnlocked = false |
|
|
err = fmt.Errorf("unlock: token mismatch") |
|
|
|
|
|
|
|
|
err = UnlockErrorTokenMismatch |
|
|
return oldValue, false |
|
|
return oldValue, false |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|