How to determine which connection I've read data on when using SelectAll

I'm putting together a command line utility that can monitor multiple instances of Redis concurrently using async/await. This works great, but I'm stumped as to how I would go about determining which connection a given bit of data is coming from.

Here's just the main routine for brevity.

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let args = std::env::args().skip(1).collect::<Vec<_>>();

    let mut connections = SelectAll::new();

    for arg in &args {
        let mut con = get_connection(arg.parse().unwrap()).await?;
        con.send(resp_array!["MONITOR"]).await?;
        let con = con.skip(1);
        connections.push(con);
    }

    // What should I wrap/implement so I can deliver context in 
    // addition to the message itself?
    while let Some(v) = connections.next().await {
        println!("{:?}", v);
    }

    Ok(())
}

How would I go about wrapping this data such that I could get not just the data itself but context as to which connection it came from?

As it happens, I can solve this issue by just parsing the MONITOR messages as they contain the IP/port information I would need, but I'm curious as to how I would go about this generally.

If it helps the RespConnection uses a Framed TcpStream to parse the RESP messages.

Link to complete Repository

The documentation for select_all says that the future yields the index of the selected future.

1 Like

Using StreamExt::map, you can change the type of stream into one that returns some extra data along with each item. You can then inspect this piece of data to figure out which stream sent it.

connections.push(con.map(|item| (item, extra)));
2 Likes

That worked perfectly, thank you! :hugs: