-
Notifications
You must be signed in to change notification settings - Fork 263
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
balance: Only balance over ready endpoints #293
Conversation
In 03ec4aa, the balancer was changed to make a quick endpoint decision. This, however, means that the balancer can return NotReady when it does in fact have a ready endpoint. Furthermore, testing shows that while this approach does have about 10% beter CPU utilization, it has about 25% worse throughput when communicating with a busy service. This changes the balancer to segregate unready endpoints, only performing p2c over ready endpoints. Unready endpoints are tracked with a FuturesUnordered that supports premature eviction via oneshots. The main downside of this change is that the Balancer must become generic over the Request type. Fixes tower-rs#292
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strategy seems good to me. I left one inline comment re: naming that caused confusion while I was reading, but afaik, the strategy is sound. We can improve the details of the impl once we update to std future as how tasks are tracked will change.
Also, ccing @jonhoo |
Sorry it took me so long to get to this @olix0r! This looks like an excellent change, though I do have some questions I'd like to resolve before merging. Most of them are around adding comments for some of the more complex interactions (and to check my own understanding). |
@olix0r depending on how busy you are, I can also take on pushing this over the finish line as I'd like to have it for some work-related stuff :) |
@jonhoo I should have a chance today to push another iteration. Thanks, though! |
@jonhoo I do take your general point about this polling perhaps excessively. I do think it's important for us to eagerly poll a selected endpoint immediately before a request is dispatched to it, but i do think we can accomplish this with a slightly more relaxed strategy. Let me try something... |
I'd also be okay with merging this as-is now and then do optimizations in a follow-up PR. Up to you :) |
@jonhoo PTAL; that change allowed us to remove some of the uglier code in there (repairing indexes). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that looks great!
tower-rs/tower#288 and tower-rs/tower#293 changed the Balance implementation substantially. Now, a new layer, `spawn_ready` is inserted around endpoint stack to ensure that readiness is driven on a background task. In support of this change, the `pending` layer was removed from the endpoint stack and, instead, the discovery system is now responsible for driving pending services to be materialized.
In tower-rs#293, `balance` was refactored to manage dispatching requests over a set of equivalent inner services that may or may not be ready. This change extracts the core logic of managing a cache of ready services into a dedicated crate, leaving the balance crate to deal with node selection. `ReadyCache` provides a default `Service` implementation, though this is just provided as convenience. The `Balance` service, for instance, uses `ReadyCache`'s APIs directly so that endpoint failure and endpoint exhaustion can be handled by the balancer.
In tower-rs#293, `balance` was refactored to manage dispatching requests over a set of equivalent inner services that may or may not be ready. This change extracts the core logic of managing a cache of ready services into a dedicated crate, leaving the balance crate to deal with node selection. `ReadyCache` provides a default `Service` implementation, though this is just provided as convenience. The `Balance` service, for instance, uses `ReadyCache`'s APIs directly so that endpoint failure and endpoint exhaustion can be handled by the balancer.
In tower-rs#293, `balance` was refactored to manage dispatching requests over a set of equivalent inner services that may or may not be ready. This change extracts the core logic of managing a cache of ready services into a dedicated crate, leaving the balance crate to deal with node selection. `ReadyCache` provides a default `Service` implementation, though this is just provided as convenience. The `Balance` service, for instance, uses `ReadyCache`'s APIs directly so that endpoint failure and endpoint exhaustion can be handled by the balancer.
In #293, `balance` was refactored to manage dispatching requests over a set of equivalent inner services that may or may not be ready. This change extracts the core logic of managing a cache of ready services into a dedicated crate, leaving the balance crate to deal with node selection.
In 03ec4aa, the balancer was changed to make a quick endpoint decision.
This, however, means that the balancer can return NotReady when it does
in fact have a ready endpoint. Furthermore, testing shows that while
this approach does have about 10% beter CPU utilization, it has about
25% worse throughput when communicating with a busy service.
This changes the balancer to segregate unready endpoints, only
performing p2c over ready endpoints. Unready endpoints are tracked with
a FuturesUnordered that supports premature eviction via oneshots.
The main downside of this change is that the Balancer must become
generic over the Request type.
Fixes #292