join_command.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package server
  2. import (
  3. "encoding/binary"
  4. etcdErr "github.com/coreos/etcd/error"
  5. "github.com/coreos/etcd/log"
  6. "github.com/coreos/go-raft"
  7. )
  8. func init() {
  9. raft.RegisterCommand(&JoinCommand{})
  10. }
  11. // The JoinCommand adds a node to the cluster.
  12. type JoinCommand struct {
  13. RaftVersion string `json:"raftVersion"`
  14. Name string `json:"name"`
  15. RaftURL string `json:"raftURL"`
  16. EtcdURL string `json:"etcdURL"`
  17. }
  18. func NewJoinCommand(version, name, raftUrl, etcdUrl string) *JoinCommand {
  19. return &JoinCommand{
  20. RaftVersion: version,
  21. Name: name,
  22. RaftURL: raftUrl,
  23. EtcdURL: etcdUrl,
  24. }
  25. }
  26. // The name of the join command in the log
  27. func (c *JoinCommand) CommandName() string {
  28. return "etcd:join"
  29. }
  30. // Join a server to the cluster
  31. func (c *JoinCommand) Apply(server *raft.Server) (interface{}, error) {
  32. ps, _ := server.Context().(*PeerServer)
  33. b := make([]byte, 8)
  34. binary.PutUvarint(b, server.CommitIndex())
  35. // Check if the join command is from a previous machine, who lost all its previous log.
  36. if _, ok := ps.registry.URL(c.Name); ok {
  37. return b, nil
  38. }
  39. // Check machine number in the cluster
  40. if ps.registry.Count() == ps.MaxClusterSize {
  41. log.Debug("Reject join request from ", c.Name)
  42. return []byte{0}, etcdErr.NewError(etcdErr.EcodeNoMoreMachine, "", server.CommitIndex(), server.Term())
  43. }
  44. // Add to shared machine registry.
  45. ps.registry.Register(c.Name, c.RaftVersion, c.RaftURL, c.EtcdURL, server.CommitIndex(), server.Term())
  46. // Add peer in raft
  47. err := server.AddPeer(c.Name, "")
  48. // Add peer stats
  49. if c.Name != ps.Name() {
  50. ps.followersStats.Followers[c.Name] = &raftFollowerStats{}
  51. ps.followersStats.Followers[c.Name].Latency.Minimum = 1 << 63
  52. }
  53. return b, err
  54. }
  55. func (c *JoinCommand) NodeName() string {
  56. return c.Name
  57. }