mirror of https://github.com/docker/docs.git
67 lines
1.3 KiB
Go
67 lines
1.3 KiB
Go
package leadership
|
|
|
|
import "github.com/docker/swarm/pkg/store"
|
|
|
|
// Follower can folow an election in real-time and push notifications whenever
|
|
// there is a change in leadership.
|
|
type Follower struct {
|
|
client store.Store
|
|
key string
|
|
|
|
leaderCh chan string
|
|
stopCh chan struct{}
|
|
}
|
|
|
|
// NewFollower creates a new follower.
|
|
func NewFollower(client store.Store, key string) *Follower {
|
|
return &Follower{
|
|
client: client,
|
|
key: key,
|
|
leaderCh: make(chan string),
|
|
stopCh: make(chan struct{}),
|
|
}
|
|
}
|
|
|
|
// LeaderCh is used to get a channel which delivers the currently elected
|
|
// leader.
|
|
func (f *Follower) LeaderCh() <-chan string {
|
|
return f.leaderCh
|
|
}
|
|
|
|
// FollowElection starts monitoring the election.
|
|
func (f *Follower) FollowElection() error {
|
|
ch, err := f.client.Watch(f.key, f.stopCh)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
go f.follow(ch)
|
|
|
|
return nil
|
|
}
|
|
|
|
// Stop stops monitoring an election.
|
|
func (f *Follower) Stop() {
|
|
close(f.stopCh)
|
|
}
|
|
|
|
func (f *Follower) follow(<-chan *store.KVPair) {
|
|
defer close(f.leaderCh)
|
|
|
|
// FIXME: We should pass `RequireConsistent: true` to Consul.
|
|
ch, err := f.client.Watch(f.key, f.stopCh)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
prev := ""
|
|
for kv := range ch {
|
|
curr := string(kv.Value)
|
|
if curr == prev {
|
|
continue
|
|
}
|
|
prev = curr
|
|
f.leaderCh <- string(curr)
|
|
}
|
|
}
|