/
lock.go
63 lines (54 loc) · 1.12 KB
/
lock.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
package transport
import (
"time"
"github.com/code-to-go/safe/safepool/core"
"github.com/godruoyi/go-snowflake"
)
type lockFileContent struct {
Id uint64
Span time.Duration
}
func waitLock(e Exchanger, name string) {
var c lockFileContent
var err error
var id uint64
var shot time.Time
for shot.IsZero() && core.Since(shot) > c.Span {
id = c.Id
err = ReadJSON(e, name, &c, nil)
if err != nil {
return
}
if c.Id != id {
shot = core.Now()
}
time.Sleep(time.Second)
}
}
func LockFile(e Exchanger, name string, span time.Duration) (uint64, error) {
var c lockFileContent
id := snowflake.ID()
for c.Id != id {
waitLock(e, name)
err := WriteJSON(e, name, lockFileContent{
Id: id,
Span: span,
}, nil)
if core.IsErr(err, "cannot write lock file %s: %v", name) {
return 0, err
}
time.Sleep(time.Second)
err = ReadJSON(e, name, &c, nil)
if core.IsErr(err, "cannot read lock file %s: %v", name) {
return 0, err
}
}
return id, nil
}
func UnlockFile(e Exchanger, name string, id uint64) {
var c lockFileContent
_ = ReadJSON(e, name, &c, nil)
if c.Id == id {
e.Delete(name)
}
}