Skip to content

New lint suggestion: You're using a blocking operation when you could be using an async one #10794

Open
@omarandlorraine

Description

@omarandlorraine

What it does

A lint which checks for blocking functions inside an async block.

One I know of (and the cause of a bug I ran into today) is std::thread::sleep, but there are others. (file operations, networking, ...). If such a function has an async counterpart, then the user could be warned of this fact.

Lint Name

unwise-block

Category

suspicious

Advantage

  • warn of badly behaving async programs

Drawbacks

  • might be too noisy

Example

use std::thread::sleep;
use std::time::Duration;
use tokio::signal::unix::signal;
use tokio::signal::unix::SignalKind;
use tokio::sync::mpsc;

async fn rx(rx: &mut mpsc::Receiver<()>) {
    loop {
        sleep(Duration::new(1, 0));
        if rx.try_recv().is_ok() {
            println!("got one splivet");
        }
    }
}

async fn tx(tx: mpsc::Sender<()>) {
    let mut stream = signal(SignalKind::user_defined1()).unwrap();

    loop {
        stream.recv().await;
        println!("sending one splivet");
        tx.send(()).await.unwrap();
    }
}

#[tokio::main(flavor = "current_thread")]
async fn main() {
    let (stx, mut srx) = mpsc::channel::<()>(5);

    tokio::join!(tx(stx), rx(&mut srx));
}

Could be written as:

use std::thread::sleep;
use std::time::Duration;
use tokio::signal::unix::signal;
use tokio::signal::unix::SignalKind;
use tokio::sync::mpsc;

async fn rx(rx: &mut mpsc::Receiver<()>) {
    loop {
        tokio::time::sleep(Duration::new(1, 0)).await;
        if rx.try_recv().is_ok() {
            println!("got one splivet");
        }
    }
}

async fn tx(tx: mpsc::Sender<()>) {
    let mut stream = signal(SignalKind::user_defined1()).unwrap();

    loop {
        stream.recv().await;
        println!("sending one splivet");
        tx.send(()).await.unwrap();
    }
}

#[tokio::main(flavor = "current_thread")]
async fn main() {
    let (stx, mut srx) = mpsc::channel::<()>(5);

    tokio::join!(tx(stx), rx(&mut srx));
}

Note the different way to sleep in the rx function.

Metadata

Metadata

Assignees

Labels

A-lintArea: New lints

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions