pub trait AsyncHostedRpcDep:
Send
+ Sync
+ 'static {
type Stub: Send + Sync + 'static;
// Required methods
fn dispatch<'a>(
&'a mut self,
method_idx: u32,
args: &'a [u8],
) -> impl Future<Output = Result<Vec<u8>, String>> + Send + 'a;
fn build_stub(channel: HostedRpcChannel) -> Self::Stub;
}Expand description
Async counterpart of HostedRpcDep. Implement this when the owner-side
method dispatcher needs to .await (e.g. controlling subprocesses, holding
tokio::sync locks, calling other async APIs).
No opt-in flag is required: under the tokio test runtime the runtime
always routes HostedRpc dispatch through AsyncHostedRpcDep, regardless
of whether the user wrote impl HostedRpcDep (covered by the blanket
bridge below) or impl AsyncHostedRpcDep directly. The #[hosted_rpc]
macro mirrors this transparency: if any trait method is async fn, the
generated dispatcher is async, otherwise it stays sync.
build_stub stays synchronous and the worker-side stub still calls a
synchronous HostedRpcChannel::call in its method bodies, exactly as
in HostedRpcDep; the only difference is that owner-side dispatch
returns a Future so it can await.
Required Associated Types§
Sourcetype Stub: Send + Sync + 'static
type Stub: Send + Sync + 'static
The worker-side handle type that tests parameterise on. Same shape
as HostedRpcDep::Stub.
Required Methods§
Sourcefn dispatch<'a>(
&'a mut self,
method_idx: u32,
args: &'a [u8],
) -> impl Future<Output = Result<Vec<u8>, String>> + Send + 'a
fn dispatch<'a>( &'a mut self, method_idx: u32, args: &'a [u8], ) -> impl Future<Output = Result<Vec<u8>, String>> + Send + 'a
Owner-side: handle one method call asynchronously. method_idx is the
per-method index assigned by the implementor / #[hosted_rpc] macro;
args is the worker-supplied serialized payload.
Sourcefn build_stub(channel: HostedRpcChannel) -> Self::Stub
fn build_stub(channel: HostedRpcChannel) -> Self::Stub
Worker-side: build a Self::Stub over the channel that connects
back to the parent’s owner. Identical contract to
HostedRpcDep::build_stub.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".
Implementors§
Source§impl<T> AsyncHostedRpcDep for Twhere
T: HostedRpcDep,
Blanket bridge: every HostedRpcDep is automatically also an
AsyncHostedRpcDep. The bridged dispatch returns
std::future::ready so the bridge itself adds only an
immediately-ready future and the tokio runtime can await all HostedRpc
dispatch uniformly.
impl<T> AsyncHostedRpcDep for Twhere
T: HostedRpcDep,
Blanket bridge: every HostedRpcDep is automatically also an
AsyncHostedRpcDep. The bridged dispatch returns
std::future::ready so the bridge itself adds only an
immediately-ready future and the tokio runtime can await all HostedRpc
dispatch uniformly.
This lets the test-r runtime drive every HostedRpc dispatch through
one async path under the tokio runtime, regardless of whether the
owner’s own implementation is sync (impl HostedRpcDep for ...) or
async (impl AsyncHostedRpcDep for ...). No annotation flag is needed
on #[hosted_rpc] or #[test_dep]; the implementor picks sync vs
async purely at the trait-impl call site.
Coherence note: on stable Rust, with this blanket impl in place
a concrete owner type cannot manually implement both HostedRpcDep and
AsyncHostedRpcDep — rustc rejects that as conflicting implementations.
That compile-time error is the intended signal that one of the two manual
impls is redundant and should be removed.
Source-compat note: if downstream code imports both
HostedRpcDep and AsyncHostedRpcDep into the same scope and calls
trait methods by method syntax (e.g. MyOwner::build_stub(channel)
or owner.dispatch(idx, args)), the call can become ambiguous now
that one type satisfies both traits. Resolve with UFCS —
<MyOwner as HostedRpcDep>::build_stub(channel).