Make io in builder-api-client not block executor
@@ -39,6 +39,7 @@ use std::{fs::{self,
PathBuf},
string::ToString};
use tee::TeeReader;
+use tokio::task;
use tokio_util::codec::{BytesCodec,
FramedRead};
use url::Url;
@@ -187,9 +188,8 @@ impl BuilderAPIClient {
let w = AtomicWriter::new(&dst_file_path)?;
let content_length = response::get_header(&resp, CONTENT_LENGTH);
let mut body = Cursor::new(resp.bytes().await?);
- // WARNING: This is a blocking write. It has the potential to block the `tokio` runtime. The
- // blocking implementation is used to allow use of `DisplayProgress` which uses the `Write`
- // trait.
+ // Blocking is used to allow use of `DisplayProgress` which uses the `Write` trait.
+ task::block_in_place(|| {
w.with_writer(|mut f| {
// There will be no CONTENT_LENGTH header if an on prem
// builder is using chunked transfer encoding
@@ -204,18 +204,18 @@ impl BuilderAPIClient {
}
})?;
Ok(dst_file_path)
+ })
}
fn upload_body(src_path: &Path, progress: Option<Box<dyn DisplayProgress>>) -> Result<Body> {
+ // Blocking is used to allow use of `DisplayProgress` which uses the `Write` trait.
+ task::block_in_place(|| {
let file =
File::open(src_path).map_err(|e| Error::KeyReadError(src_path.to_path_buf(), e))?;
let file_size = file.metadata()
.map_err(|e| Error::KeyReadError(src_path.to_path_buf(), e))?
.len();
- // WARNING: This uses a blocking read. It has the potential to block the `tokio` runtime.
- // The blocking implementation is used to allow use of `DisplayProgress` which uses the
- // `Write` trait.
Ok(if let Some(mut progress) = progress {
progress.size(file_size);
let reader = AllowStdIo::new(TeeReader::new(file, progress));
@@ -226,6 +226,7 @@ impl BuilderAPIClient {
let reader = FramedRead::new(reader, BytesCodec::new()).map_ok(BytesMut::freeze);
Body::wrap_stream(reader)
})
+ })
}
async fn seach_package_with_range(&self,
