github.com/jpetazzo/etcd@v0.2.1-0.20140113055439-97f1363afac5/server/join_command.go (about) 1 package server 2 3 import ( 4 "encoding/binary" 5 6 etcdErr "github.com/coreos/etcd/error" 7 "github.com/coreos/etcd/log" 8 "github.com/coreos/raft" 9 ) 10 11 func init() { 12 raft.RegisterCommand(&JoinCommand{}) 13 } 14 15 // The JoinCommand adds a node to the cluster. 16 type JoinCommand struct { 17 MinVersion int `json:"minVersion"` 18 MaxVersion int `json:"maxVersion"` 19 Name string `json:"name"` 20 RaftURL string `json:"raftURL"` 21 EtcdURL string `json:"etcdURL"` 22 } 23 24 func NewJoinCommand(minVersion int, maxVersion int, name, raftUrl, etcdUrl string) *JoinCommand { 25 return &JoinCommand{ 26 MinVersion: minVersion, 27 MaxVersion: maxVersion, 28 Name: name, 29 RaftURL: raftUrl, 30 EtcdURL: etcdUrl, 31 } 32 } 33 34 // The name of the join command in the log 35 func (c *JoinCommand) CommandName() string { 36 return "etcd:join" 37 } 38 39 // Join a server to the cluster 40 func (c *JoinCommand) Apply(context raft.Context) (interface{}, error) { 41 ps, _ := context.Server().Context().(*PeerServer) 42 43 b := make([]byte, 8) 44 binary.PutUvarint(b, context.CommitIndex()) 45 46 // Make sure we're not getting a cached value from the registry. 47 ps.registry.Invalidate(c.Name) 48 49 // Check if the join command is from a previous peer, who lost all its previous log. 50 if _, ok := ps.registry.ClientURL(c.Name); ok { 51 return b, nil 52 } 53 54 // Check peer number in the cluster 55 if ps.registry.Count() == ps.MaxClusterSize { 56 log.Debug("Reject join request from ", c.Name) 57 return []byte{0}, etcdErr.NewError(etcdErr.EcodeNoMorePeer, "", context.CommitIndex()) 58 } 59 60 // Add to shared peer registry. 61 ps.registry.Register(c.Name, c.RaftURL, c.EtcdURL) 62 63 // Add peer in raft 64 err := context.Server().AddPeer(c.Name, "") 65 66 // Add peer stats 67 if c.Name != ps.RaftServer().Name() { 68 ps.followersStats.Followers[c.Name] = &raftFollowerStats{} 69 ps.followersStats.Followers[c.Name].Latency.Minimum = 1 << 63 70 } 71 72 return b, err 73 } 74 75 func (c *JoinCommand) NodeName() string { 76 return c.Name 77 }