Dynamic Dispatch / Classic Wrapper for MakeService is surprisingly non-trivial #10
Description
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 extra where
constraints are sufficient. But, with multiple layers, it seems to require not only async_fn_in_trait
but also return_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. ↩