-
Notifications
You must be signed in to change notification settings - Fork 282
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
Make poll_ready() return a token which call() consumes #412
Comments
I agree that this API is much more misuse resistant and would enable disarm. That said, I think as of now none of us have the current bandwidth to refactor the code into this. I think we are mostly waiting for GAT to arrive to do the last and final version of tower. So as of now I think we will stick with the current API since, we a lot of use have it deployed already in production 😄. I'd love to see what a PoC of this would look like though! cc @davidbarsky I know you've brought this one up a lot. |
@LucioFranco This is a pretty mechanical refactor: willglynn@44de76e All this boils away entirely if It also seems to me that making a change like this in I'd be happy to continue plumbing this through the other crates if there's interest in merging it. |
I think the plan for the next breaking change for cc @carllerche id love to hear your thoughts |
Why does this need GAT to be implemented? update: I found it on discord: only issue is how you tie the token to self to disarm on drop without GAT |
Would be nice to see that implemented, now that GATs are there. |
Current API makes it way too easy to introduce race conditions, and the proposed change with explicitly attaching reserved resource(s) to the token seems like a good way to address this issue. For instance, in reqwest/issues/491 it was suggested to put Separately, another feature that |
It's been too tedious to ensure correct usage of current services. This change can make it trivial and rusty in using compiler to ensure proper usage. As GATs are now stable, it would be great if proposal is considered. |
Now that GATs are stable, this would be a great change that would make tower's idioms more "rust-y" |
Currently,
Service
contains:Convention requires that the user call
poll_ready()
, and only when it returnsPoll::Ready(Ok(()))
is the user permitted to callcall()
.call()
is permitted to panic if misused.If we introduce token – an opaque type which the user cannot construct – we can instead say:
Now the type system enforces the required call sequence. The user must call
poll_ready()
and receive aPoll::Ready(Ok(token))
, sincecall()
now requires such atoken
to accompany each request.This pattern has benefits beyond just preventing API misuse. The token type could itself hold the resources necessary to handle a request, like a lock on a table slot or a connection checked out from a connection pool. In other words, this proposal reduces the TOCTOU raciness of the
poll_ready()
->call()
dance.A token also provides an alternative to the disarming mechanism proposed in #408: a user who got a
Poll::Ready(Ok(_))
may either return their token to the service viacall()
, or they may forfeit the opportunity to make a request by dropping their token. Just as type system can guarantee the correct flow betweenpoll_ready()
andcall()
, the ownership system can guarantee use-it-or-lose-it semantics for everyPoll::Ready(Ok(_))
response, ensuring services can all reliably distribute and reclaim per-request resources.The text was updated successfully, but these errors were encountered: