google / tarpc

An RPC framework for Rust with a focus on ease of use.
MIT License
3.09k stars 189 forks source link

Rkyv support? #437

Open comath opened 4 months ago

comath commented 4 months ago

I think it would be awesome if this supported zero-copy rkyv in addition to serde. It's a bit more complicated as the types the client and server operate on are different to the types in the trait definition. I'm moving types with large vectors and buffers around in my distributed application and rkyv saves a lot of time over bincode.

Here's a mockup:

#[tarpc::service]
trait Hello {
    async fn health(name: String) -> String;
}

This would derive a trait HelloRkyv which would be the zero-copy version of the serve trait for Hello. It would look something like this to implement

pub struct HelloEcho;
impl HelloRkyv for HelloEcho {
    async fn health(self, _: context::Context, name: &ArchivedString) -> String {
        format!("Hello, {name}")
    }
}

We can have a transport that deserializes the rkyv bytes so we can re-use the regular HelloClient. A zero-copy client would be different as it should also return archived values. These are borrowed from a buffer, so the buffer needs to also be returned. We'd need a RkyvBytes<T> { ... } struct that has a function that returns the archived value &Archived<T>.

pub struct HelloRkyvClient {...};
impl HelloRkyvClient {
    async fn health(self, _: context::Context, name: String) -> RkyvBytes<String>  {
}

There's a bunch of details to work out.

I'd like it to work out that if you have a server object like HelloEcho that implements both the normal server trait and the rkyv one that you can set up normal clients locally that don't need serialization, and rkyv clients remotely for things that do.

This might be something to fork from this, but it might done within this crate.