diff --git a/pkg/activator/net/lb_policy.go b/pkg/activator/net/lb_policy.go index 4f8cd835e99f..0e2fc3b0d685 100644 --- a/pkg/activator/net/lb_policy.go +++ b/pkg/activator/net/lb_policy.go @@ -67,6 +67,11 @@ func randomChoice2Policy(_ context.Context, targets []*podTracker) (func(), *pod // so fine. if pick.getWeight() > alt.getWeight() { pick = alt + } else if pick.getWeight() == alt.getWeight() { + //nolint:gosec // We don't need cryptographic randomness here. + if rand.Int63()%2 == 0 { + pick = alt + } } pick.increaseWeight() return pick.decreaseWeight, pick diff --git a/pkg/activator/net/lb_policy_test.go b/pkg/activator/net/lb_policy_test.go index 95e53a24bade..2a460965d132 100644 --- a/pkg/activator/net/lb_policy_test.go +++ b/pkg/activator/net/lb_policy_test.go @@ -25,6 +25,32 @@ import ( "knative.dev/serving/pkg/queue" ) +func TestRandomChoice_TwoTrackersDistribution(t *testing.T) { + podTrackers := makeTrackers(2, 0) + counts := map[string]int{} + + total := 100 + for i := 0; i < total; i++ { + cb, pt := randomChoice2Policy(context.Background(), podTrackers) + cb() + counts[pt.dest]++ + } + + first := counts[podTrackers[0].dest] + second := counts[podTrackers[1].dest] + + // probability of this occurring is 0.5^100 + if first == 0 { + t.Error("expected the first tracker to get some requests") + } + if second == 0 { + t.Error("expected the second tracker to get some requests") + } + if first+second != total { + t.Error("expected total requests to equal 100 - was ", first+second) + } +} + func TestRandomChoice2(t *testing.T) { t.Run("1 tracker", func(t *testing.T) { podTrackers := makeTrackers(1, 0)