server_picker.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package protocol
  2. import (
  3. "sync"
  4. )
  5. type ServerList struct {
  6. sync.RWMutex
  7. servers []*ServerSpec
  8. }
  9. func NewServerList() *ServerList {
  10. return &ServerList{}
  11. }
  12. func (this *ServerList) AddServer(server *ServerSpec) {
  13. this.Lock()
  14. defer this.Unlock()
  15. this.servers = append(this.servers, server)
  16. }
  17. func (this *ServerList) Size() uint32 {
  18. this.RLock()
  19. defer this.RUnlock()
  20. return uint32(len(this.servers))
  21. }
  22. func (this *ServerList) GetServer(idx uint32) *ServerSpec {
  23. this.RLock()
  24. defer this.RUnlock()
  25. for {
  26. if idx >= uint32(len(this.servers)) {
  27. return nil
  28. }
  29. server := this.servers[idx]
  30. if !server.IsValid() {
  31. this.RemoveServer(idx)
  32. continue
  33. }
  34. return server
  35. }
  36. }
  37. // Private: Visible for testing.
  38. func (this *ServerList) RemoveServer(idx uint32) {
  39. n := len(this.servers)
  40. this.servers[idx] = this.servers[n-1]
  41. this.servers = this.servers[:n-1]
  42. }
  43. type ServerPicker interface {
  44. PickServer() *ServerSpec
  45. }
  46. type RoundRobinServerPicker struct {
  47. sync.Mutex
  48. serverlist *ServerList
  49. nextIndex uint32
  50. }
  51. func NewRoundRobinServerPicker(serverlist *ServerList) *RoundRobinServerPicker {
  52. return &RoundRobinServerPicker{
  53. serverlist: serverlist,
  54. nextIndex: 0,
  55. }
  56. }
  57. func (this *RoundRobinServerPicker) PickServer() *ServerSpec {
  58. this.Lock()
  59. defer this.Unlock()
  60. next := this.nextIndex
  61. server := this.serverlist.GetServer(next)
  62. if server == nil {
  63. next = 0
  64. server = this.serverlist.GetServer(0)
  65. }
  66. next++
  67. if next >= this.serverlist.Size() {
  68. next = 0
  69. }
  70. this.nextIndex = next
  71. return server
  72. }