migrate from github
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
package lock
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/XingfenD/yoresee_doc/pkg/errs"
|
||||
"github.com/XingfenD/yoresee_doc/pkg/storage"
|
||||
)
|
||||
|
||||
// distributed lock, depredated by usage of singleflight
|
||||
type DistributedLock struct {
|
||||
key string
|
||||
value string
|
||||
expiration time.Duration
|
||||
}
|
||||
|
||||
func NewDistributedLock(key string, expiration time.Duration) *DistributedLock {
|
||||
return &DistributedLock{
|
||||
key: key,
|
||||
value: fmt.Sprintf("%d", time.Now().UnixNano()),
|
||||
expiration: expiration,
|
||||
}
|
||||
}
|
||||
|
||||
func (dl *DistributedLock) Lock(ctx context.Context) error {
|
||||
success, err := storage.SetNX(ctx, dl.key, dl.value, dl.expiration)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !success {
|
||||
return errs.Detail(errs.ErrLockAcquireFailed, dl.key)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dl *DistributedLock) TryLock(ctx context.Context) (bool, error) {
|
||||
return storage.SetNX(ctx, dl.key, dl.value, dl.expiration)
|
||||
}
|
||||
|
||||
func (dl *DistributedLock) Unlock(ctx context.Context) error {
|
||||
script := `
|
||||
if redis.call("get", KEYS[1]) == ARGV[1] then
|
||||
return redis.call("del", KEYS[1])
|
||||
else
|
||||
return 0
|
||||
end
|
||||
`
|
||||
result, err := storage.GetRedis().Eval(ctx, script, []string{dl.key}, dl.value).Result()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if result.(int64) == 0 {
|
||||
return errs.Detail(errs.ErrLockNotHeld, dl.key)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user