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

smol::spawn: BrokenPipe io::copy failed #237

Open
bbros-dev opened this issue Mar 11, 2022 · 0 comments
Open

smol::spawn: BrokenPipe io::copy failed #237

bbros-dev opened this issue Mar 11, 2022 · 0 comments

Comments

@bbros-dev
Copy link

We observe a stream of these errors:

Connection error: Custom {
    kind: BrokenPipe,
    error: VerboseError {
        source: Os {
            code: 32,
            kind: BrokenPipe,
            message: "Broken pipe",        },
        message: "io::copy failed",
    },
}

when running rewrk --json -t 12 -c 500 -d 30s -h http://127.0.0.1:3000 against this simplified version of the examples/async-h1-server (with tls removed):

use std::net::TcpListener;

use anyhow::Result;
use http_types::{Request, Response, StatusCode};
use smol::Async;

/// Serves a request and returns a response.
async fn serve(_req: Request) -> http_types::Result<Response> {
    let mut res = Response::new(StatusCode::Ok);
    res.insert_header("Content-Type", "text/plain");
    res.set_body("Hello, World!");
    Ok(res)
}

/// Listens for incoming connections and serves them.
async fn listen(listener: Async<TcpListener>) -> Result<()> {
    loop {
        // Accept the next connection.
        let (stream, _) = listener.accept().await?;

        // Spawn a background task serving this connection.
        let stream = async_dup::Arc::new(stream);
        let task = smol::spawn(async move {
            if let Err(err) = async_h1::accept(stream, serve).await {
                println!("Connection error: {:#?}", err);
            }
        });

        // Detach the task to let it run in the background.
        task.detach();
    }
}

fn main() -> Result<()> {
    // Start HTTP server.
    smol::block_on(async {
        let http = listen(Async::<TcpListener>::bind(([127, 0, 0, 1], 3000))?);
        http.await?;
        Ok(())
    })
}

There are no build errors. We have found that if instead we use a smol::Executor these errors go away.
Specifically, replace:

let task = smol::spawn(async move {
            if let Err(err) = async_h1::accept(stream, serve).await {
                println!("Connection error: {:#?}", err);
            }
        });

        // Detach the task to let it run in the background.
        task.detach();

with:

let ex = smol::Executor::new();
        ex.spawn(async move {
            if let Err(err) = async_h1::accept(stream, serve).await {
                println!("Connection error: {:#?}", err);
            }
        })
        .detach();

We aren't sure if:

  • the example should just be updated,
  • we have used smol::spawn incorrectly
  • there is an issue with smol::spawn
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant