-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add round robin policy for the cc > 3 #8263
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,6 +21,7 @@ package net | |
| import ( | ||
| "context" | ||
| "math/rand" | ||
| "sync" | ||
| ) | ||
|
|
||
| // lbPolicy is a functor that selects a target pod from the list, or (noop, nil) if | ||
|
|
@@ -84,3 +85,34 @@ func firstAvailableLBPolicy(ctx context.Context, targets []*podTracker) (func(), | |
| } | ||
| return noop, nil | ||
| } | ||
|
|
||
| type roundRobinPolicyT struct { | ||
| mu sync.Mutex | ||
| idx int | ||
| } | ||
|
|
||
| func newRoundRobinPolicy() lbPolicy { | ||
| rrp := roundRobinPolicyT{} | ||
| return func(ctx context.Context, targets []*podTracker) (func(), *podTracker) { | ||
| rrp.mu.Lock() | ||
| defer rrp.mu.Unlock() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we get away without locking? We could try to get away using atomics potentially, though the benchmarks don't really warrant that I suppose.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried, I was not happy with provable semantics for parallel requests.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair enough, we can iterate if necessary 🤷
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the problem, is that we start moving indices either independently or in interleaving fashion. In theory with enough requests it will still average out, but it's much harder to reason about |
||
| // The number of trackers might have shrunk, so reset to 0. | ||
|
vagababov marked this conversation as resolved.
|
||
| l := len(targets) | ||
| if rrp.idx >= l { | ||
| rrp.idx = 0 | ||
| } | ||
|
|
||
| // Now for |targets| elements and check every next one in | ||
| // round robin fashion. | ||
| for i := 0; i < l; i++ { | ||
| p := (rrp.idx + i) % l | ||
| if cb, ok := targets[p].Reserve(ctx); ok { | ||
| // We want to start with the next index. | ||
| rrp.idx = p + 1 | ||
| return cb, targets[p] | ||
| } | ||
| } | ||
| // We exhausted all the options... | ||
| return noop, nil | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -163,12 +163,18 @@ func newRevisionThrottler(revID types.NamespacedName, | |
| revBreaker breaker | ||
| lbp lbPolicy | ||
| ) | ||
| if containerConcurrency == 0 { | ||
| switch { | ||
| case containerConcurrency == 0: | ||
| revBreaker = newInfiniteBreaker(logger) | ||
| lbp = randomChoice2Policy | ||
| } else { | ||
| case containerConcurrency <= 3: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we have benchmarks that warrant this switch? I.e. have we tried round robin for the lower CC values?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. well the benchmark above shows that full first is better even on code level. Given that pods might be shared (if we don't divide evenly) in case of lower cc we prefer to use the pods at the tail less, since they might be shared, causing queueing. |
||
| // For very low CC values use first available pod. | ||
| revBreaker = queue.NewBreaker(breakerParams) | ||
| lbp = firstAvailableLBPolicy | ||
| default: | ||
| // Otherwise RR. | ||
| revBreaker = queue.NewBreaker(breakerParams) | ||
| lbp = newRoundRobinPolicy() | ||
| } | ||
| return &revisionThrottler{ | ||
| revID: revID, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.