github.com/ghodss/etcd@v0.3.1-0.20140417172404-cc329bfa55cb/server/demote_command.go (about)

     1  package server
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/coreos/etcd/log"
     7  	"github.com/coreos/etcd/third_party/github.com/goraft/raft"
     8  )
     9  
    10  func init() {
    11  	raft.RegisterCommand(&DemoteCommand{})
    12  }
    13  
    14  // DemoteCommand represents a command to change a peer to a standby.
    15  type DemoteCommand struct {
    16  	Name string `json:"name"`
    17  }
    18  
    19  // CommandName returns the name of the command.
    20  func (c *DemoteCommand) CommandName() string {
    21  	return "etcd:demote"
    22  }
    23  
    24  // Apply executes the command.
    25  func (c *DemoteCommand) Apply(context raft.Context) (interface{}, error) {
    26  	ps, _ := context.Server().Context().(*PeerServer)
    27  
    28  	// Ignore this command if there is no peer.
    29  	if !ps.registry.PeerExists(c.Name) {
    30  		return nil, fmt.Errorf("peer does not exist: %s", c.Name)
    31  	}
    32  
    33  	// Save URLs.
    34  	clientURL, _ := ps.registry.ClientURL(c.Name)
    35  	peerURL, _ := ps.registry.PeerURL(c.Name)
    36  
    37  	// Remove node from the shared registry.
    38  	err := ps.registry.UnregisterPeer(c.Name)
    39  	if err != nil {
    40  		log.Debugf("Demote peer %s: Error while unregistering (%v)", c.Name, err)
    41  		return nil, err
    42  	}
    43  
    44  	// Delete from stats
    45  	delete(ps.followersStats.Followers, c.Name)
    46  
    47  	// Remove peer in raft
    48  	err = context.Server().RemovePeer(c.Name)
    49  	if err != nil {
    50  		log.Debugf("Demote peer %s: (%v)", c.Name, err)
    51  		return nil, err
    52  	}
    53  
    54  	// Register node as a standby.
    55  	ps.registry.RegisterStandby(c.Name, peerURL, clientURL)
    56  
    57  	// Update mode if this change applies to this server.
    58  	if c.Name == ps.Config.Name {
    59  		log.Infof("Demote peer %s: Set mode to standby with %s", c.Name, ps.server.Leader())
    60  		ps.standbyPeerURL, _ = ps.registry.PeerURL(ps.server.Leader())
    61  		go ps.setMode(StandbyMode)
    62  	}
    63  
    64  	return nil, nil
    65  }
    66  
    67  // NodeName returns the name of the affected node.
    68  func (c *DemoteCommand) NodeName() string {
    69  	return c.Name
    70  }