-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add RedLock && release new version v1.0.0
- Loading branch information
panjiangming
committed
Aug 3, 2023
1 parent
78c573c
commit ca1b43f
Showing
8 changed files
with
221 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,18 @@ | ||
package rlock | ||
|
||
import "time" | ||
|
||
type RedisClientOptions struct { | ||
Addr string // redis address | ||
Password string // redis password | ||
} | ||
|
||
type lockOptions struct { | ||
blockWaitingSecond int64 // blocking timeout time | ||
expireSeconds int64 // key expire time | ||
watchdogSwitch bool // watchdog on/off | ||
blockWaitingTime time.Duration // blocking timeout time, default 60s. | ||
expireTime time.Duration // key expire time, default 30s. | ||
watchdogSwitch bool // watchdog on/off, default false. | ||
} | ||
|
||
type redLockOptions struct { | ||
maxSingleNodeWaitTime time.Duration // max try lock wait time. | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,67 @@ | ||
package rlock | ||
|
||
import ( | ||
"errors" | ||
"time" | ||
|
||
"github.com/pjimming/rlock/utils" | ||
) | ||
|
||
type RedLock struct { | ||
locks []*RLock | ||
redLockOptions | ||
} | ||
|
||
// NewRedLock new a RedLock from multi redis servers. | ||
// | ||
// It is required that the cumulative timeout threshold of all nodes is | ||
// less than one-tenth of the distributed lock expiration time. | ||
func NewRedLock(ops []RedisClientOptions, key string, expireTime time.Duration) (redLock *RedLock, err error) { | ||
if key == "" { | ||
key = utils.GenerateRandomString(10) | ||
} | ||
|
||
for _, op := range ops { | ||
rlock := NewRLock(op, key) | ||
|
||
if rlock != nil { | ||
redLock.locks = append(redLock.locks, rlock. | ||
SetToken(key+"_token"). | ||
SetWatchdogSwitch(true). | ||
SetExpireTime(expireTime)) | ||
} | ||
} | ||
|
||
if len(redLock.locks) < 3 { | ||
return nil, errors.New("new redlock fail, locks count less than 3") | ||
} | ||
|
||
redLock.maxSingleNodeWaitTime = expireTime / time.Duration(10*len(redLock.locks)) | ||
|
||
return | ||
} | ||
|
||
// TryLock try to acquire lock. | ||
// | ||
// If RedLock gets lock count greater than half of locks, | ||
// it means acquire lock successfully. | ||
func (l *RedLock) TryLock() bool { | ||
successCnt := 0 | ||
for _, lock := range l.locks { | ||
start := time.Now() | ||
ttl := lock.TryLock() | ||
cost := time.Since(start) | ||
if ttl == int64(0) && cost <= l.maxSingleNodeWaitTime { | ||
successCnt++ | ||
} | ||
} | ||
|
||
return successCnt >= (len(l.locks)>>1 + 1) | ||
} | ||
|
||
// UnLock release lock. | ||
func (l *RedLock) UnLock() { | ||
for _, lock := range l.locks { | ||
lock.UnLock() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.