bytecodealliance / wasmtime

A fast and secure runtime for WebAssembly

Home Page:https://wasmtime.dev/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Question about `blocking_write_and_flush` behavior

karthik2804 opened this issue · comments

Given this rust code

async fn handler(req: IncomingRequest, res: ResponseOutparam) {
    let response = OutgoingResponse::new(
        Headers::from_list(&[("content-type".to_string(), b"plain/text-stream".to_vec())]).unwrap(),
    );

    let body = response.body().unwrap();
    res.set(response);

    let out_stream = body.write().unwrap();

    out_stream
        .blocking_write_and_flush("hello world 1".as_bytes())
        .unwrap();

    thread::sleep(Duration::from_secs(2));
    out_stream
        .blocking_write_and_flush("\nline 2".as_bytes())
        .unwrap();

    thread::sleep(Duration::from_secs(2));
    out_stream
        .blocking_write_and_flush("\nline 3".as_bytes())
        .unwrap();
    drop(out_stream);
    OutgoingBody::finish(body, None).unwrap();
}

When running it through wasmtime serve -S common blockingstream.wasm, I get the behavior as described below.

curl -i localhost:8080
HTTP/1.1 200 OK
content-type: plain/text-stream
transfer-encoding: chunked
date: Thu, 04 Apr 2024 21:44:46 GMT

# 2 second pause
hello world 1
# 2 second pause
line 2
line 3%  

To be clear (as shown in the above terminal) the previous write is not written until the next write or finish is called on the response body. Is this expected behavior or should the writes be flush as soon as written?

I'm able to reproduce this locally as well, but after some debugging I think you might accidentally be falling victim of curl's default buffering behavior. With the --no-buffer flag to curl (which I just now learned existed) the timing here looks to be as expected. Changing the program to put \n at the end of the lines in the sample instead of at the beginning also looks to have the expected behavior with curl's default buffering mode too.

Oh! That is exactly what was happening and I can achieve the expected behavior with either of the options mentioned.

Thanks!