aatxe / irc

the irc crate – usable, async IRC for Rust
Mozilla Public License 2.0
530 stars 97 forks source link

Decouple connecting from creating a server object? #103

Closed fizyk20 closed 6 years ago

fizyk20 commented 6 years ago

It would be nice if the creation of an IrcServer and connecting to it were separate.

I want to run the IRC client in a separate thread, but still be able to send messages etc. from the main thread. If I understand the design correctly, this means that I can create an IrcServer, clone it and move one of the clones into the newly spawned thread. The problem here is that since the creation of IrcServer immediately connects, it will block the main thread (am I right? I haven't actually checked it yet...). I would like the connection itself to happen in the separate thread already, but if I create the IrcServer inside the thread, I have no way of passing a clone of it outside.

Therefore, it would be nice if something like this was possible:

let server = IrcServer::from_config(config).unwrap();
let thread_server = server.clone(); // for passing into the thread
let thread = thread::spawn(move || {
    thread_server.connect();  // main thread isn't blocked!
    thread_server.for_each_incoming(|message| {
        //...
    }).unwrap();
});

If I'm wrong anywhere or if you have any other solution for that, I'll be glad to learn about it, too :)

fizyk20 commented 6 years ago

Lesson for me: look into the code first, ask later. I checked and of course the connection happens in a separate thread already, so the problem is non-existent. Sorry for the mess!

aatxe commented 6 years ago

In spite of the fact that the library does what you want in terms of being async and allowing you to send messages without blocking the main thread, I wanted to note that it is sort of possible to create an IrcServer without connecting right now. examples/nothreads.rs has an example of using IrcServer::new_future. In this case, you don't actually have the IrcServer yet (because the server requires a connection to actually exist), but you have a future that will eventually yield the IrcServer. This may be valuable for some use cases, though the primary reason for it existing is to control your own executor (and get more control over error-handling).

Also, perhaps another factor worth noting here is that the IrcServer's creation doesn't cause blocking anyway. It's only the use of for_each_incoming that will actually cause the thread to block.

fizyk20 commented 6 years ago

Right, I noticed the solution with futures, but I still don't feel too comfortable using them, so I preferred to leave it alone ;)

I also noticed that only for_each_incoming blocks, but only after posting the issue, which is why I closed it immediately :p

Thank you for your answer, though!