cluster.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. package etcdserver
  2. import (
  3. "fmt"
  4. "math/rand"
  5. "net/url"
  6. "sort"
  7. "strings"
  8. )
  9. // Cluster is a list of Members that belong to the same raft cluster
  10. type Cluster map[int64]*Member
  11. func (c Cluster) FindID(id int64) *Member {
  12. return c[id]
  13. }
  14. func (c Cluster) FindName(name string) *Member {
  15. for _, m := range c {
  16. if m.Name == name {
  17. return m
  18. }
  19. }
  20. return nil
  21. }
  22. func (c Cluster) Add(m Member) error {
  23. if c.FindID(m.ID) != nil {
  24. return fmt.Errorf("Member exists with identical ID %v", m)
  25. }
  26. c[m.ID] = &m
  27. return nil
  28. }
  29. func (c *Cluster) AddSlice(mems []Member) error {
  30. for _, m := range mems {
  31. err := c.Add(m)
  32. if err != nil {
  33. return err
  34. }
  35. }
  36. return nil
  37. }
  38. // Pick chooses a random address from a given Member's addresses, and returns it as
  39. // an addressible URI. If the given member does not exist, an empty string is returned.
  40. func (c Cluster) Pick(id int64) string {
  41. if m := c.FindID(id); m != nil {
  42. addrs := m.PeerURLs
  43. if len(addrs) == 0 {
  44. return ""
  45. }
  46. return addrs[rand.Intn(len(addrs))]
  47. }
  48. return ""
  49. }
  50. // Set parses command line sets of names to IPs formatted like:
  51. // mach0=1.1.1.1,mach0=2.2.2.2,mach0=1.1.1.1,mach1=2.2.2.2,mach1=3.3.3.3
  52. func (c *Cluster) Set(s string) error {
  53. *c = Cluster{}
  54. v, err := url.ParseQuery(strings.Replace(s, ",", "&", -1))
  55. if err != nil {
  56. return err
  57. }
  58. for name, urls := range v {
  59. if len(urls) == 0 || urls[0] == "" {
  60. return fmt.Errorf("Empty URL given for %q", name)
  61. }
  62. m := newMember(name, urls)
  63. err := c.Add(*m)
  64. if err != nil {
  65. return err
  66. }
  67. }
  68. return nil
  69. }
  70. func (c Cluster) String() string {
  71. sl := []string{}
  72. for _, m := range c {
  73. for _, u := range m.PeerURLs {
  74. sl = append(sl, fmt.Sprintf("%s=%s", m.Name, u))
  75. }
  76. }
  77. sort.Strings(sl)
  78. return strings.Join(sl, ",")
  79. }
  80. func (c Cluster) IDs() []int64 {
  81. var ids []int64
  82. for _, m := range c {
  83. ids = append(ids, m.ID)
  84. }
  85. return ids
  86. }
  87. // PeerURLs returns a list of all peer addresses. Each address is prefixed
  88. // with the scheme (currently "http://"). The returned list is sorted in
  89. // ascending lexicographical order.
  90. func (c Cluster) PeerURLs() []string {
  91. endpoints := make([]string, 0)
  92. for _, p := range c {
  93. for _, addr := range p.PeerURLs {
  94. endpoints = append(endpoints, addScheme(addr))
  95. }
  96. }
  97. sort.Strings(endpoints)
  98. return endpoints
  99. }
  100. // ClientURLs returns a list of all client addresses. Each address is prefixed
  101. // with the scheme (currently "http://"). The returned list is sorted in
  102. // ascending lexicographical order.
  103. func (c Cluster) ClientURLs() []string {
  104. urls := make([]string, 0)
  105. for _, p := range c {
  106. for _, url := range p.ClientURLs {
  107. urls = append(urls, addScheme(url))
  108. }
  109. }
  110. sort.Strings(urls)
  111. return urls
  112. }