forked from v2fly/v2ray-core
-
Notifications
You must be signed in to change notification settings - Fork 1
/
server_picker.go
90 lines (72 loc) · 1.48 KB
/
server_picker.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
package protocol
import (
"sync"
)
type ServerList struct {
sync.RWMutex
servers []*ServerSpec
}
func NewServerList() *ServerList {
return &ServerList{}
}
func (this *ServerList) AddServer(server *ServerSpec) {
this.Lock()
defer this.Unlock()
this.servers = append(this.servers, server)
}
func (this *ServerList) Size() uint32 {
this.RLock()
defer this.RUnlock()
return uint32(len(this.servers))
}
func (this *ServerList) GetServer(idx uint32) *ServerSpec {
this.RLock()
defer this.RUnlock()
for {
if idx >= uint32(len(this.servers)) {
return nil
}
server := this.servers[idx]
if !server.IsValid() {
this.RemoveServer(idx)
continue
}
return server
}
}
// @Private
func (this *ServerList) RemoveServer(idx uint32) {
n := len(this.servers)
this.servers[idx] = this.servers[n-1]
this.servers = this.servers[:n-1]
}
type ServerPicker interface {
PickServer() *ServerSpec
}
type RoundRobinServerPicker struct {
sync.Mutex
serverlist *ServerList
nextIndex uint32
}
func NewRoundRobinServerPicker(serverlist *ServerList) *RoundRobinServerPicker {
return &RoundRobinServerPicker{
serverlist: serverlist,
nextIndex: 0,
}
}
func (this *RoundRobinServerPicker) PickServer() *ServerSpec {
this.Lock()
defer this.Unlock()
next := this.nextIndex
server := this.serverlist.GetServer(next)
if server == nil {
next = 0
server = this.serverlist.GetServer(0)
}
next++
if next >= this.serverlist.Size() {
next = 0
}
this.nextIndex = next
return server
}