В новой основной версии etcd v3 представлены новые примитивы параллелизма. Один из них election
.
В API отсутствует поддержка для запуска кампании и возврата (другого) победителя, это означает, что нам нужно запросить лидера. Это усложняет задачу, потому что теперь у нас есть два параллельных пути: один управляет кампанией, а другой отслеживает смену лидеров. Как лучше всего синхронизировать эти два узла, если мы хотим, чтобы все узлы работали в качестве лидера, а резервный — в качестве ведомого.
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
}
}
}