Skip to content

Commit 127a082

Browse files
committed
client: Handle get_blob futures being polled serially
- Add documentation for how it worked before - Wrap the reader in a `.take()` which will handle the case where the caller polls the futures serially - Change one example to do it that way to test it Closes: #71
1 parent 611314d commit 127a082

File tree

2 files changed

+15
-5
lines changed

2 files changed

+15
-5
lines changed

examples/client.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,13 @@ async fn fetch_container_to_devnull(o: GetMetadataOpts) -> Result<()> {
9494
for layer in manifest.layers() {
9595
let (mut blob, driver) = proxy.get_descriptor(img, layer).await?;
9696
let mut devnull = tokio::io::sink();
97-
let copier = tokio::io::copy(&mut blob, &mut devnull);
98-
let (copier, driver) = tokio::join!(copier, driver);
99-
copier?;
100-
driver?;
97+
// This is the preferred way to handle this:
98+
// let copier = tokio::io::copy(&mut blob, &mut devnull);
99+
// let (copier, driver) = tokio::join!(copier, driver);
100+
// But in our example code here we do it serially to verify it works.
101+
// ref https://github.com/containers/containers-image-proxy-rs/issues/71
102+
tokio::io::copy(&mut blob, &mut devnull).await?;
103+
driver.await?;
101104
}
102105
Ok(())
103106
}

src/imageproxy.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,11 @@ impl ImageProxy {
550550
/// <https://github.com/opencontainers/image-spec/blob/main/descriptor.md>
551551
///
552552
/// The requested size and digest are verified (by the proxy process).
553+
///
554+
/// Note that because of the implementation details of this function, you should
555+
/// [`futures::join!`] the returned futures instead of polling one after the other. The
556+
/// secondary "driver" future will only return once everything has been read from
557+
/// the reader future.
553558
#[instrument]
554559
pub async fn get_blob(
555560
&self,
@@ -568,7 +573,9 @@ impl ImageProxy {
568573
let (_bloblen, fd) = self.impl_request::<i64, _, _>("GetBlob", args).await?;
569574
let (fd, pipeid) = fd.ok_or_else(|| Error::new_other("Missing fd from reply"))?;
570575
let fd = tokio::fs::File::from_std(std::fs::File::from(fd));
571-
let fd = tokio::io::BufReader::new(fd);
576+
// We only read up to the object size, ref https://github.com/containers/containers-image-proxy-rs/issues/71
577+
// This is a fallback to handle the case where the caller polls the two futures serially.
578+
let fd = tokio::io::BufReader::new(fd).take(size);
572579
let finish = Box::pin(self.finish_pipe(pipeid));
573580
Ok((fd, finish))
574581
}

0 commit comments

Comments
 (0)