New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EAGAIN / socket::send #240
Comments
Hey @fabienjuif I believe you have to use bitwise OR ( |
Hey @kysely ! Thank you for your help, so you are right about socket.send(&worker_name, zmq::SNDMORE | zmq::DONTWAIT).expect("send should work 1");
socket.send("", zmq::SNDMORE | zmq::DONTWAIT).expect("send should work 2"); // TODO: this could be removed!
socket.send(&task.payload, zmq::DONTWAIT).expect("send should work 3"); I never goes in my expects sadly 😢 https://github.com/fabienjuif/zeromq-rs-tryout/blob/master/src/main.rs#L149 |
I did a little video to show you the issue I have: https://i.imgur.com/63ncAbx.mp4
|
Hmm, I overlooked this at first, but When ROUTER can't deliver the message (either unknown identity or full send buffer), it simply drops the message. It never blocks (thus you can't use the DONTWAIT flag). You can check against the official zmq_socket docs, “action in mute state” section. |
I also made a toy example just to make sure. I intentionally set the high-water mark for send buffer to 1 message so that we hit the mute state when trying to send 2 messages. You'll see the ROUTER successfully finishes because when it cannot buffer the first message for sending out (due to unknown identity), it simply drops the message. On the other hand, DEALER successfully saves the first message into the send buffer, however it cannot do the same with the second message (due to high-water mark). Because we use DONTWAIT flag, it expectedly returns an error (if we didn't use DONTWAIT, it would simply block at use zmq;
fn router_example(ctx: &zmq::Context) {
let sock = ctx.socket(zmq::ROUTER).unwrap();
sock.bind("tcp://*:5555").unwrap();
// set send buffer to 1 message so that we enter “mute state”
// when trying to send out more than 1 msg
sock.set_sndhwm(1).unwrap();
println!("\nRunning ROUTER example");
let mut i = 0;
while i < 2 {
println!("Sending out msg #{:?}...", i);
sock.send("IDENTITY", zmq::DONTWAIT | zmq::SNDMORE).unwrap();
sock.send("HEADER", zmq::DONTWAIT | zmq::SNDMORE).unwrap();
sock.send("PAYLOAD", zmq::DONTWAIT).unwrap();
println!("Message #{:?} sent", i);
i += 1;
}
}
fn dealer_example(ctx: &zmq::Context) {
let sock = ctx.socket(zmq::DEALER).unwrap();
sock.connect("tcp://localhost:5555").unwrap();
// set send buffer to 1 message so that we enter “mute state”
// when trying to send out more than 1 msg
sock.set_sndhwm(1).unwrap();
println!("\nRunning DEALER example");
let mut i = 0;
while i < 2 {
println!("Sending out msg #{:?}...", i);
sock.send("HEADER", zmq::DONTWAIT | zmq::SNDMORE).unwrap();
sock.send("PAYLOAD", zmq::DONTWAIT).unwrap();
println!("Message #{:?} buffered", i);
i += 1;
}
}
fn main() {
let ctx = zmq::Context::new();
router_example(&ctx);
dealer_example(&ctx);
} |
Hm ok, surprisingly it works the way I described it with the js binding 🤔 : if send doesn't find the worker it drops an error. I will re-read your response and read the pointer on doc you give me. Did you get the concept of what I tried to achieve? Thank you again! |
I quickly looked at your JS load balancer and there is one important difference. You enabled
By default, ROUTER drops message if it cannot resolve the host or the send buffer is full. However with ZMQ_ROUTER_MANDATORY, you enforce the address to be send-able, otherwise raise an error. You can do the same in Rust via socket.set_router_mandatory(true).unwrap(); |
Yo very nice I forgot about it thank you!! |
I think we've proven this is not a |
Sure, I wanted to test it first. |
Nice ! Thank you @kysely 😄 |
Hi 👋!
As you can see here, I tried to write a custom broker:
The JS version hangs for some reason, I wanted to try with Rust because I don't know if this is the JS binding or a poor code design from my side.
But I rely on
socket::send
to returns an error if the message can't be send (it helps me considerer a worker is dead, and try to send the task to an other).At this point,
socket::send
doesn't seems to send an error if message can't be delivered (I tried with and without flagzmq::DONTWAIT
.My socket is in ROUTER mode (
SocketType::ROUTER
).With this code, if I kill the "worker" process, there is no error:
Same for this code:
Is it something I don't understand or this is a known lack from
rust-zmq
?Versions:
Thank you!
The text was updated successfully, but these errors were encountered: