prost
prost copied to clipboard
Support for `std::sync::Arc` as indirection
Hi, I wonder, would be possible to allow prost-types to be wrapped inside std::sync::Arc
? The reason is that I want my messages to be sendable across both processes and threads. When sent across processes, my messages should be serialized/deserialized with prost
. When sent across threads, I would like to use reference counting.
#[derive(prost::Message)]
struct MyMessage {
#[prost(string, tag = "1")]
label: Arc<String>,
#[prost(message, tag = "2")]
payload: Arc<Payload>,
}
#[derive(prost::Message)]
struct Payload {
#[prost(i32, repeated, tag = "1")]
stuff: Vec<i32>,
}
Thanks for the great crate.
This would also be nice in conjunction with Tonic servers. If we had
something analogous to bytes
or btree_map
, like:
Config::new()
.arc(&[".my_service.FooRequest.my_big_field"])
.compile_protos(...)
…then we could get away with fewer wasted clones in RPC handlers.
I think that this might be nice, but am not strongly lobbying for it, and wouldn’t be too upset if it were wontfixed.
Sounds like a good addition! We should probably also support Box
and Rc
similarly.
This could also be helpful (I think) for cases where a large object is received in the request and needs to outlive it. Allowing that object to be an Arc
would allow it to be taken outside the request/response lifetime without copying.
🤔Seems it's possible to implement the feature, I'll try this.
will this be on the road map?
Sounds like a good addition! We should probably also support
Box
andRc
similarly.
Rc
cannot be supported since prost::Message
requires Send + Sync
Yeah I can here just to comment/upvote this. I'm trying to use a watch with tonic and I need to clone the message that hits each receiver because arc isn't supported. I can probably modify some of the generated code.
I can probably modify some of the generated code.
@jasongoodwin do you happen to have an implementation for this? I'm in a similar position, only the data I'm sending can get quite large.
Rc cannot be supported since prost::Message requires Send + Sync
Honestly... why does Message
require Send + Sync
? I peeked at the associated functions and there didn't seem any reason for it.
It's actually blocking me for another reason: I tried implementing Message for Cow<str>
. I can logically encode and decode a Cow<str>
into proto string
:
- Encoding is easy, it can borrow basically all of string encoding infrastructure.
- Decoding is not bad either:
- If it's an empty string, then decode it as
Cow::Borrowed("")
. - If it's not an empty string, then decode it as
Cow::Owned
String
.
- If it's an empty string, then decode it as
But due to the requirement of Message
to be Send + Sync
, it doesn't matter.
The requirement of Send
is particularly odd, because I would think serializing to protobuf is one way you can send non-Send types to other threads...