Closed wangjia184 closed 5 years ago
Funny thing is, changing from actix::spawn
to thread::spawn
would make it work!
fn index(req: HttpRequest) -> impl Responder {
let (tx, rx_body) = mpsc::unbounded();
let text = "Something!\n";
thread::spawn(move || loop {
let _ = tx.unbounded_send(Bytes::from(text.as_bytes()));
let ten_millis = time::Duration::from_millis(100);
thread::sleep(ten_millis);
});
HttpResponse::Ok().streaming(rx_body.map_err(|_| error::ErrorInternalServerError("Internal Server Error")))
}
What is the secret behind actix::spawn
? why does thread::spawn
work instead?
Remove thread::sleep
@fafhrd91 tried that. Removing thread::sleep
does not make any difference. unbounded_send()
is being called many times and there is no response at all.
Because your code blocks and never yields
I guess, this line needs to be let result = tx.unbounded_send(Bytes::from(text.as_bytes())).await;
or something like this
Thanks @fafhrd91
The return value of unbounded_send()
is type of Result<(), SendError<T>>
which cannot await
.
However, I take your advice and await
on a non-blocking timer, it works!
let fu = async move {
loop {
// we will await here, for now send a hardcode string to test
let result = tx.unbounded_send(Bytes::from(text.as_bytes()));
if let Err(e) = result {
println!("{}", e);
return;
} else {
println!("Success");
}
futures_timer::Delay::new(std::time::Duration::from_secs(1)).await;
}
};
actix::spawn(fu.unit_error().boxed_local().compat());
I found there is another key point. App::new().wrap(middleware::Compress::default())
has to be removed to make it work.
If compression middleware is enabled, progressive response is impossible. Is this a bug?
It is not bug. Compression works
I copied your source code but it doesn't work. How did you solve this problem? It says "Success" but never receive any message.
@tomocrafter "Success" means the channel is closed. you need keep the channel open and send data to it.
@wangjia184 Thank you for quick reply. It continues to print with Success regularly. but When I close the connection of http, and then the streaming immediately stops and prints "send failed because receiver is gone". I don't think channel is closed.
Rust Version : 1.39 nightly actix-web version : 1.0.7
The following code does not produce any response and HTTP connection hangs although
unbounded_send()
returns a success and Success is printed.It seems actix-web cannot send out chunked response progressively before the connection completes in
actix::spawn
.main.rs
cargo.toml