/
fusing.go
70 lines (60 loc) · 1.34 KB
/
fusing.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
package core
import (
"errors"
"strconv"
"strings"
"sync/atomic"
"time"
)
type fusingData struct {
StartTimestamp int64
Quantity int64
}
func (g *Garden) fusingAnalyze(limiter string) (int64, int64, error) {
arr := strings.Split(limiter, "/")
if len(arr) != 2 {
return 0, 0, errors.New("route fusing format error")
}
second, err := strconv.Atoi(arr[0])
if err != nil {
return 0, 0, errors.New("route fusing format error")
}
quantity, err := strconv.Atoi(arr[1])
if err != nil {
return 0, 0, errors.New("route fusing format error")
}
return int64(second), int64(quantity), nil
}
func (g *Garden) fusingInspect(path string, second, quantity int64) bool {
f, ok := g.fusingMap.Load(path)
if !ok {
f = g.resetFusingIndex(path)
}
fd := f.(*fusingData)
now := time.Now().Unix()
lost := now - fd.StartTimestamp
if lost >= second {
fd = g.resetFusingIndex(path)
}
q := atomic.LoadInt64(&fd.Quantity)
if q >= quantity {
return false
}
return true
}
func (g *Garden) resetFusingIndex(index string) *fusingData {
fd := fusingData{
StartTimestamp: time.Now().Unix(),
Quantity: 0,
}
g.fusingMap.Store(index, &fd)
return &fd
}
func (g *Garden) addFusingQuantity(index string) {
f, ok := g.fusingMap.Load(index)
if !ok {
f = g.resetFusingIndex(index)
}
fd := f.(*fusingData)
atomic.AddInt64(&fd.Quantity, 1)
}