Skip to content
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

Sends seem to be buffered #246

Open
bemug opened this issue Dec 27, 2022 · 3 comments
Open

Sends seem to be buffered #246

bemug opened this issue Dec 27, 2022 · 3 comments

Comments

@bemug
Copy link

bemug commented Dec 27, 2022

Might be a noob question, I'm learning Rust.

When using tokio::time::sleep to delay each send_privmsg, it sends them all at once instead of sending one, then delaying, then sending one, etc.
Here is a reporducing example, where you can see all message got sent at once after waiting for 5 seconds.

use futures::prelude::*;
use irc::client::prelude::*;
use tokio::time::{sleep, Duration};

#[tokio::main]
async fn main() -> irc::error::Result<()> {
    let config = Config {
        [...]
    };

    let mut client = Client::from_config(config).await?;
    client.identify()?;

    let mut stream = client.stream()?;
    let sender = client.sender();

    while let Some(message) = stream.next().await.transpose()? {
      match message.command {
        Command::PRIVMSG(ref target, ref msg) => {
          for i in 0..5 {
            sender.send_privmsg(target, i)?;
            sleep(Duration::from_secs(1)).await;
          }
        }
        _ => (),
      }
    }

    Ok(())
}
@bemug bemug changed the title Sends seems to be buffered Sends seem to be buffered Dec 28, 2022
@Sildulir
Copy link

Sildulir commented Feb 3, 2023

Might be a noob question, I'm learning Rust.

This behavior is somewhat surprising unless you understand exactly what this crate is doing so no it isn't a noob question.

In short this crate make it so that the send_<message_type>() and send() methods are simply sending the message to an Outgoing future that might send them the next time it is poll-ed. By default, when you make a ClientStream, the Outgoing is polled by the poll_next() method of the ClientStream (so the next time your application is looking for an incoming message).

Therefore the only time messages can be sent is at the start of the next loop iteration (it will then send as many messages as possible without any waiting in between). Hence the behavior you see.

Therefore the solution would be to separate the Outgoing prior to making the stream (with the ougoing() method of Client) and driving it in a separate thread (see tokio::spawn().

I personally believe that sends should just send the message through the network connection instead of using such a scheme but there probably is a reason not to do that here... (might be historical though)

@8573
Copy link

8573 commented Feb 3, 2023

I personally believe that sends should just send the message through the network connection

I wonder whether the synchronous API in version 0.13 would work for this. (I imagine one would be giving up something by using 0.13 rather than 0.15, but I don't remember what.)

@aatxe
Copy link
Owner

aatxe commented May 22, 2023

The design is definitely historical, and I'd welcome PRs looking to fix it. It might be something I look at myself if I can find the time, as well.

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

No branches or pull requests

4 participants