Description
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!