66 "fmt"
77 "time"
88
9+ "github.com/golangid/candi/options"
910 "github.com/gomodule/redigo/redis"
1011)
1112
@@ -15,39 +16,37 @@ type (
1516 // RedisLocker lock using redis
1617 RedisLocker struct {
1718 pool * redis.Pool
18- lockeroptions LockerOptions
19+ lockeroptions options. LockerOptions
1920 }
2021
2122 // NoopLocker empty locker
2223 NoopLocker struct {}
23-
24- // Options for RedisLocker
25- LockerOptions struct {
26- Prefix string
27- TTL time.Duration
28- }
29-
30- // Option function type for setting options
31- LockerOption func (* LockerOptions )
3224)
3325
3426// WithPrefix sets the prefix for keys
35- func WithPrefixLocker (prefix string ) LockerOption {
36- return func (o * LockerOptions ) {
27+ func WithPrefixLocker (prefix string ) options. LockerOption {
28+ return func (o * options. LockerOptions ) {
3729 o .Prefix = prefix
3830 }
3931}
4032
4133// WithTTL sets the default TTL for keys
42- func WithTTLLocker (ttl time.Duration ) LockerOption {
43- return func (o * LockerOptions ) {
34+ func WithTTLLocker (ttl time.Duration ) options. LockerOption {
35+ return func (o * options. LockerOptions ) {
4436 o .TTL = ttl
4537 }
4638}
4739
40+ // WithLimit sets the limit for keys
41+ func WithLimitLocker (limit int ) options.LockerOption {
42+ return func (o * options.LockerOptions ) {
43+ o .Limit = limit
44+ }
45+ }
46+
4847// NewRedisLocker constructor
49- func NewRedisLocker (pool * redis.Pool , opts ... LockerOption ) * RedisLocker {
50- lockeroptions := LockerOptions {
48+ func NewRedisLocker (pool * redis.Pool , opts ... options. LockerOption ) * RedisLocker {
49+ lockeroptions := options. LockerOptions {
5150 Prefix : "LOCKFOR" ,
5251 TTL : 0 ,
5352 }
@@ -104,31 +103,26 @@ func (r *RedisLocker) IsLockedTTL(key string, TTL time.Duration) bool {
104103 return incr > 1
105104}
106105
107- // IsLockedTTLWithLimit checks if the key has been incremented more than the specified limit
108- // within the given TTL. If the key is being created for the first time, it sets the TTL.
109- // Example usage: check if a key has been incremented more than 10 times within 1 minute.
110- func (r * RedisLocker ) IsLockedTTLWithLimit (key string , limit int , TTL time.Duration ) bool {
106+ func (r * RedisLocker ) IsLockedWithOpts (key string , opts ... options.LockerOption ) bool {
111107 conn := r .pool .Get ()
112108 defer conn .Close ()
113109
110+ lockOpt := r .lockeroptions
111+ for _ , opt := range opts {
112+ opt (& lockOpt )
113+ }
114+
114115 lockKey := fmt .Sprintf ("%s:%s" , r .lockeroptions .Prefix , key )
115116 incr , err := redis .Int64 (conn .Do ("INCR" , lockKey ))
116117 if err != nil {
117118 return false
118119 }
119120
120- var expireTime time.Duration
121- if TTL > 0 {
122- expireTime = TTL
123- } else {
124- expireTime = r .lockeroptions .TTL
125- }
126-
127- if expireTime > 0 && incr == 1 {
128- conn .Do ("EXPIRE" , lockKey , int (expireTime .Seconds ()))
121+ withLimit := lockOpt .Limit > 1
122+ if lockOpt .TTL > 0 && ! (withLimit && incr == 1 ) {
123+ conn .Do ("EXPIRE" , lockKey , int (lockOpt .TTL .Seconds ()))
129124 }
130-
131- return incr > int64 (limit )
125+ return incr > int64 (lockOpt .Limit )
132126}
133127
134128func (r * RedisLocker ) HasBeenLocked (key string ) bool {
@@ -242,6 +236,9 @@ func (NoopLocker) IsLocked(string) bool { return false }
242236// IsLockedTTL method
243237func (NoopLocker ) IsLockedTTL (string , time.Duration ) bool { return false }
244238
239+ // IsLockedWithOpts method
240+ func (NoopLocker ) IsLockedWithOpts (string , ... options.LockerOption ) bool { return false }
241+
245242// HasBeenLocked method
246243func (NoopLocker ) HasBeenLocked (string ) bool { return false }
247244
@@ -254,13 +251,10 @@ func (NoopLocker) Reset(string) {}
254251// Lock method
255252func (NoopLocker ) Lock (string , time.Duration ) (func (), error ) { return func () {}, nil }
256253
257- func (NoopLocker ) Disconnect (context.Context ) error { return nil }
258-
259254// GetPrefix method
260255func (NoopLocker ) GetPrefixLocker () string { return "" }
261256
262257// GetTTLLocker method
263258func (NoopLocker ) GetTTLLocker () time.Duration { return 0 }
264259
265- // IsLockedTTLWithLimit method
266- func (NoopLocker ) IsLockedTTLWithLimit (string , int , time.Duration ) bool { return false }
260+ func (NoopLocker ) Disconnect (context.Context ) error { return nil }
0 commit comments