-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathround.go
119 lines (106 loc) · 2.04 KB
/
round.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package round
import (
"sync"
"time"
)
type Round struct {
ServerList []*Server
KeepAlive bool
HeartBeatTime time.Duration
Lock sync.Mutex
totalWeight int
CheckAlive func(string,int)bool
}
func NewRound() *Round{
r := new(Round)
return r
}
func (r *Round) WithKeepAlive(b bool){
r.KeepAlive = b
}
func (r *Round) WithHeartBeatTime(t time.Duration){
r.HeartBeatTime = t
}
func (r *Round) Start(){
if r.KeepAlive {
if r.CheckAlive == nil {
return
}
go func(){
for{
time.Sleep(r.HeartBeatTime)
for _,v := range r.ServerList {
if r.CheckAlive(v.IP,v.Port) {
if !v.Alive {
r.Lock.Lock()
v.Alive = true
r.totalWeight += v.Weight
r.reSetCurrentWeight()
r.Lock.Unlock()
}
}else{
if v.Alive {
r.Lock.Lock()
v.Alive = false
r.totalWeight -= v.Weight
r.reSetCurrentWeight()
r.Lock.Unlock()
}
}
}
}
}()
}
}
func (r *Round) AddServer(s *Server)error{
if s.Weight<=0{
return ErrInvalidWeight
}
s.CurrentWeight = s.Weight
r.ServerList = append(r.ServerList, s)
r.addTotalWeight(s.Weight)
return nil
}
func (r *Round) GetServer()(*Server, error){
index := -1
maxWeight := 0
r.Lock.Lock()
defer r.Lock.Unlock()
for k,v := range r.ServerList {
if v.Alive {
if v.CurrentWeight > maxWeight{
index = k
maxWeight = v.CurrentWeight
}
v.CurrentWeight += v.Weight
}
}
if index<0{
return &Server{}, ErrNoServerAlive
}
r.ServerList[index].CurrentWeight -= r.totalWeight
return r.ServerList[index], nil
}
func (r *Round) setTotalWeight(w int){
r.Lock.Lock()
defer r.Lock.Unlock()
r.totalWeight = w
}
func (r *Round) addTotalWeight(w int){
r.Lock.Lock()
defer r.Lock.Unlock()
r.totalWeight += w
}
func (r *Round) reduceTotalWeight(w int){
r.Lock.Lock()
defer r.Lock.Unlock()
r.totalWeight -= w
}
func (r *Round) reSetCurrentWeight(){
for _,v := range r.ServerList {
v.CurrentWeight = v.Weight
}
}
func (r *Round) WithCheckAlive(fn func(string,int)bool){
r.CheckAlive = fn
}