check that there's exactly one leader. try a few times in case re-elections are needed.
()
| 370 | // check that there's exactly one leader. |
| 371 | // try a few times in case re-elections are needed. |
| 372 | func (cfg *config) checkOneLeader() int { |
| 373 | for iters := 0; iters < 10; iters++ { |
| 374 | ms := 450 + (rand.Int63() % 100) |
| 375 | time.Sleep(time.Duration(ms) * time.Millisecond) |
| 376 | |
| 377 | leaders := make(map[int][]int) |
| 378 | for i := 0; i < cfg.n; i++ { |
| 379 | if cfg.connected[i] { |
| 380 | if term, leader := cfg.rafts[i].GetState(); leader { |
| 381 | leaders[term] = append(leaders[term], i) |
| 382 | } |
| 383 | } |
| 384 | } |
| 385 | |
| 386 | lastTermWithLeader := -1 |
| 387 | for term, leaders := range leaders { |
| 388 | if len(leaders) > 1 { |
| 389 | cfg.t.Fatalf("term %d has %d (>1) leaders", term, len(leaders)) |
| 390 | } |
| 391 | if term > lastTermWithLeader { |
| 392 | lastTermWithLeader = term |
| 393 | } |
| 394 | } |
| 395 | |
| 396 | if len(leaders) != 0 { |
| 397 | return leaders[lastTermWithLeader][0] |
| 398 | } |
| 399 | } |
| 400 | cfg.t.Fatalf("expected one leader, got none") |
| 401 | return -1 |
| 402 | } |
| 403 | |
| 404 | // check that everyone agrees on the term. |
| 405 | func (cfg *config) checkTerms() int { |