fix lock usage in server list

pull/298/merge
Darien Raymond 2017-04-25 23:40:25 +02:00
parent fb3d2ca862
commit 0d92dce5eb
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
2 changed files with 28 additions and 29 deletions

View File

@ -13,32 +13,32 @@ func NewServerList() *ServerList {
return &ServerList{} return &ServerList{}
} }
func (v *ServerList) AddServer(server *ServerSpec) { func (sl *ServerList) AddServer(server *ServerSpec) {
v.Lock() sl.Lock()
defer v.Unlock() defer sl.Unlock()
v.servers = append(v.servers, server) sl.servers = append(sl.servers, server)
} }
func (v *ServerList) Size() uint32 { func (sl *ServerList) Size() uint32 {
v.RLock() sl.RLock()
defer v.RUnlock() defer sl.RUnlock()
return uint32(len(v.servers)) return uint32(len(sl.servers))
} }
func (v *ServerList) GetServer(idx uint32) *ServerSpec { func (sl *ServerList) GetServer(idx uint32) *ServerSpec {
v.RLock() sl.Lock()
defer v.RUnlock() defer sl.Unlock()
for { for {
if idx >= uint32(len(v.servers)) { if idx >= uint32(len(sl.servers)) {
return nil return nil
} }
server := v.servers[idx] server := sl.servers[idx]
if !server.IsValid() { if !server.IsValid() {
v.RemoveServer(idx) sl.removeServer(idx)
continue continue
} }
@ -46,11 +46,10 @@ func (v *ServerList) GetServer(idx uint32) *ServerSpec {
} }
} }
// Private: Visible for testing. func (sl *ServerList) removeServer(idx uint32) {
func (v *ServerList) RemoveServer(idx uint32) { n := len(sl.servers)
n := len(v.servers) sl.servers[idx] = sl.servers[n-1]
v.servers[idx] = v.servers[n-1] sl.servers = sl.servers[:n-1]
v.servers = v.servers[:n-1]
} }
type ServerPicker interface { type ServerPicker interface {
@ -70,21 +69,21 @@ func NewRoundRobinServerPicker(serverlist *ServerList) *RoundRobinServerPicker {
} }
} }
func (v *RoundRobinServerPicker) PickServer() *ServerSpec { func (p *RoundRobinServerPicker) PickServer() *ServerSpec {
v.Lock() p.Lock()
defer v.Unlock() defer p.Unlock()
next := v.nextIndex next := p.nextIndex
server := v.serverlist.GetServer(next) server := p.serverlist.GetServer(next)
if server == nil { if server == nil {
next = 0 next = 0
server = v.serverlist.GetServer(0) server = p.serverlist.GetServer(0)
} }
next++ next++
if next >= v.serverlist.Size() { if next >= p.serverlist.Size() {
next = 0 next = 0
} }
v.nextIndex = next p.nextIndex = next
return server return server
} }

View File

@ -19,11 +19,11 @@ func AlwaysValid() ValidationStrategy {
return AlwaysValidStrategy{} return AlwaysValidStrategy{}
} }
func (v AlwaysValidStrategy) IsValid() bool { func (AlwaysValidStrategy) IsValid() bool {
return true return true
} }
func (v AlwaysValidStrategy) Invalidate() {} func (AlwaysValidStrategy) Invalidate() {}
type TimeoutValidStrategy struct { type TimeoutValidStrategy struct {
until time.Time until time.Time