erickt / rust-zmq

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

Send doesn't give back the message on EAGAIN #211

Open asonix opened 6 years ago

asonix commented 6 years ago

I'm attempting to write wrappers around this library for use with Tokio's event loop, and there are certain cases where it is important that the Message not be destroyed.

If Sendable::send() in 0.9 or Socket::send_msg() in 0.8 fail to send with EAGAIN, it just means the socket is currently busy, and we can try again, however, these methods both consume the Message and don't give it back, making it impossible to try again.

With my wrapper's current logic, this state should be impossible, but it is still possible to express this state with code, so I'd like to be able to properly handle it.

A possible solution could be to make Error::EAGAIN into Error::EAGAIN(Option<T>). T could be Message, but I haven't looked around ZeroMQ enough to know if there are other situations where this could be important.

rotty commented 6 years ago

Indeed, we have an issue here -- thanks for noticing :-).

Unfortunately, the zmq documentation (man zmq_msg_send) is not very explicit about what happens to the message in the error case (or EAGAIN specifically). However, reading between the lines, I guess the message is invalidated (nullified) only in the success case. This means that we should return the message in all failure cases, not only EAGAIN, so the return type of send needs to be std::result::Result<(), (zmq::Error, zmq::Message)>.

rotty commented 5 years ago

I'll wait for clarification from the libzmq team, but if that works out as suspected, this is clear to be fixed in master soonish, as I'm about to introduce API-breaking changes again soon.