The new major version of etcd v3 has introduces new concurrency primitives. One of those is election.
The api lacks support to start a campaign and return the (other) winner, this means we need to query the leader. This makes it complex because now we have two concurrent paths, one running an campaign and the other monitoring leader changes. What is the best practise to synchronise those two if we want all the nodes to run for leader, and fallback to follower.
go func() {
if err := election.Campaign(this.ctx, this.Address); err != nil {
this.log.Error("election campaign failed", zap.Error(err))
}
}()
for {
select {
case response, ok := <-observations:
if !ok {
this.log.Warn("election observation channel closed")
return
}
value := string(response.Kvs[0].Value)
change := LeaderChanged{strings.EqualFold(value, this.Address), value}
select {
case changes <- change:
// should we figure out if we are a leader at this point?
case <-session.Done():
// it might be that we lost leadership
}
}
}