Skip to content

How to send generated readers across threads #479

Open
@f1recracker

Description

@f1recracker

Hello,

Thank you for this project! Also, apologies if this is a duplicate - I've found similar questions but I'm not quite sure if we're solving the same problem.

So I'm writing a program that consists of two threads:

  • Thread 1 deserializes data that's read from a socket, and stores some state in a shared collection. Note that the state written need not be the root of the message.
  • Thread 2 reads data from the shared collection.

I've been able to make an example of this using rust-native structs, but I just can't seem to figure out how to move to capnproto generated code. Here's a minimal example using the addressbook schema.

struct People {
    id: u32,
    // ...
}

pub fn main() {
    let result_map = std::sync::Arc::new(dashmap::DashMap::<String, People>::new());
    {
        // Thread 1
        let result_map = result_map.clone();
        let mut buffer = vec![];
        {
            let builder = build_address_book();
            serialize_packed::write_message(&mut buffer, &builder).unwrap();
        }
        {
            let reader = serialize_packed::read_message(
                std::io::Cursor::new(buffer), capnp::message::ReaderOptions::new()).unwrap();
            let address_book = reader.get_root::<address_book::Reader>().unwrap();
            let _people = address_book.get_people().unwrap().get(0);
            // How to avoid using a rust-native struct here and use `_people`?
            result_map.insert("foo".into(), People { id: _people.get_id() });

        }
    }
    {
        // Thread 2
        let result_map = result_map.clone();
        std::thread::spawn(move || {
            loop {
                match result_map.get("foo") {
                    Some(person) => {
                        println!("Person: {:?}", person.id)
                    },
                    None => {
                        std::thread::sleep(std::time::Duration::from_secs(1));
                    }
                }
            }
        });
    }
}

Specifically I have two questions:

  • How do I pass around generated readers (and any associated buffers) into collections to Send between threads?

  • Does this access pattern make sense in a capnproto world? Essentially I'm trying to manage the lifecycle of the buffer and associated Readers / Builders to provide views over an Arc<RwLock<_>>'d buffer.

Thank you!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions