algo.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. package lb
  2. import (
  3. "errors"
  4. "sync"
  5. )
  6. func GetLbAlgo(algo string) Algo {
  7. // switch
  8. return NewRoundRobin()
  9. }
  10. type Algo interface {
  11. Next() (interface{}, error)
  12. Append(i interface{}) error
  13. Remove(i interface{}) error
  14. Empty() bool
  15. }
  16. // rotation
  17. type roundRobin struct {
  18. head *server
  19. now *server
  20. sync.RWMutex
  21. }
  22. type server struct {
  23. self interface{}
  24. next *server
  25. }
  26. func NewRoundRobin() *roundRobin {
  27. return &roundRobin{}
  28. }
  29. func (r *roundRobin) Append(i interface{}) error {
  30. r.Lock()
  31. defer r.Unlock()
  32. if r.head == nil {
  33. r.head = &server{self: i}
  34. return nil
  35. }
  36. r.now = r.head
  37. for {
  38. if r.now.next == nil {
  39. r.now.next = &server{self: i}
  40. break
  41. }
  42. r.now = r.now.next
  43. }
  44. return nil
  45. }
  46. func (r *roundRobin) Remove(i interface{}) error {
  47. r.Lock()
  48. defer r.Unlock()
  49. o := r.head
  50. var last *server
  51. for {
  52. if o == nil {
  53. return errors.New("not round")
  54. }
  55. if o.self == i {
  56. if last == nil {
  57. r.head = o.next
  58. } else {
  59. last.next = o.next
  60. }
  61. r.now = r.head
  62. return nil
  63. }
  64. last = o
  65. o = o.next
  66. }
  67. }
  68. func (r *roundRobin) Next() (interface{}, error) {
  69. r.Lock()
  70. defer r.Unlock()
  71. if r.head == nil {
  72. return nil, errors.New("not found component")
  73. }
  74. if r.now == nil {
  75. r.now = r.head
  76. }
  77. i := r.now
  78. r.now = r.now.next
  79. return i.self, nil
  80. }
  81. func (r *roundRobin) Empty() bool {
  82. if r.head != nil {
  83. return false
  84. }
  85. return true
  86. }