erickt / rust-zmq

Rust zeromq bindings.
Apache License 2.0
887 stars 190 forks source link

Implement io::Read & io::Write #238

Closed jean-airoldie closed 5 years ago

jean-airoldie commented 5 years ago

Hi,

Is there any specific reason why io::Read and io::Write is not implemented for zmq::Socket? I can implement io::Read using zmq::Socket::recv_into but not io::Write since there is no send method that provides the number of bytes written.

birkenfeld commented 5 years ago

I don't think Read and Write are a good conceptual fit for zmq sockets. They are meant for continuous streams, while zmq very much emphasizes (and guarantees) the discrete nature of each message sent.

jean-airoldie commented 5 years ago

They are required in order to implement the Stream and Sink traits and therefore fit in the general rust async ecosystem.

While the zmq crates offer async operations via the polling mechanism, it makes it hard to integrate zmq sockets alongside other types of streams. For instance, I have a specific use case where a server must poll asynchronously both a tcp stream and a zmq socket. This can be easily done if the socket implements Stream (I can simply merge the two streams via select), but it becomes a headache otherwise.

asonix commented 5 years ago

I wonder if a native-rust implementation of zeromq could work with a generic stream of bytes plus a zeromq tokio-codec on top...

I agree that ZeroMQ's concept of messages conflicts with the idea of reading and writing bytes, but I do know that it's possible to use zmq with tokio, as I'm the author of tokio-zmq and futures-zmq. These crates provide an abstraction of streams and futures on top of zmq, where the Stream::Item is a custom Multipart type, that represents a full multipart zmq message, whether that contains one or many individual zmq messages.

The reason I've created two crates that do the same thing is tokio-zmq uses unix-specific and tokio-specific code, while futures-zmq is OS agnostic and executor agnostic for the price of performance. The futures-zmq implementation uses a separate thread that polls a bunch of zeromq sockets, using channels to send messages back and forth to the chosen executor.

jean-airoldie commented 5 years ago

I wasn't aware that implementing io::Read could be done without modifying the rust-zmq code. And I agree that this trait shouldn't be publicly implemented since it contradicts the zmq message concept. I was just looking for a quick and dirty hack to allow integration into tokio.

jean-airoldie commented 5 years ago

@asonix I'll take a look at your crate.

asonix commented 5 years ago

@jean-airoldie I don't implement io::Read in my crates at all. I just build streams around the zmq::Message type