IsRoundRobin checks whether f's return value is roundrobin of elements from want. But it doesn't check for the order. Note that want can contain duplicate items, which makes it weight-round-robin. Step 1. the return values of f should form a permutation of all elements in want, but not necessary in
(want []balancer.SubConn, f func() balancer.SubConn)
| 350 | // If error is found in this step, the returned error contains the first |
| 351 | // iteration + the second iteration until where it goes wrong. |
| 352 | func IsRoundRobin(want []balancer.SubConn, f func() balancer.SubConn) error { |
| 353 | wantSet := make(map[balancer.SubConn]int) // SubConn -> count, for weighted RR. |
| 354 | for _, sc := range want { |
| 355 | wantSet[sc]++ |
| 356 | } |
| 357 | |
| 358 | // The first iteration: makes sure f's return values form a permutation of |
| 359 | // elements in want. |
| 360 | // |
| 361 | // Also keep the returns values in a slice, so we can compare the order in |
| 362 | // the second iteration. |
| 363 | gotSliceFirstIteration := make([]balancer.SubConn, 0, len(want)) |
| 364 | for range want { |
| 365 | got := f() |
| 366 | gotSliceFirstIteration = append(gotSliceFirstIteration, got) |
| 367 | wantSet[got]-- |
| 368 | if wantSet[got] < 0 { |
| 369 | return fmt.Errorf("non-roundrobin want: %v, result: %v", want, gotSliceFirstIteration) |
| 370 | } |
| 371 | } |
| 372 | |
| 373 | // The second iteration should repeat the first iteration. |
| 374 | var gotSliceSecondIteration []balancer.SubConn |
| 375 | for i := 0; i < 2; i++ { |
| 376 | for _, w := range gotSliceFirstIteration { |
| 377 | g := f() |
| 378 | gotSliceSecondIteration = append(gotSliceSecondIteration, g) |
| 379 | if w != g { |
| 380 | return fmt.Errorf("non-roundrobin, first iter: %v, second iter: %v", gotSliceFirstIteration, gotSliceSecondIteration) |
| 381 | } |
| 382 | } |
| 383 | } |
| 384 | |
| 385 | return nil |
| 386 | } |
| 387 | |
| 388 | // SubConnFromPicker returns a function which returns a SubConn by calling the |
| 389 | // Pick() method of the provided picker. There is no caching of SubConns here. |