Add sync => go-sync
This commit is contained in:
29
sync/lock/redis/pool.go
Normal file
29
sync/lock/redis/pool.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package redis
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/gomodule/redigo/redis"
|
||||
)
|
||||
|
||||
type pool struct {
|
||||
sync.Mutex
|
||||
i int
|
||||
addrs []string
|
||||
}
|
||||
|
||||
func (p *pool) Get() redis.Conn {
|
||||
for i := 0; i < 3; i++ {
|
||||
p.Lock()
|
||||
addr := p.addrs[p.i%len(p.addrs)]
|
||||
p.i++
|
||||
p.Unlock()
|
||||
|
||||
c, err := redis.Dial("tcp", addr)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
94
sync/lock/redis/redis.go
Normal file
94
sync/lock/redis/redis.go
Normal file
@@ -0,0 +1,94 @@
|
||||
// Package redis is a redis implemenation of lock
|
||||
package redis
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-redsync/redsync"
|
||||
"github.com/micro/go-micro/sync/lock"
|
||||
)
|
||||
|
||||
type redisLock struct {
|
||||
sync.Mutex
|
||||
|
||||
locks map[string]*redsync.Mutex
|
||||
opts lock.Options
|
||||
c *redsync.Redsync
|
||||
}
|
||||
|
||||
func (r *redisLock) Acquire(id string, opts ...lock.AcquireOption) error {
|
||||
var options lock.AcquireOptions
|
||||
for _, o := range opts {
|
||||
o(&options)
|
||||
}
|
||||
|
||||
var ropts []redsync.Option
|
||||
|
||||
if options.Wait > time.Duration(0) {
|
||||
ropts = append(ropts, redsync.SetRetryDelay(options.Wait))
|
||||
ropts = append(ropts, redsync.SetTries(1))
|
||||
}
|
||||
|
||||
if options.TTL > time.Duration(0) {
|
||||
ropts = append(ropts, redsync.SetExpiry(options.TTL))
|
||||
}
|
||||
|
||||
m := r.c.NewMutex(r.opts.Prefix+id, ropts...)
|
||||
err := m.Lock()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r.Lock()
|
||||
r.locks[id] = m
|
||||
r.Unlock()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *redisLock) Release(id string) error {
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
m, ok := r.locks[id]
|
||||
if !ok {
|
||||
return errors.New("lock not found")
|
||||
}
|
||||
|
||||
unlocked := m.Unlock()
|
||||
delete(r.locks, id)
|
||||
|
||||
if !unlocked {
|
||||
return errors.New("lock not unlocked")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *redisLock) String() string {
|
||||
return "redis"
|
||||
}
|
||||
|
||||
func NewLock(opts ...lock.Option) lock.Lock {
|
||||
var options lock.Options
|
||||
for _, o := range opts {
|
||||
o(&options)
|
||||
}
|
||||
|
||||
nodes := options.Nodes
|
||||
|
||||
if len(nodes) == 0 {
|
||||
nodes = []string{"127.0.0.1:6379"}
|
||||
}
|
||||
|
||||
rpool := redsync.New([]redsync.Pool{&pool{
|
||||
addrs: nodes,
|
||||
}})
|
||||
|
||||
return &redisLock{
|
||||
locks: make(map[string]*redsync.Mutex),
|
||||
opts: options,
|
||||
c: rpool,
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user