Skip to content

Commit

Permalink
Upgrade package to v3, adding some API changes.
Browse files Browse the repository at this point in the history
- Add context to lock constructor.
- Support kv cache options.
  • Loading branch information
amyangfei committed Jun 15, 2022
1 parent c44afdc commit a5fc556
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 97 deletions.
41 changes: 22 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,17 @@ go mod init github.com/<user>/<repo>
And then install this library via go get

```bash
go get github.com/amyangfei/redlock-go/v2
go get github.com/amyangfei/redlock-go/v3
```

## Usage

To create a lock manager:

```golang
lockMgr, err := redlock.NewRedLock([]string{
lockMgr, err := redlock.NewRedLock(
ctx,
[]string{
"tcp://127.0.0.1:6379",
"tcp://127.0.0.1:6380",
"tcp://127.0.0.1:6381",
Expand All @@ -37,7 +39,7 @@ lockMgr, err := redlock.NewRedLock([]string{
To acquire a lock:

```golang
import "github.com/amyangfei/redlock-go/v2/redlock"
import "github.com/amyangfei/redlock-go/v3/redlock"

ctx := context.Background()
expirity, err := lockMgr.Lock(ctx, "resource_name", 200*time.Milliseconds)
Expand All @@ -51,7 +53,7 @@ otherwise an expirity larger than zero is returned representing the number of mi
To release a lock:

```golang
import "github.com/amyangfei/redlock-go/v2/redlock"
import "github.com/amyangfei/redlock-go/v3/redlock"

ctx := context.Background()
err := lockMgr.UnLock(ctx, "resource_name")
Expand All @@ -66,32 +68,33 @@ A KV cache is used for local lock item query, currently this library provides tw
#### map based cache

```golang
import "github.com/amyangfei/redlock-go/v2/redlock"
import "github.com/amyangfei/redlock-go/v3/redlock"

lock, err := redlock.NewRedLock([]string{
lock, err := redlock.NewRedLock(
ctx,
[]string{
"tcp://127.0.0.1:6379",
"tcp://127.0.0.1:6380",
"tcp://127.0.0.1:6381",
})
opts := map[string]interface{}{
redlock.OptDisableGC: false,
redlock.OptGCInterval: "1m",
}
lock.SetCache(redlock.CacheTypeSimple, opts)
},
WithCacheType(redlock.CacheTypeSimple),
WithCacheDisableGC(false),
WithGCInterval(time.Minute),
)
```

#### freecache based cache

```golang
import "github.com/amyangfei/redlock-go/v2/redlock"
import "github.com/amyangfei/redlock-go/v3/redlock"

