Skip to main content

AsyncHostedRpcDep

Trait AsyncHostedRpcDep 

Source
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§

Source

type Stub: Send + Sync + 'static

The worker-side handle type that tests parameterise on. Same shape as HostedRpcDep::Stub.

Required Methods§

Source

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.

Source

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 T
where 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).