v2ray-core/common/protocol/server_picker.go

90 lines
1.4 KiB
Go
Raw Normal View History

2016-07-24 21:22:46 +00:00
package protocol
import (
"sync"
)
type ServerList struct {
sync.RWMutex
servers []*ServerSpec
}
func NewServerList() *ServerList {
return &ServerList{}
}
2017-04-25 21:40:25 +00:00
func (sl *ServerList) AddServer(server *ServerSpec) {
sl.Lock()
defer sl.Unlock()
2016-07-24 21:22:46 +00:00
2017-04-25 21:40:25 +00:00
sl.servers = append(sl.servers, server)
2016-07-24 21:22:46 +00:00
}
2017-04-25 21:40:25 +00:00
func (sl *ServerList) Size() uint32 {
sl.RLock()
defer sl.RUnlock()
2016-07-24 21:22:46 +00:00
2017-04-25 21:40:25 +00:00
return uint32(len(sl.servers))
2016-07-24 21:22:46 +00:00
}
2017-04-25 21:40:25 +00:00
func (sl *ServerList) GetServer(idx uint32) *ServerSpec {
sl.Lock()
defer sl.Unlock()
2016-07-24 21:22:46 +00:00
for {
2017-04-25 21:40:25 +00:00
if idx >= uint32(len(sl.servers)) {
2016-07-24 21:22:46 +00:00
return nil
}
2017-04-25 21:40:25 +00:00
server := sl.servers[idx]
2016-07-24 21:22:46 +00:00
if !server.IsValid() {
2017-04-25 21:40:25 +00:00
sl.removeServer(idx)
2016-07-24 21:22:46 +00:00
continue
}
return server
}
}
2017-04-25 21:40:25 +00:00
func (sl *ServerList) removeServer(idx uint32) {
n := len(sl.servers)
sl.servers[idx] = sl.servers[n-1]
sl.servers = sl.servers[:n-1]
2016-07-24 21:22:46 +00:00
}
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,
}
}
2017-04-25 21:40:25 +00:00
func (p *RoundRobinServerPicker) PickServer() *ServerSpec {
p.Lock()
defer p.Unlock()
2016-07-24 21:22:46 +00:00
2017-04-25 21:40:25 +00:00
next := p.nextIndex
server := p.serverlist.GetServer(next)
2016-07-24 21:22:46 +00:00
if server == nil {
next = 0
2017-04-25 21:40:25 +00:00
server = p.serverlist.GetServer(0)
2016-07-24 21:22:46 +00:00
}
next++
2017-04-25 21:40:25 +00:00
if next >= p.serverlist.Size() {
2016-07-24 21:22:46 +00:00
next = 0
}
2017-04-25 21:40:25 +00:00
p.nextIndex = next
2016-07-24 21:22:46 +00:00
return server
}