lock, err := redlock.NewRedLock([]string{
lock, err := redlock.NewRedLock(
ctx,
[]string{
"tcp://127.0.0.1:6379",
"tcp://127.0.0.1:6380",
"tcp://127.0.0.1:6381",
})
opts := map[string]interface{}{
redlock.OptCacheSize: 10*1024*1024, // 10 Megabytes
}
lock.SetCache(redlock.CacheTypeFreeCache, opts)
},
WithCacheSize(10*1024*1024), // 10 Megabytes
)
```
15 changes: 8 additions & 7 deletions _examples/basic.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,22 @@ import (
"fmt"
"time"

"github.com/amyangfei/redlock-go/v2/redlock"
"github.com/amyangfei/redlock-go/v3/redlock"
)

func main() {
lock, err := redlock.NewRedLock([]string{
"tcp://127.0.0.1:6379",
"tcp://127.0.0.1:6380",
"tcp://127.0.0.1:6381",
})
ctx := context.Background()
lock, err := redlock.NewRedLock(
ctx, []string{
"tcp://127.0.0.1:6379",
"tcp://127.0.0.1:6380",
"tcp://127.0.0.1:6381",
})

if err != nil {
panic(err)
}

ctx := context.Background()
expiry, err := lock.Lock(ctx, "foo", 200*time.Millisecond)
if err != nil {
fmt.Println(err)
Expand Down
14 changes: 8 additions & 6 deletions _examples/counter.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"strings"
"time"

"github.com/amyangfei/redlock-go/v2/redlock"
"github.com/amyangfei/redlock-go/v3/redlock"
)

const (
Expand All @@ -17,11 +17,13 @@ const (

func writer(count int, back chan string) {
ctx := context.Background()
lock, err := redlock.NewRedLock([]string{
"tcp://127.0.0.1:6379",
"tcp://127.0.0.1:6380",
"tcp://127.0.0.1:6381",
})
lock, err := redlock.NewRedLock(
ctx,
[]string{
"tcp://127.0.0.1:6379",
"tcp://127.0.0.1:6380",
"tcp://127.0.0.1:6381",
})

if err != nil {
panic(err)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/amyangfei/redlock-go/v2
module github.com/amyangfei/redlock-go/v3

go 1.15

Expand Down
8 changes: 0 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,11 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/go-redis/redis/v8 v8.4.4 h1:fGqgxCTR1sydaKI00oQf3OmkU/DIe/I/fYXvGklCIuc=
github.com/go-redis/redis/v8 v8.4.4/go.mod h1:nA0bQuF0i5JFx4Ta9RZxGKXFrQ8cRWntra97f0196iY=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
Expand All @@ -31,7 +29,6 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
Expand Down Expand Up @@ -59,15 +56,12 @@ go.opentelemetry.io/otel v0.15.0 h1:CZFy2lPhxd4HlhZnYK8gRyDotksO3Ip9rBweY1vVYJw=
go.opentelemetry.io/otel v0.15.0/go.mod h1:e4GKElweB8W2gWUqbghw0B8t5MCTccc9212eNHnOHwA=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand All @@ -78,7 +72,6 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
Expand All @@ -96,7 +89,6 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
Expand Down
93 changes: 61 additions & 32 deletions redlock/kvcache.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,51 @@ const (
CacheTypeFreeCache = "freecache"
)

// kv cache options
const (
OptDisableGC = "opt-disable-gc"
OptGCInterval = "opt-gc-interval"
OptCacheSize = "opt-cache-size"
)
// CacheOptions defines optional parameters for configuring kv cache.
type CacheOptions struct {
CacheType string
DisableGC bool
GCInterval time.Duration
CacheSize int
}

var defaultCacheOptions = &CacheOptions{
CacheType: CacheTypeSimple,
DisableGC: false,
GCInterval: time.Minute,
CacheSize: 10 * 1024 * 1024,
}

// CacheOption alias to the function that can be used to configure CacheOptions
type CacheOption func(*CacheOptions)

// WithCacheType sets CacheType to CacheOptions
func WithCacheType(tp string) CacheOption {
return func(o *CacheOptions) {
o.CacheType = tp
}
}

// WithDisableGC sets DisableGC to CacheOptions
func WithDisableGC(disabled bool) CacheOption {
return func(o *CacheOptions) {
o.DisableGC = disabled
}
}

// WithGCInterval sets GCInterval of CacheOptions
func WithGCInterval(interval time.Duration) CacheOption {
return func(o *CacheOptions) {
o.GCInterval = interval
}
}

// WithCacheSize sets CacheSize of CacheOptions
func WithCacheSize(size int) CacheOption {
return func(o *CacheOptions) {
o.CacheSize = size
}
}

// LockElem keeps a lock element
type LockElem struct {
Expand Down Expand Up @@ -50,14 +89,19 @@ type KVCache interface {
}

// NewCacheImpl returns a KVCache implementation based on given cache type
func NewCacheImpl(cacheType string, opts map[string]interface{}) KVCache {
switch cacheType {
func NewCacheImpl(ctx context.Context, opts ...CacheOption) KVCache {
options := new(CacheOptions)
*options = *defaultCacheOptions
for _, opt := range opts {
opt(options)
}
switch options.CacheType {
case CacheTypeFreeCache:
return NewFreeCache(opts)
return NewFreeCache(options)
case CacheTypeSimple:
fallthrough
default:
return NewSimpleCache(opts)
return NewSimpleCache(ctx, options)
}
}

Expand All @@ -68,24 +112,13 @@ type SimpleCache struct {
}

// NewSimpleCache creates a new SimpleCache object
func NewSimpleCache(opts map[string]interface{}) *SimpleCache {
func NewSimpleCache(ctx context.Context, options *CacheOptions) *SimpleCache {
c := &SimpleCache{
kvs: make(map[string]*LockElem),
}
gcInterval := time.Minute
disableAutoGC := false
if v, ok := opts[OptDisableGC].(bool); ok {
disableAutoGC = v
}
if !disableAutoGC {
if v, ok := opts[OptGCInterval].(string); ok {
dur, err := time.ParseDuration(v)
if err == nil {
gcInterval = dur
}
}
go func(ctx context.Context) {
ticker := time.NewTicker(gcInterval)
if !options.DisableGC {
go func() {
ticker := time.NewTicker(options.GCInterval)
defer ticker.Stop()
for {
select {
Expand All @@ -95,7 +128,7 @@ func NewSimpleCache(opts map[string]interface{}) *SimpleCache {
c.gc()
}
}
}(context.Background())
}()
}
return c
}
Expand Down Expand Up @@ -154,13 +187,9 @@ type FreeCache struct {
}

// NewFreeCache returns a new FreeCache instance
func NewFreeCache(opts map[string]interface{}) *FreeCache {
cacheSize := 10 * 1024 * 1024
if v, ok := opts[OptCacheSize].(int); ok {
cacheSize = v
}
func NewFreeCache(options *CacheOptions) *FreeCache {
return &FreeCache{
c: freecache.NewCache(cacheSize),
c: freecache.NewCache(options.CacheSize),
}
}

Expand Down
20 changes: 12 additions & 8 deletions redlock/kvcache_test.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
package redlock

import (
"context"
"testing"
"time"

"github.com/stretchr/testify/assert"
)

func TestSimpleCache(t *testing.T) {
opts := map[string]interface{}{
OptDisableGC: true,
ctx := context.Background()
opts := &CacheOptions{
DisableGC: true,
}
cache := NewSimpleCache(opts)
cache := NewSimpleCache(ctx, opts)

var (
key = "test_key"
Expand Down Expand Up @@ -53,9 +55,11 @@ func TestSimpleCache(t *testing.T) {
assert.Zero(t, cache.Size())

// test auto gc
opts[OptDisableGC] = false
opts[OptGCInterval] = "1s"
cache = NewSimpleCache(opts)
opts = &CacheOptions{
DisableGC: false,
GCInterval: time.Second,
}
cache = NewSimpleCache(ctx, opts)
elem, err = cache.Set(key, val, shortExpiry)
assert.Nil(t, err)
assert.Equal(t, elem.Val, val)
Expand All @@ -73,8 +77,8 @@ func TestFreeCache(t *testing.T) {
err error
)

opts := map[string]interface{}{
OptCacheSize: 1024 * 1024,
opts := &CacheOptions{
CacheSize: 1024 * 1024,
}
cache := NewFreeCache(opts)

Expand Down
Loading

0 comments on commit a5fc556

Please sign in to comment.