You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
v2ray-core/common/protocol/server_picker.go

91 lines
1.4 KiB

8 years ago
package protocol
import (
"sync"
)
type ServerList struct {
sync.RWMutex
servers []*ServerSpec
}
func NewServerList() *ServerList {
return &ServerList{}
}
8 years ago
func (v *ServerList) AddServer(server *ServerSpec) {
v.Lock()
defer v.Unlock()
8 years ago
8 years ago
v.servers = append(v.servers, server)
8 years ago
}
8 years ago
func (v *ServerList) Size() uint32 {
v.RLock()
defer v.RUnlock()
8 years ago
8 years ago
return uint32(len(v.servers))
8 years ago
}
8 years ago
func (v *ServerList) GetServer(idx uint32) *ServerSpec {
v.RLock()
defer v.RUnlock()
8 years ago
for {
8 years ago
if idx >= uint32(len(v.servers)) {
8 years ago
return nil
}
8 years ago
server := v.servers[idx]
8 years ago
if !server.IsValid() {
8 years ago
v.RemoveServer(idx)
8 years ago
continue
}
return server
}
}
// Private: Visible for testing.
8 years ago
func (v *ServerList) RemoveServer(idx uint32) {
n := len(v.servers)
v.servers[idx] = v.servers[n-1]
v.servers = v.servers[:n-1]
8 years ago
}
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,
}
}
8 years ago
func (v *RoundRobinServerPicker) PickServer() *ServerSpec {
v.Lock()
defer v.Unlock()
8 years ago
8 years ago
next := v.nextIndex
server := v.serverlist.GetServer(next)
8 years ago
if server == nil {
next = 0
8 years ago
server = v.serverlist.GetServer(0)
8 years ago
}
next++
8 years ago
if next >= v.serverlist.Size() {
8 years ago
next = 0
}
8 years ago
v.nextIndex = next
8 years ago
return server
}