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

Suggestion for BufReader Documentation Improvement #55546

Closed
ghost opened this issue Oct 31, 2018 · 0 comments
Closed

Suggestion for BufReader Documentation Improvement #55546

ghost opened this issue Oct 31, 2018 · 0 comments
Labels
A-docs Area: documentation for any part of the project, including the compiler, standard library, and tools

Comments

@ghost
Copy link

ghost commented Oct 31, 2018

Introduction

After we have chased down a bug in our multiprocess application, which caused messages passed between processes to get lost sometimes, I would like to suggest including a small hint in the Rust documentation of BufReader. Maybe a lint implementation for clippy also would be possible.

Background

The messages got (sometimes partly) lost, because I repeatedly created a BufReader instance on the same ChildStdout reference for every line I wanted to read off the stream. This instance got then dropped at the end of the scope. Retroperspective this was not a wise decision in my implementation and I understand that this can cause parts of stream data to get lost when the BufReader instance gets dropped.
But when implementing it I did not think of such a possibility and finding the source of this bug was quite difficult. It ended up searching the libstd source, after having found out that a crude self implementation of read_line() somehow fixed the bug. Only this brought up the idea, that the buffering of BufReader could be the cause of our issues.

Code

The issue can be reproduced by the following simple application and one file input.log with some lines of text in the execution directory. The read lines are written for comparison into output.log.

use std::fs::{File, OpenOptions};
use std::io::{prelude::*, BufReader};

fn main() -> std::io::Result<()> {
    let mut read = File::open("./input.log")?;
    let mut write = OpenOptions::new()
        .write(true)
        .truncate(true)
        .create(true)
        .open("./output.log")?;

    loop {
        let mut reader = BufReader::new(&mut read);
        let mut line = String::new();

        match reader.read_line(&mut line) {
            Ok(0) | Err(_) => break,
            Ok(_) => write!(write, "{}", line)?,
        }
    }

    Ok(())
}

Suggestion

To decrease the chance for others repeating the same mistake, I would suggest a short hint in the documentation of BufReader, that creating multiple instances on a referenced stream (especially in some sort of loop) can cause data loss.
Maybe it might even be possible to implement a clippy lint to fetch such a pitfall.

Reference

The related users topic can be found here.

@jonas-schievink jonas-schievink added the A-docs Area: documentation for any part of the project, including the compiler, standard library, and tools label Jan 27, 2019
czipperz added a commit to czipperz/rust that referenced this issue Mar 28, 2019
Centril added a commit to Centril/rust that referenced this issue Mar 28, 2019
…scards, r=Centril

Document that `std::io::BufReader` discards contents on drop

Resolves rust-lang#55546
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-docs Area: documentation for any part of the project, including the compiler, standard library, and tools
Projects
None yet
Development

No branches or pull requests

1 participant