Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading two blocking iterators

Tags:

rust

I'm using the Rust websocket library to talk to things and I have this thread that looks roughly like this:

thread::spawn(move || {
    while let Ok(Message::Text(text)) = receiver.recv_message() {
        /* Do some stuff */
    }
});

The above receiver can also be a blocking iterator:

thread::spawn(move || {
    for message in receiver.incoming_messages() {
        /* Do same stuff */
    }
});

I want to send a signal to this thread telling it to stop doing things. I thought a mpsc::channel would be great for this signal-sending. select! seemed like the way to go, but it only works if all the channels are mpsc::channel types.

Is there something that can join two blocking iterators and provide output as data comes in? Or any other solution to this issue? I'd like to avoid creating a thread for each source of input and managing my own queue.

like image 482
Michael Eden Avatar asked Nov 09 '22 05:11

Michael Eden


1 Answers

Is there something that can join two blocking iterators and provide output as data comes in? Or any other solution to this issue?

Although I certainly hope someone proves me wrong, I think the answer has to be "no". By definition, something that blocks will prevent any further work from being done on that thread. You'd need something that can distinguish between the states of "done", "nothing to read", and "something to read" and that cannot be built atop building blocks that only give two of those states.

I'd like to avoid creating a thread for each source of input and managing my own queue.

I do not see any way around this. Since a blocking iterator blocks the thread, having multiple threads allows you to add back the state of "nothing to read".

The better solution would involve making both input sources have all 3 states.

loop {
    if let Ok(Message::Text(text)) = receiver.recv_message() {
        // Do some stuff
    } else if let Err(TryRecvError::Disconnected) = kill.try_recv() {
        break;
    } else {
        // Something intelligent for the other cases?
    }
}
like image 107
Shepmaster Avatar answered Jan 04 '23 02:01

Shepmaster