Stream: git-wasmtime

Topic: wasmtime / issue #8300 Question about `blocking_write_and...


view this post on Zulip Wasmtime GitHub notifications bot (Apr 04 2024 at 22:14):

karthik2804 opened issue #8300:

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 behaviour or should the writes be flush as soon as written?

view this post on Zulip Wasmtime GitHub notifications bot (Apr 04 2024 at 22:16):

karthik2804 edited issue #8300:

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?

view this post on Zulip Wasmtime GitHub notifications bot (Apr 05 2024 at 02:43):

alexcrichton commented on issue #8300:

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.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 05 2024 at 03:14):

karthik2804 closed issue #8300:

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?

view this post on Zulip Wasmtime GitHub notifications bot (Apr 05 2024 at 03:14):

karthik2804 commented on issue #8300:

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

Thanks!


Last updated: Oct 23 2024 at 20:03 UTC