-
Notifications
You must be signed in to change notification settings - Fork 281
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
Disarming Service after successful poll_ready #408
Comments
@mitsuhiko hey sorry for the late reply here, I think this is some potential here. By chance have you played around with an API like this yet? |
I came up with a common use-case for this in The issue arises in the context of non-buffering wrappers that are generic over impl Future {
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
loop {
ready!(self.service.poll_ready(cx)?);
let next = ready!(self.requests.poll_next(cx));
self.service.start_send(next)?;
}
}
} Great, no buffering! The challenge arises in the contract of What we need (as observed in this issue) is some way to "give up" ("disarm" seems like a good name for it) a |
Related issue for |
I agree that this is important but I am struggling to see how we could get this out into a trait easily. I also worry about our current users of tower like hyper which would require an entire ecosystem bump again. |
I'll add to this that there is only a small number of |
@LucioFranco I ran into this again and came back to this issue. You're saying there is a concern in retrofitting this without breaking the ecosystem. Since a disarm could have an empty default implementation wouldn't it be a somewhat safe change if nobody implements this for a while? |
@mitsuhiko the issue with a default is that with composition they would need to forward the inner implementation which is impossible and error prone to do with a default impl. That said, I think we could start exploring a new trait on nightly w/ this addition. The ecosystem is getting in a solid spot now that we can focus on the next iteration. cc @davidpdrsn |
I agree! Would be cool to starting thinking about concrete designs. |
Currently if
poll_ready
returnsReady
it effectively reserves something (for instance a semaphore token). This means you must be following up withcall
next. The only other option is toDrop
the service which however is not always possible.It was mentioned in the tokio repo that it would be useful to be able to disarm a service (tokio-rs/tokio#898).
This would be particularly useful when one wants to implement an HTTP health check for a load balancer by checking
poll_ready
without actually calling.Example:
And then be used like this:
The proposed new flow would be the following:
poll_ready
must be called. If it'sReady
it must be followed up with eithercall
ordisarm_ready
.call
must not be called withoutpoll_ready
being called beforedisarm_ready
may always be called and should undo whatpoll_ready
didClone
is supposed to either internally calldisarm_ready
or do the same it does (a Clone should always be disarmed)The latter is already the logic that exists in some layers.
Now obviously it's a bit suboptimal that it means not all services will be able to disarmed so it might also be possible to indicate if something can actually be disarmed. For instance already existing services might just not ever be disarmable until they get retrofitted.
The text was updated successfully, but these errors were encountered: