Hi. I wanted to implement my own backend selection (basically least connections), but faced some inconvenience and issues.
To address Inconvenience:
Moved BackendIter bound into BackendSelection::Iter.
It was only used with this bound everywhere anyway, even docs says that Iter should be BackendIter.
Can't see any reason why it's like that. Tested against rust 1.72 to verify that it satisfies msrv.
It doesn't break any existing code, just makes bound S::Iter: BackendIter redundant.
Issues:
selector field in LoadBalancer is private, but I needed to access it to share some handle that will be used to notify selector of pending upstream requests.
It's possible to achieve this by other means (either global state, but then it's hard to share code, or more api churn and changing public interfaces, which I don't want to do here).
When backends are updated new instance of BackendSelection is created and replaced, but to keep handle from previous selector I had to resort to global state. So I added previous: Option<Arc<Self>> argument that will be passed in LoadBalancer::update, so it's possible to keep provided handle or some other state. This is somewhat breaking change.
Hi. I wanted to implement my own backend selection (basically least connections), but faced some inconvenience and issues.
To address Inconvenience: Moved
BackendIter
bound intoBackendSelection::Iter
. It was only used with this bound everywhere anyway, even docs says that Iter should be BackendIter. Can't see any reason why it's like that. Tested against rust 1.72 to verify that it satisfies msrv. It doesn't break any existing code, just makes boundS::Iter: BackendIter
redundant.Issues:
selector
field inLoadBalancer
is private, but I needed to access it to share some handle that will be used to notify selector of pending upstream requests. It's possible to achieve this by other means (either global state, but then it's hard to share code, or more api churn and changing public interfaces, which I don't want to do here).When backends are updated new instance of
BackendSelection
is created and replaced, but to keep handle from previous selector I had to resort to global state. So I addedprevious: Option<Arc<Self>>
argument that will be passed in LoadBalancer::update, so it's possible to keep provided handle or some other state. This is somewhat breaking change.Related Issue: https://github.com/cloudflare/pingora/issues/144 Maybe later after my experiments will make a PR for least connections.