mirror of https://github.com/XTLS/Xray-core
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.
89 lines
1.4 KiB
89 lines
1.4 KiB
package protocol |
|
|
|
import ( |
|
"sync" |
|
) |
|
|
|
type ServerList struct { |
|
sync.RWMutex |
|
servers []*ServerSpec |
|
} |
|
|
|
func NewServerList() *ServerList { |
|
return &ServerList{} |
|
} |
|
|
|
func (sl *ServerList) AddServer(server *ServerSpec) { |
|
sl.Lock() |
|
defer sl.Unlock() |
|
|
|
sl.servers = append(sl.servers, server) |
|
} |
|
|
|
func (sl *ServerList) Size() uint32 { |
|
sl.RLock() |
|
defer sl.RUnlock() |
|
|
|
return uint32(len(sl.servers)) |
|
} |
|
|
|
func (sl *ServerList) GetServer(idx uint32) *ServerSpec { |
|
sl.Lock() |
|
defer sl.Unlock() |
|
|
|
for { |
|
if idx >= uint32(len(sl.servers)) { |
|
return nil |
|
} |
|
|
|
server := sl.servers[idx] |
|
if !server.IsValid() { |
|
sl.removeServer(idx) |
|
continue |
|
} |
|
|
|
return server |
|
} |
|
} |
|
|
|
func (sl *ServerList) removeServer(idx uint32) { |
|
n := len(sl.servers) |
|
sl.servers[idx] = sl.servers[n-1] |
|
sl.servers = sl.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 (p *RoundRobinServerPicker) PickServer() *ServerSpec { |
|
p.Lock() |
|
defer p.Unlock() |
|
|
|
next := p.nextIndex |
|
server := p.serverlist.GetServer(next) |
|
if server == nil { |
|
next = 0 |
|
server = p.serverlist.GetServer(0) |
|
} |
|
next++ |
|
if next >= p.serverlist.Size() { |
|
next = 0 |
|
} |
|
p.nextIndex = next |
|
|
|
return server |
|
}
|
|
|