Skip to content

MessageResult borrow server in future select! #19

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

Open
tchamelot opened this issue Dec 26, 2021 · 0 comments
Open

MessageResult borrow server in future select! #19

tchamelot opened this issue Dec 26, 2021 · 0 comments

Comments

@tchamelot
Copy link
Contributor

I came back to an old project and updated this crate which I still find realy nice ;) (from 0.4.2 to 0.5.1).

I noticed that you changed the behavior of Server::recv to return MessageResult which seems to be a nice upgrade compared to handling the buffer on the user side. However, now the MessageResult borrows the Server for its (the MessageResult) whole lifetime because of the internal pool. Therefore, it is not possible to Server::send while a MessageResult is returned by select!. It took me a while to identify this in my code which was looking like

enum Incoming<'a> {
    Webrtc(MessageResult<'a>),
    Channel(...),
}
loop {
    let received = tokio::select! {
        msg = server.recv() => msg.map(|msg| Incoming::Webrtc(msg)),
        msg = receiver.recv() => msg.map(|msg| Incoming::Channel(msg)).ok_or(...),
    };
    match received {
        // ...
    }
    server.send(&some_bytes, MessageType::Binary, &client).await.unwrap()
} // loop end

the compiler gave an error looking like

    |
    |                   msg = server.recv() => msg.map(|msg| Incoming::Webrtc(msg)),
    |                         ------------------ first mutable borrow occurs here
...
    |               server.send(&some_bytes, MessageType::Binary, &client)
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ second mutable borrow occurs here
...
    |           } // loop end
    |           - first borrow might be used here, when `received` is dropped and runs the destructor for type `Result<RtcServer::run::{closure#0}::Incoming<'_>, std::io::Error>`

For me the solution was to parse the MessageResult and to return a different owned variant such as

enum Incoming {
    Webrtc(MyCustomOwnedPacket, SocketAddr),
    ...
}

loop {
    let received = tokio::select! {
        msg = server.recv() => msg.map(|msg| {
            let content = MyCustomOwnedPacket::from(msg.message.as_ref());
            Incoming::Webrtc(content, message.remote_addr)
        }),
        ...
    };
   ...
    server.send(&some_bytes, MessageType::Binary, &client).await.unwrap()
} // loop end

I am not asking for any changes, just putting this here because somebody might run into the same issue ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant