mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-27 12:46:03 +01:00
Include go-redsync v1.0.1 in vendor
This commit is contained in:
parent
e9b656ce79
commit
ea38b7eefe
8
src/Gopkg.lock
generated
8
src/Gopkg.lock
generated
@ -120,6 +120,12 @@
|
|||||||
revision = "47dc60e71eed504e3ef8e77ee3c6fe720f3be57f"
|
revision = "47dc60e71eed504e3ef8e77ee3c6fe720f3be57f"
|
||||||
version = "v1.3.0"
|
version = "v1.3.0"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/go-redsync/redsync"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "98dabdf1c8574561bf976911c14ff652c47b1ddf"
|
||||||
|
version = "v1.0.1"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/go-sql-driver/mysql"
|
name = "github.com/go-sql-driver/mysql"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
@ -258,6 +264,6 @@
|
|||||||
[solve-meta]
|
[solve-meta]
|
||||||
analyzer-name = "dep"
|
analyzer-name = "dep"
|
||||||
analyzer-version = 1
|
analyzer-version = 1
|
||||||
inputs-digest = "1b5bec4304c99684de7fddc82ce9c81788e945f82455125110f32441a6ffd4cc"
|
inputs-digest = "49328284c14629d33811bc9d67012a48314bb52bbb4ad7282699afbd4506f287"
|
||||||
solver-name = "gps-cdcl"
|
solver-name = "gps-cdcl"
|
||||||
solver-version = 1
|
solver-version = 1
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
# [[override]]
|
# [[override]]
|
||||||
# name = "github.com/x/y"
|
# name = "github.com/x/y"
|
||||||
# version = "2.4.0"
|
# version = "2.4.0"
|
||||||
|
ignored = ["github.com/vmware/harbor"]
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/astaxie/beego"
|
name = "github.com/astaxie/beego"
|
||||||
@ -55,3 +55,7 @@
|
|||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/stretchr/testify"
|
name = "github.com/stretchr/testify"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/go-redsync/redsync"
|
||||||
|
version = "1.0.1"
|
||||||
|
24
src/vendor/github.com/go-redsync/redsync/.gitlab-ci.yml
generated
vendored
Normal file
24
src/vendor/github.com/go-redsync/redsync/.gitlab-ci.yml
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
before_script:
|
||||||
|
- mkdir -p $GOPATH/src/github.com/redsync
|
||||||
|
- ln -s $CI_PROJECT_DIR $GOPATH/src/github.com/redsync/redsync
|
||||||
|
- cd $GOPATH/src/github.com/redsync/redsync
|
||||||
|
- apt-get update
|
||||||
|
- apt-get -y install redis-server
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- build
|
||||||
|
- test
|
||||||
|
|
||||||
|
build-go-1.5:
|
||||||
|
image: golang:1.5
|
||||||
|
stage: build
|
||||||
|
script:
|
||||||
|
- go get -v
|
||||||
|
- go build -v
|
||||||
|
|
||||||
|
test-go-1.5:
|
||||||
|
image: golang:1.5
|
||||||
|
stage: test
|
||||||
|
script:
|
||||||
|
- go get -v -t
|
||||||
|
- go test -v
|
27
src/vendor/github.com/go-redsync/redsync/LICENSE
generated
vendored
Normal file
27
src/vendor/github.com/go-redsync/redsync/LICENSE
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) 2016, Mahmud Ridwan
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the Redsync nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
src/vendor/github.com/go-redsync/redsync/README.md
generated
vendored
Normal file
29
src/vendor/github.com/go-redsync/redsync/README.md
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Redsync
|
||||||
|
|
||||||
|
[![Build Status](https://drone.io/github.com/go-redsync/redsync/status.png)](https://drone.io/github.com/go-redsync/redsync/latest)
|
||||||
|
|
||||||
|
Redsync provides a Redis-based distributed mutual exclusion lock implementation for Go as described in [this post](http://redis.io/topics/distlock). A reference library (by [antirez](https://github.com/antirez)) for Ruby is available at [github.com/antirez/redlock-rb](https://github.com/antirez/redlock-rb).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Install Redsync using the go get command:
|
||||||
|
|
||||||
|
$ go get gopkg.in/redsync.v1
|
||||||
|
|
||||||
|
The only dependencies are the Go distribution and [Redigo](github.com/garyburd/redigo).
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
- [Reference](https://godoc.org/gopkg.in/redsync.v1)
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Contributions are welcome.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Redsync is available under the [BSD (3-Clause) License](https://opensource.org/licenses/BSD-3-Clause).
|
||||||
|
|
||||||
|
## Disclaimer
|
||||||
|
|
||||||
|
This code implements an algorithm which is currently a proposal, it was not formally analyzed. Make sure to understand how it works before using it in production environments.
|
1
src/vendor/github.com/go-redsync/redsync/VERSION
generated
vendored
Normal file
1
src/vendor/github.com/go-redsync/redsync/VERSION
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
v1
|
4
src/vendor/github.com/go-redsync/redsync/doc.go
generated
vendored
Normal file
4
src/vendor/github.com/go-redsync/redsync/doc.go
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
// Package redsync provides a Redis-based distributed mutual exclusion lock implementation as described in the post http://redis.io/topics/distlock.
|
||||||
|
//
|
||||||
|
// Values containing the types defined in this package should not be copied.
|
||||||
|
package redsync
|
5
src/vendor/github.com/go-redsync/redsync/error.go
generated
vendored
Normal file
5
src/vendor/github.com/go-redsync/redsync/error.go
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package redsync
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
var ErrFailed = errors.New("redsync: failed to acquire lock")
|
145
src/vendor/github.com/go-redsync/redsync/mutex.go
generated
vendored
Normal file
145
src/vendor/github.com/go-redsync/redsync/mutex.go
generated
vendored
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
package redsync
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/base64"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/garyburd/redigo/redis"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Mutex is a distributed mutual exclusion lock.
|
||||||
|
type Mutex struct {
|
||||||
|
name string
|
||||||
|
expiry time.Duration
|
||||||
|
|
||||||
|
tries int
|
||||||
|
delay time.Duration
|
||||||
|
|
||||||
|
factor float64
|
||||||
|
|
||||||
|
quorum int
|
||||||
|
|
||||||
|
value string
|
||||||
|
until time.Time
|
||||||
|
|
||||||
|
nodem sync.Mutex
|
||||||
|
|
||||||
|
pools []Pool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lock locks m. In case it returns an error on failure, you may retry to acquire the lock by calling this method again.
|
||||||
|
func (m *Mutex) Lock() error {
|
||||||
|
m.nodem.Lock()
|
||||||
|
defer m.nodem.Unlock()
|
||||||
|
|
||||||
|
value, err := m.genValue()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < m.tries; i++ {
|
||||||
|
if i != 0 {
|
||||||
|
time.Sleep(m.delay)
|
||||||
|
}
|
||||||
|
|
||||||
|
start := time.Now()
|
||||||
|
|
||||||
|
n := 0
|
||||||
|
for _, pool := range m.pools {
|
||||||
|
ok := m.acquire(pool, value)
|
||||||
|
if ok {
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
until := time.Now().Add(m.expiry - time.Now().Sub(start) - time.Duration(int64(float64(m.expiry)*m.factor)) + 2*time.Millisecond)
|
||||||
|
if n >= m.quorum && time.Now().Before(until) {
|
||||||
|
m.value = value
|
||||||
|
m.until = until
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for _, pool := range m.pools {
|
||||||
|
m.release(pool, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ErrFailed
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unlock unlocks m and returns the status of unlock. It is a run-time error if m is not locked on entry to Unlock.
|
||||||
|
func (m *Mutex) Unlock() bool {
|
||||||
|
m.nodem.Lock()
|
||||||
|
defer m.nodem.Unlock()
|
||||||
|
|
||||||
|
n := 0
|
||||||
|
for _, pool := range m.pools {
|
||||||
|
ok := m.release(pool, m.value)
|
||||||
|
if ok {
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n >= m.quorum
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extend resets the mutex's expiry and returns the status of expiry extension. It is a run-time error if m is not locked on entry to Extend.
|
||||||
|
func (m *Mutex) Extend() bool {
|
||||||
|
m.nodem.Lock()
|
||||||
|
defer m.nodem.Unlock()
|
||||||
|
|
||||||
|
n := 0
|
||||||
|
for _, pool := range m.pools {
|
||||||
|
ok := m.touch(pool, m.value, int(m.expiry/time.Millisecond))
|
||||||
|
if ok {
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n >= m.quorum
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Mutex) genValue() (string, error) {
|
||||||
|
b := make([]byte, 32)
|
||||||
|
_, err := rand.Read(b)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return base64.StdEncoding.EncodeToString(b), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Mutex) acquire(pool Pool, value string) bool {
|
||||||
|
conn := pool.Get()
|
||||||
|
defer conn.Close()
|
||||||
|
reply, err := redis.String(conn.Do("SET", m.name, value, "NX", "PX", int(m.expiry/time.Millisecond)))
|
||||||
|
return err == nil && reply == "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
var deleteScript = redis.NewScript(1, `
|
||||||
|
if redis.call("GET", KEYS[1]) == ARGV[1] then
|
||||||
|
return redis.call("DEL", KEYS[1])
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
`)
|
||||||
|
|
||||||
|
func (m *Mutex) release(pool Pool, value string) bool {
|
||||||
|
conn := pool.Get()
|
||||||
|
defer conn.Close()
|
||||||
|
status, err := deleteScript.Do(conn, m.name, value)
|
||||||
|
return err == nil && status != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var touchScript = redis.NewScript(1, `
|
||||||
|
if redis.call("GET", KEYS[1]) == ARGV[1] then
|
||||||
|
return redis.call("SET", KEYS[1], ARGV[1], "XX", "PX", ARGV[2])
|
||||||
|
else
|
||||||
|
return "ERR"
|
||||||
|
end
|
||||||
|
`)
|
||||||
|
|
||||||
|
func (m *Mutex) touch(pool Pool, value string, expiry int) bool {
|
||||||
|
conn := pool.Get()
|
||||||
|
defer conn.Close()
|
||||||
|
status, err := redis.String(touchScript.Do(conn, m.name, value, expiry))
|
||||||
|
return err == nil && status != "ERR"
|
||||||
|
}
|
180
src/vendor/github.com/go-redsync/redsync/mutex_test.go
generated
vendored
Normal file
180
src/vendor/github.com/go-redsync/redsync/mutex_test.go
generated
vendored
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
package redsync
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/garyburd/redigo/redis"
|
||||||
|
"github.com/stvp/tempredis"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMutex(t *testing.T) {
|
||||||
|
pools := newMockPools(8)
|
||||||
|
mutexes := newTestMutexes(pools, "test-mutex", 8)
|
||||||
|
orderCh := make(chan int)
|
||||||
|
for i, mutex := range mutexes {
|
||||||
|
go func(i int, mutex *Mutex) {
|
||||||
|
err := mutex.Lock()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Expected err == nil, got %q", err)
|
||||||
|
}
|
||||||
|
defer mutex.Unlock()
|
||||||
|
|
||||||
|
assertAcquired(t, pools, mutex)
|
||||||
|
|
||||||
|
orderCh <- i
|
||||||
|
}(i, mutex)
|
||||||
|
}
|
||||||
|
for range mutexes {
|
||||||
|
<-orderCh
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMutexExtend(t *testing.T) {
|
||||||
|
pools := newMockPools(8)
|
||||||
|
mutexes := newTestMutexes(pools, "test-mutex-extend", 1)
|
||||||
|
mutex := mutexes[0]
|
||||||
|
|
||||||
|
err := mutex.Lock()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Expected err == nil, got %q", err)
|
||||||
|
}
|
||||||
|
defer mutex.Unlock()
|
||||||
|
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
|
||||||
|
expiries := getPoolExpiries(pools, mutex.name)
|
||||||
|
ok := mutex.Extend()
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("Expected ok == true, got %v", ok)
|
||||||
|
}
|
||||||
|
expiries2 := getPoolExpiries(pools, mutex.name)
|
||||||
|
|
||||||
|
for i, expiry := range expiries {
|
||||||
|
if expiry >= expiries2[i] {
|
||||||
|
t.Fatalf("Expected expiries[%d] > expiry, got %d %d", i, expiries2[i], expiry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMutexQuorum(t *testing.T) {
|
||||||
|
pools := newMockPools(4)
|
||||||
|
for mask := 0; mask < 1<<uint(len(pools)); mask++ {
|
||||||
|
mutexes := newTestMutexes(pools, "test-mutex-partial-"+strconv.Itoa(mask), 1)
|
||||||
|
mutex := mutexes[0]
|
||||||
|
mutex.tries = 1
|
||||||
|
|
||||||
|
n := clogPools(pools, mask, mutex)
|
||||||
|
|
||||||
|
if n >= len(pools)/2+1 {
|
||||||
|
err := mutex.Lock()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Expected err == nil, got %q", err)
|
||||||
|
}
|
||||||
|
assertAcquired(t, pools, mutex)
|
||||||
|
} else {
|
||||||
|
err := mutex.Lock()
|
||||||
|
if err != ErrFailed {
|
||||||
|
t.Fatalf("Expected err == %q, got %q", ErrFailed, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newMockPools(n int) []Pool {
|
||||||
|
pools := []Pool{}
|
||||||
|
for _, server := range servers {
|
||||||
|
func(server *tempredis.Server) {
|
||||||
|
pools = append(pools, &redis.Pool{
|
||||||
|
MaxIdle: 3,
|
||||||
|
IdleTimeout: 240 * time.Second,
|
||||||
|
Dial: func() (redis.Conn, error) {
|
||||||
|
return redis.Dial("unix", server.Socket())
|
||||||
|
},
|
||||||
|
TestOnBorrow: func(c redis.Conn, t time.Time) error {
|
||||||
|
_, err := c.Do("PING")
|
||||||
|
return err
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}(server)
|
||||||
|
if len(pools) == n {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pools
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPoolValues(pools []Pool, name string) []string {
|
||||||
|
values := []string{}
|
||||||
|
for _, pool := range pools {
|
||||||
|
conn := pool.Get()
|
||||||
|
value, err := redis.String(conn.Do("GET", name))
|
||||||
|
conn.Close()
|
||||||
|
if err != nil && err != redis.ErrNil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
values = append(values, value)
|
||||||
|
}
|
||||||
|
return values
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPoolExpiries(pools []Pool, name string) []int {
|
||||||
|
expiries := []int{}
|
||||||
|
for _, pool := range pools {
|
||||||
|
conn := pool.Get()
|
||||||
|
expiry, err := redis.Int(conn.Do("PTTL", name))
|
||||||
|
conn.Close()
|
||||||
|
if err != nil && err != redis.ErrNil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
expiries = append(expiries, expiry)
|
||||||
|
}
|
||||||
|
return expiries
|
||||||
|
}
|
||||||
|
|
||||||
|
func clogPools(pools []Pool, mask int, mutex *Mutex) int {
|
||||||
|
n := 0
|
||||||
|
for i, pool := range pools {
|
||||||
|
if mask&(1<<uint(i)) == 0 {
|
||||||
|
n++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
conn := pool.Get()
|
||||||
|
_, err := conn.Do("SET", mutex.name, "foobar")
|
||||||
|
conn.Close()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTestMutexes(pools []Pool, name string, n int) []*Mutex {
|
||||||
|
mutexes := []*Mutex{}
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
mutexes = append(mutexes, &Mutex{
|
||||||
|
name: name,
|
||||||
|
expiry: 8 * time.Second,
|
||||||
|
tries: 32,
|
||||||
|
delay: 500 * time.Millisecond,
|
||||||
|
factor: 0.01,
|
||||||
|
quorum: len(pools)/2 + 1,
|
||||||
|
pools: pools,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return mutexes
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertAcquired(t *testing.T, pools []Pool, mutex *Mutex) {
|
||||||
|
n := 0
|
||||||
|
values := getPoolValues(pools, mutex.name)
|
||||||
|
for _, value := range values {
|
||||||
|
if value == mutex.value {
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if n < mutex.quorum {
|
||||||
|
t.Fatalf("Expected n >= %d, got %d", mutex.quorum, n)
|
||||||
|
}
|
||||||
|
}
|
8
src/vendor/github.com/go-redsync/redsync/redis.go
generated
vendored
Normal file
8
src/vendor/github.com/go-redsync/redsync/redis.go
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package redsync
|
||||||
|
|
||||||
|
import "github.com/garyburd/redigo/redis"
|
||||||
|
|
||||||
|
// A Pool maintains a pool of Redis connections.
|
||||||
|
type Pool interface {
|
||||||
|
Get() redis.Conn
|
||||||
|
}
|
73
src/vendor/github.com/go-redsync/redsync/redsync.go
generated
vendored
Normal file
73
src/vendor/github.com/go-redsync/redsync/redsync.go
generated
vendored
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package redsync
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
// Redsync provides a simple method for creating distributed mutexes using multiple Redis connection pools.
|
||||||
|
type Redsync struct {
|
||||||
|
pools []Pool
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates and returns a new Redsync instance from given Redis connection pools.
|
||||||
|
func New(pools []Pool) *Redsync {
|
||||||
|
return &Redsync{
|
||||||
|
pools: pools,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMutex returns a new distributed mutex with given name.
|
||||||
|
func (r *Redsync) NewMutex(name string, options ...Option) *Mutex {
|
||||||
|
m := &Mutex{
|
||||||
|
name: name,
|
||||||
|
expiry: 8 * time.Second,
|
||||||
|
tries: 32,
|
||||||
|
delay: 500 * time.Millisecond,
|
||||||
|
factor: 0.01,
|
||||||
|
quorum: len(r.pools)/2 + 1,
|
||||||
|
pools: r.pools,
|
||||||
|
}
|
||||||
|
for _, o := range options {
|
||||||
|
o.Apply(m)
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
// An Option configures a mutex.
|
||||||
|
type Option interface {
|
||||||
|
Apply(*Mutex)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OptionFunc is a function that configures a mutex.
|
||||||
|
type OptionFunc func(*Mutex)
|
||||||
|
|
||||||
|
// Apply calls f(mutex)
|
||||||
|
func (f OptionFunc) Apply(mutex *Mutex) {
|
||||||
|
f(mutex)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetExpiry can be used to set the expiry of a mutex to the given value.
|
||||||
|
func SetExpiry(expiry time.Duration) Option {
|
||||||
|
return OptionFunc(func(m *Mutex) {
|
||||||
|
m.expiry = expiry
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTries can be used to set the number of times lock acquire is attempted.
|
||||||
|
func SetTries(tries int) Option {
|
||||||
|
return OptionFunc(func(m *Mutex) {
|
||||||
|
m.tries = tries
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRetryDelay can be used to set the amount of time to wait between retries.
|
||||||
|
func SetRetryDelay(delay time.Duration) Option {
|
||||||
|
return OptionFunc(func(m *Mutex) {
|
||||||
|
m.delay = delay
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDriftFactor can be used to set the clock drift factor.
|
||||||
|
func SetDriftFactor(factor float64) Option {
|
||||||
|
return OptionFunc(func(m *Mutex) {
|
||||||
|
m.factor = factor
|
||||||
|
})
|
||||||
|
}
|
38
src/vendor/github.com/go-redsync/redsync/redsync_test.go
generated
vendored
Normal file
38
src/vendor/github.com/go-redsync/redsync/redsync_test.go
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package redsync
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stvp/tempredis"
|
||||||
|
)
|
||||||
|
|
||||||
|
var servers []*tempredis.Server
|
||||||
|
|
||||||
|
func TestMain(m *testing.M) {
|
||||||
|
for i := 0; i < 8; i++ {
|
||||||
|
server, err := tempredis.Start(tempredis.Config{})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
servers = append(servers, server)
|
||||||
|
}
|
||||||
|
result := m.Run()
|
||||||
|
for _, server := range servers {
|
||||||
|
server.Term()
|
||||||
|
}
|
||||||
|
os.Exit(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRedsync(t *testing.T) {
|
||||||
|
pools := newMockPools(8)
|
||||||
|
rs := New(pools)
|
||||||
|
|
||||||
|
mutex := rs.NewMutex("test-redsync")
|
||||||
|
err := mutex.Lock()
|
||||||
|
if err != nil {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
assertAcquired(t, pools, mutex)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user