I’m writing a client of our home made protocol. My client has to send request and wait response. I don’t want to wait indefinitely so I want to wait a specific time or I want to be able to cancel the request if needed to unblock my client (if I want to close the application for example).
To do that, I’m using mio to be able to have events. Here is a small example of what it looks like. The problem comes with mio::Registration, you can’t register the same object to two differents poll, even if the previous poll doesn’t exist anymore. Even if I use poll.deregister(…). I found this : https://github.com/carllerche/mio/issues/506 Maybe it makes sense for channel/socket, but does it here ? The following example crashs on
poll.register(registration, Token(1), Ready::readable(), PollOpt::edge()).unwrap();
for the second call to wait_response. The error is : error: StringError(“registration handle associated with another Poll
instance”)
I don’t want to create a different Registration/SetReadiness for each call. So how can I cancel different loop with the same registration object ?
Here is the code example :
extern crate mio;
extern crate mio_extras;
use std::time::Duration;
use mio::{Ready, Events, Registration, Poll, PollOpt, Token, SetReadiness};
use mio_extras::Timer;
fn main() {
let (registration, set_readiness) = Registration::new2();
let client = Client{};
client.send_req1(Duration::from_secs(2), ®istration).unwrap();
client.send_req2(Duration::from_secs(2), ®istration).unwrap();
}
struct Client;
impl Client {
pub fn send_req1(&self, timeout: Duration, registration: &Registration) -> Result<(), ()> {
//Send req
self.wait_response(timeout, registration)?;
Ok(())
}
pub fn send_req2(&self, timeout: Duration, registration: &Registration) -> Result<(), ()> {
//Send req2
self.wait_response(timeout, registration)?;
Ok(())
}
fn wait_response(&self, timeout: Duration, registration: &Registration) -> Result<(), ()> {
let poll = Poll::new().unwrap();
let mut timer = Timer::<()>::default();
timer.set_timeout(timeout, ());
poll.register(&timer, Token(0), Ready::readable(), PollOpt::edge()).unwrap();
poll.register(registration, Token(1), Ready::readable(), PollOpt::edge()).unwrap();
// Create storage for events
let mut events = Events::with_capacity(1024);
loop {
poll.poll(&mut events, None).unwrap();
for event in events.iter() {
match event.token() {
Token(0) => {
println!("TIMEOUT");
return Ok(());
},
Token(1) => {
println!("CANCEL");
return Ok(());
},
_ => {unreachable!()}
}
}
}
}
}