-
Notifications
You must be signed in to change notification settings - Fork 0
/
util-nmutex.go
72 lines (59 loc) · 1.17 KB
/
util-nmutex.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/*
* Copyright (c) 2023.
* Created by Andy Pangaribuan <https://github.com/apangaribuan>.
* All Rights Reserved.
*/
package util
import (
"time"
"github.com/andypangaribuan/project9/abs"
"github.com/viney-shih/go-lock"
)
func (slf *srUtil) NewNMutex(max int) abs.UtilNMutex {
return &srNMutex{
sr: slf,
mux: lock.NewChanMutex(),
max: max,
keys: make(map[string]interface{}, 0),
}
}
func (slf *srNMutex) getTimeout() time.Duration {
return slf.sr.GetRandomDuration(1, 500, time.Microsecond)
}
func (slf *srNMutex) sleep() {
time.Sleep(slf.getTimeout())
}
func (slf *srNMutex) Lock(key string, totalTry ...int) (locked bool) {
n := 1
if len(totalTry) > 0 {
n = totalTry[0]
if n < 1 {
n = 1
}
}
for i := 0; i < n; i++ {
locked = slf.doLock(key)
if locked {
break
}
}
return
}
func (slf *srNMutex) doLock(key string) (locked bool) {
locked = slf.mux.TryLockWithTimeout(slf.getTimeout())
if !locked {
return
}
defer slf.mux.Unlock()
if len(slf.keys) >= slf.max {
slf.sleep()
return false
}
slf.keys[key] = nil
return true
}
func (slf *srNMutex) Unlock(key string) {
slf.mux.Lock()
defer slf.mux.Unlock()
delete(slf.keys, key)
}