Skip to content

Commit

Permalink
Merge pull request #131 from abronan/overhaul_join
Browse files Browse the repository at this point in the history
raft: synchronous raft conf change, safeguard on join/leave raft
  • Loading branch information
aaronlehmann committed Apr 5, 2016
2 parents c613f0d + 2963dc7 commit fbebe48
Show file tree
Hide file tree
Showing 4 changed files with 343 additions and 180 deletions.
107 changes: 75 additions & 32 deletions manager/state/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,56 +6,99 @@ import (
"github.com/docker/swarm-v2/api"
)

// Cluster represents a set of active
// Cluster represents a raft cluster
type Cluster interface {
// ID returns the cluster ID
ID() uint64
// Members returns a map of members identified by their raft ID
Members() map[uint64]*Member
// AddMember adds a member to the cluster memberlist
AddMember(*Member) error
// RemoveMember removes a member from the memberlist and add
// it to the remove set
RemoveMember(uint64) error
// Member retrieves a particular member based on ID, or nil if the
// member does not exist in the cluster
GetMember(id uint64) *Member
// IsIDRemoved checks whether the given ID has been removed from this
// cluster at some point in the past
IsIDRemoved(id uint64) bool
}

// cluster represents a set of active
// raft members
type Cluster struct {
lock sync.RWMutex
peers map[uint64]*Peer
type cluster struct {
id uint64

mu sync.RWMutex
members map[uint64]*Member

// removed contains the list of removed members,
// those ids cannot be reused
removed map[uint64]bool
}

// Peer represents a raft cluster peer
type Peer struct {
// Member represents a raft cluster member
type Member struct {
*api.RaftNode

Client *Raft
}

// NewCluster creates a new cluster neighbors
// list for a raft member
func NewCluster() *Cluster {
return &Cluster{
peers: make(map[uint64]*Peer),
func NewCluster() Cluster {
// TODO generate cluster ID

return &cluster{
members: make(map[uint64]*Member),
removed: make(map[uint64]bool),
}
}

// Peers returns the list of peers in the cluster
func (c *Cluster) Peers() map[uint64]*Peer {
peers := make(map[uint64]*Peer)
c.lock.RLock()
for k, v := range c.peers {
peers[k] = v
func (c *cluster) ID() uint64 {
return c.id
}

// Members returns the list of raft members in the cluster
func (c *cluster) Members() map[uint64]*Member {
members := make(map[uint64]*Member)
c.mu.RLock()
for k, v := range c.members {
members[k] = v
}
c.lock.RUnlock()
return peers
c.mu.RUnlock()
return members
}

// GetMember returns informations on a given member
func (c *cluster) GetMember(id uint64) *Member {
c.mu.RLock()
defer c.mu.RUnlock()
return c.members[id]
}

// GetPeer returns informations on a given peer
func (c *Cluster) GetPeer(id uint64) *Peer {
c.lock.RLock()
defer c.lock.RUnlock()
return c.peers[id]
// AddMember adds a node to the cluster memberlist
func (c *cluster) AddMember(member *Member) error {
c.mu.Lock()
defer c.mu.Unlock()
c.members[member.ID] = member
return nil
}

// AddPeer adds a node to our neighbors
func (c *Cluster) AddPeer(peer *Peer) {
c.lock.Lock()
c.peers[peer.ID] = peer
c.lock.Unlock()
// RemoveMember removes a node from the cluster memberlist
func (c *cluster) RemoveMember(id uint64) error {
c.mu.Lock()
defer c.mu.Unlock()
c.members[id].Client.Conn.Close()
c.removed[id] = true
delete(c.members, id)
return nil
}

// RemovePeer removes a node from our neighbors
func (c *Cluster) RemovePeer(id uint64) {
c.lock.Lock()
delete(c.peers, id)
c.lock.Unlock()
// IsIDRemoved checks if a member is in the remove set
func (c *cluster) IsIDRemoved(id uint64) bool {
c.mu.RLock()
defer c.mu.RUnlock()
return c.removed[id]
}
Loading

0 comments on commit fbebe48

Please sign in to comment.