Пример #1
0
func campaign(conn db.Conn, store Store) {
	watch := store.Watch(leaderKey, 1*time.Second)
	trigg := conn.TriggerTick(electionTTL/2, db.EtcdTable)
	oldMaster := false

	for {
		select {
		case <-watch:
		case <-trigg.C:
		}

		etcdRows := conn.SelectFromEtcd(nil)

		minion, err := conn.MinionSelf()
		master := err == nil && minion.Role == db.Master && len(etcdRows) == 1

		if !master {
			if oldMaster {
				commitLeader(conn, false, "")
			}
			continue
		}

		IP := minion.PrivateIP
		if IP == "" {
			continue
		}

		ttl := electionTTL * time.Second

		if etcdRows[0].Leader {
			err = store.Update(leaderKey, IP, ttl)
		} else {
			err = store.Create(leaderKey, IP, ttl)
		}

		if err == nil {
			commitLeader(conn, true, IP)
		} else {
			clientErr, ok := err.(client.Error)
			if !ok || clientErr.Code != client.ErrorCodeNodeExist {
				log.WithError(err).Warn("Error setting leader key")
				commitLeader(conn, false, "")

				// Give things a chance to settle down.
				time.Sleep(electionTTL * time.Second)
			} else {
				commitLeader(conn, false)
			}
		}
	}
}