Skip to content
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

Builder::finish() does not 'close' inner Writer #9

Open
danieleades opened this issue Dec 5, 2020 · 5 comments
Open

Builder::finish() does not 'close' inner Writer #9

danieleades opened this issue Dec 5, 2020 · 5 comments
Labels
help wanted Extra attention is needed

Comments

@danieleades
Copy link
Contributor

Builder::finish() doesn't seem to flush the state of the inner writer. this means the following snippet doesn't work-

use async_compression::futures::write::GzipEncoder;
use async_std::{fs::File, path::Path};
use async_tar::Builder;
use futures::io::AsyncWrite;

async fn write_archive<W>(writer: W, src_directory: impl AsRef<Path>) -> std::io::Result<()>
where
    W: AsyncWrite + Unpin + Send + Sync,
{
    let mut archive_builder = Builder::new(writer);
    archive_builder.append_dir_all("", src_directory).await?;
    archive_builder.finish().await
}

#[async_std::main]
async fn main() {
    let file = File::create("foo.tar.gz").await.unwrap();
    let encoder = GzipEncoder::new(file);
    write_archive(encoder, "sample-directory").await.unwrap();
}

but this snippet does work

use async_compression::futures::write::GzipEncoder;
use async_std::{fs::File, path::Path};
use async_tar::Builder;
use futures::io::{AsyncWrite, AsyncWriteExt};

async fn write_archive<W>(writer: W, src_directory: impl AsRef<Path>) -> std::io::Result<()>
where
    W: AsyncWrite + Unpin + Send + Sync,
{
    let mut archive_builder = Builder::new(writer);
    archive_builder.append_dir_all("", src_directory).await?;
    archive_builder.finish().await?;

    archive_builder.into_inner().await?.close().await
}

#[async_std::main]
async fn main() {
    let file = File::create("foo.tar.gz").await.unwrap();
    let encoder = GzipEncoder::new(file);
    write_archive(encoder, "docker-context").await.unwrap();
}

that's more than a little surprising.

Builder::finish() should flush the inner writer, or at the very least, this behaviour should be clearly documented

@danieleades
Copy link
Contributor Author

looking through the docs, the Builder::append* methods mention that Builder::finish should be called, but the Builder::finish method itself says "In most situations the into_inner method should be preferred". That seems inconsistent, no?

In the above snippet, does that mean I can use into_inner().await?.close().await instead of archive_builder.finish().await (rather than both)?

@Nemo157
Copy link

Nemo157 commented Dec 6, 2020

I think it would also pay to update all examples to finish/close the writer. The one in the readme is presumably ok since async-std::fs::File is unbuffered, but if someone were to take that and wrap it into an async-std::io::BufWriter they would encounter the same sort of issue with their writes not making it to disk. Adding a finish/close call to it, while not strictly necessary, should have no runtime cost and help with new users learning they need to call close.

@dignifiedquire dignifiedquire added the help wanted Extra attention is needed label Jan 11, 2021
@danieleades
Copy link
Contributor Author

hi @dignifiedquire could i get a bit of clarification on the questions above? I'm happy to take a run at this, but I want to make sure I understand the preferred solution

@dignifiedquire
Copy link
Owner

Lets go with updating examples & docs for now. I agree it is surprising, but I think I'd like to keep the api as it is for now. We could add a call finish_and_close() or sth like that, as a convenience, for making sure everything is done, thoughts?

@piegamesde
Copy link

I agree that finish probably should call flush on the inner writer, but why close it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

4 participants