How can a sender send itself in a flume channel

Hello,

I just finished the book "the rust programming language" and i am now working on a WebSocket server.

I am trying to make it impossible to send two messages in a row: It should receive a message and send one.

I created an object that looks like this.

pub struct Connection {
    id : u128,
    event_sender: Sender<Event>,
    socket : Socket
}

The event_sender sends back a notification to the main thread (either connection created, message received, or connection closed)

The socket is what makes me able to interact with the client, and here is my problem, all the implementation of connection are mut self, so they always consume the connection.

And my idea was to send the connection inside the notification so when the connection comes into the main thread; the main thread can do
connection.send(message) and the connection will be consumed and waiting for a new message to be received.

The big problem is here :


    fn send_connection_opened_notification(mut self) {
        self.event_sender.send(Event::ConnectionOpened(self).expect("Could not send a message back to the main thread");
    }

    pub async fn send_message(mut self, message: String){
        self.socket.send(Message::Text(message)).await.expect("Message could not be sent");
        self.handle_next_msg();
    }

} 

So I wanted the connection to be passed back and forth without the possibility of sending two messages in a row.

I am trying to move the connection itself through a channel.
I want the connection to be consumed, Is there any ways?
Do I have to think about the design again?

I found this solution to be elegant.

Thank you a lot

Sending the Connection through its own sender should work without much problems. You’ll probably just need to clone the sender before sending the connection.

    fn send_connection_opened_notification(self) {
        self.event_sender.clone().send(Event::ConnectionOpened(self).expect("Could not send a message back to the main thread");
    }

If you have further problems, it’s useful if you provide the error message :wink:

Thank you a lot ! :smiley:

I am so sorry FYI, here it is :

error[E0505]: cannot move out of `self` because it is borrowed
  --> src/socket_manager.rs:73:56
   |
73 |         self.event_sender.send(Event::ConnectionOpened(self)).expect("");
   |         -----------------------------------------------^^^^--
   |         |                                              |
   |         |                                              move out of `self` occurs here
   |         borrow of `self.event_sender` occurs here

For more information about this error, try `rustc --explain E0505`.

Your solution is working perfectly !

And as the connection takes self as an argument, the clone value will be dropped anyway right ?

I imagine there is no way to make it work without cloning right ?
Cause I was wondering if I could send a reference of self to the main thread, and somehow dereference it the main thread, while the original value would be dropped at the end of send_connection_opened_notification

Yes, the clone of the sender will be dropped right after its used.

By the way, it’s not much overhead either, it will update one counter for the number of senders and clone one Arc, as far as I can tell looking at the implementation. Dropping the sender will then drop the clone of the Arc and decrement that counter again.