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
Actix HTTP2 error with long blocking requests and async task #2728
Comments
|
do not use std thread sleep inside async function. it would block thread and starve all other async tasks on the same thread. in this case you are blocking http2 ping/pong. |
|
Hello, and thanks for your reply ! Indeed, blocking tasks should be sent to a thread dedicated to running blocking tasks. But I still don't understand why the |
|
It's very simple. One route have await point and one does not. Every await point can potential yield back to runtime for other async task. or in other word you are trying to peak into how yielding would affect the inner state change of actix-web itself from outside. |
|
Hello, and thank you again. I understand that yielding to the runtime may have "side effects", but I still do not understand how. In both cases, as Even worse, in my understanding, yielding gives the runtime an opportunity to send an http2 ping/pong frame, so if one endpoint could work, it would be the So I guess something is happening in the runtime when the request handler sleeps after being pooled for the second time, but I cannot figure out what. |
|
Like I said you are trying to figure out the state change from your handler. If you really want to know exactly why you can check the source code of http2 handler here. actix-web/actix-http/src/h2/dispatcher.rs Line 106 in de9e414
|
|
Thank you very much, I'll look into it ! |
|
Thank you for pointing the right place to start digging in the code ! After some investigations, I understand that my server never sends an I still haven't figured out why this is happening in one case and not the other, but this raises another question, which is hopefully a bit more straightforward: |


Hello, and thank you very much for this crate.
Here is the gist for a reproductible example: https://gist.github.com/allencamal/cfe62dda9fc8132ba6707d5771cac7f1
Expected Behavior
It should be possible to curl the
failingendpoint.Current Behavior
When
curling thefailingendpoint,curlreturns the following error message:curl: (18) transfer closed with 7302400 bytes remaining to read.Possible Solution
Actually, forcing HTTP1.1 via
curlwith the--http1.1option works, but I don't think this is a viable option. Disabling TLS forces HTTP1.1, and also works, but that is not something viable.Also, using
spawn_blockingfor the blockingsleepfixes the issue, but that does not make the bug less curious.Steps to Reproduce (for bugs)
Gist: https://gist.github.com/allencamal/cfe62dda9fc8132ba6707d5771cac7f1
actix-webandrustlsstd::thread::sleep, and return more than 13 MB of data.curl --insecure https://localhost:8085/failing > aContext
Here are the two endpoints:
Here is the gist for a reproductible example: https://gist.github.com/allencamal/cfe62dda9fc8132ba6707d5771cac7f1
I'm creating a very basic HTTP web server, using TLS (so that http2 is available). I've got two endpoints, that basically just sleeps 15 secs (using
std's sleep, nottokio's) and returns 20 MB of data. (for less data, e.g. 10 MB, the bug does not appears).From my experience, sleeping for less than 15 seconds (e.g. 5 seconds) also fails, but anything less than 3 seconds works correctly.
The only difference between the two endpoints is that one calls:
actix_web::rt::task::spawn_blocking(|| println!("Request will fail")).await;before sleeping (blocking).If I curl my two endpoints:
curl --insecure https://localhost:8085/working > a % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 19.0M 100 19.0M 0 0 1271k 0 0:00:15 0:00:15 --:--:-- 4709kThe one that spawn a blocking task fails.
Note that on another project, I have a similar issue, but the error is
curl (92) HTTP/2 stream 1 was not closed cleanly before end of the underlying stream.Your Environment
Cargo.tomlincluded at the beginning of the gistrustc -V): rustc 1.60.0 (7737e0b5c 2022-04-04)The text was updated successfully, but these errors were encountered: