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

How to handle request cancelation? #123

Open
Dirbaio opened this issue Jun 19, 2020 · 3 comments
Open

How to handle request cancelation? #123

Dirbaio opened this issue Jun 19, 2020 · 3 comments

Comments

@Dirbaio
Copy link

Dirbaio commented Jun 19, 2020

How can I detect from a handler that the underlying request is canceled? Other server implementations such as hyper drop the handle future on request cancelation, but it seems async-h1 doesn't.

How to reproduce:

struct DropGuard;

impl Drop for DropGuard {
    fn drop(&mut self) {
        println!("dropped!")
    }
}

// Take a TCP stream, and convert it into sequential HTTP request / response pairs.
async fn accept(stream: TcpStream) -> http_types::Result<()> {
    println!("starting new connection from {}", stream.peer_addr()?);
    async_h1::accept(stream.clone(), |_req| async move {
        let g = DropGuard;
        println!("got request!");
        async_std::task::sleep(std::time::Duration::from_secs(3)).await;

        println!("sending response!");

        let mut res = Response::new(StatusCode::Ok);
        res.insert_header("Content-Type", "text/plain");
        res.set_body("Hello world");
        Ok(res)
    })
    .await?;
    Ok(())
}

In a terminal, curl localhost:8080 and ctrl+C before the 3 second timeout.

What you see is:

got request!
...(3 seconds later)
sending response!
dropped!!!!

what you would see if the future was dropped is:

got request!
...(on request cancel, less than 3 seconds later)
dropped!!!!
@ririsoft
Copy link

I am serving big files (movies) with tide and get a lot of errors due to cancellation of the video playing on client side.
I am wondering wether this should be handled at async-h1 level or tide level (for instance).

@jbr
Copy link
Member

jbr commented Aug 12, 2020

I started looking into this but haven't picked it back up. I think it might end up related to handling graceful shutdown in tide http-rs/tide#528

@Dirbaio
Copy link
Author

Dirbaio commented Dec 10, 2020

Go does it like this:

  • When the handler is done reading the request body, start a "background read"
  • If the background read completes with EOF or with error, the request has been canceled.
  • If the background read completes with some data, this is part of the next (probably pipelined) request. That data needs to be kept around for decoding it.

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

No branches or pull requests

3 participants