-
-
Notifications
You must be signed in to change notification settings - Fork 1
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
Dynamic Dispatch / Classic Wrapper for MakeService is surprisingly non-trivial #10
Comments
Given it is a feature request I assume it is so that you cannot contribute this yourself either due to lack of time or feeling stuck? What’s the use case for this? As in my usage I don’t really need boxed services? |
I got completely stuck in the process and ended up switching to standard Tower for orchestrating stacks of services, after converting them using the I ended up needing dynamic dispatch in the architecture of a plugin system, but I also found that the Send-bounds bug in the compiler can be alleviated through boxing. |
Ok thank you for taking the time @Dessix to report and elaborate on this. For now I have no time or motivation to really work on this, but I do welcome contributions about it. As I said I am already working fine in production with Next |
Works for me- though with the send bounds issues still active in the compiler, async trait fns being marked "stable" may have been a bit premature. |
Well.. Not sure about that. For many use cases it is already possible. E.g. in my case I do need it as long as stuff like But yeah I do agree that there are probably also plenty of use cases like yourself. That said I think the real stability will be there in Rust 2024 I guess. Until then it will be a bit awkward I think. |
That appears to viably cover my use cases; Is there a chance you'd be willing to provide a type alias for Boxed For future PRs, something like |
Would you be willing to contribute this? I'm not entirely sure I am following 😓 . |
Hmmm... I think I was too optimistic... Which would make it very experimental for much longer... |
Mind flagging it under a |
Added a nightly feature in the current PR. I think I screwed it up a bit so far though. Might need to have a fresh look at some point later. Problem is that the Send/Sync bounds are a requirement that leak through everywhere... |
After reading through the newest announcements at https://blog.rust-lang.org/2023/12/21/async-fn-rpit-in-traits.html and discussing it on other channels I think it is clear that the time is not yet ready for tower to be async. Implementing this fork has been a great learning experience for me, but for now I'm going to cut my losses on it, as it is starting to cost me a lot more in terms of resources then the benefits I was hoping to get out of it. I do not plan to archive this repo however as I am continuing to opening this up to others to help experiment with this code, both by using it, as well as adding missing features or even making entirely new design proposals. All can be used to feed back into the rest of ecosystem and tower. Be it in the form of ideas or code. In the meanwhile I'm going myself to switch back to tower itself so I can spend my tower-async time on more contribution time on tower itself. Last reason why is because it became also clear that it might not even be certain that this kind of design approach of tower-async is the future of tower. As it might well in a very different direction. So for now, nice as it was, I'll no longer be actively developing on this repo. I'll remain however still available to you and others who are interested in tower-async, and gladly mentor and help others with contributions to it :) Also still happy to have discussions about it over discord. |
The Problem
With the current lack of object-safety on async traits1, Dynamic Dispatch on Service instances can only be achieved by converting to classic Tower traits for boxing.
With a single layer,
into_classic()
,tower::ServiceExt::boxed()
, and a few extrawhere
constraints are sufficient. But, with multiple layers, it seems to require not onlyasync_fn_in_trait
but alsoreturn_type_notation
to achieve, which then massively convolutes usage at the call site.Even with all of this, I've only managed to come up with a non-generic wrapper for my individual use case, which continues to be difficult to utilize due to a large number of impenetrable trait solver failures.
Feature Request
An API for correctly boxing via classic-service wrappers would be very helpful, especially if it can handle the multi-layer boxing problem2 involved in boxing a
tower_async::MakeService
.If it ends up being nightly-only due to a requirement on
return_type_notation
, that would still be very nice even behind a feature flag.Footnotes
As mentioned in the RFC to stabilize it, with no active or draft RFC to add
dyn-async-traits
, so far as I am aware. The tracking issue for eventual work on this is Tracking Issue for Async Functions in Dyn Traits rust-lang/rust#107011. ↩My attempt to do so with an intermediate
MapResponse
call to box the outgoing services was, as mentioned above, unsuccessful. ↩The text was updated successfully, but these errors were encountered: