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

[WIP] Rust course project 2 tests and example solution #33

Merged
merged 7 commits into from Mar 31, 2019

Conversation

sticnarf
Copy link
Collaborator

No description provided.

brson and others added 6 commits March 27, 2019 14:42
Signed-off-by: Yilin Chen <sticnarf@gmail.com>
Signed-off-by: Yilin Chen <sticnarf@gmail.com>
Signed-off-by: Yilin Chen <sticnarf@gmail.com>
Signed-off-by: Yilin Chen <sticnarf@gmail.com>
@sticnarf sticnarf self-assigned this Mar 29, 2019
failure = "0.1.5"
serde = { version = "1.0.89", features = ["derive"] }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not know you could get the derive macros directly from the serde crate. Neat!

for set_cmd in stream {
let set_cmd = set_cmd?;
map.insert(set_cmd.key, set_cmd.value);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm glad this code was so easy. I was afraid serde wouldn't deserialize multiple records in sequence like that.

temp_dir.push(name);
create_dir_all(&temp_dir).expect("unable to create working directory");
temp_dir
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the looks of this the temp dirs are not deleted up after the test. Can you instead use the tempfile crate's tempdir, which has destructors that automatically clean up.

Copy link
Collaborator Author

@sticnarf sticnarf Mar 29, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was avoiding introducing dependencies to tests. If we do so, we'll either change to use a workspace or just add dev-dependencies to Cargo.toml. I prefer the latter one. I think we can add necessary dev-dependencies to the Cargo.toml at the beginning of the course in project 1 and tell them these dependencies are only used for tests.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This way, students copy the content of Cargo.toml at first, and copy the tests of each project, then everything will go fine.

}

/// Sets the value of a string key to a string.
///
/// If the key already exists, the previous value will be overwritten.
pub fn set(&mut self, key: String, value: String) -> Result<()> {
self.map.insert(key, value);
let cmd = SetCommand::new(key, value);
to_writer(&mut self.wal_writer, &cmd)?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It took me a few seconds to figure out that to_writer isn't in this crate, but from serde_json.

It's common in Rust to import types, but to call functions through their module name, like serde_json::to_writer. Will you do that here for clarity?

Copy link
Contributor

@brson brson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great stuff again.

I put a few change requests inline.

The use of BufWriter is interesting. Here's the commit code as written:

    let cmd = SetCommand::new(key, value);
    to_writer(&mut self.wal_writer, &cmd)?;
    self.map.insert(cmd.key, cmd.value);
    Ok(())

The function returns to the caller with Ok. That means that their data is definitely inserted. So even if there's a crash they can restart and see the commit. To guarantee that, the userspace buffer and the kernel buffer need to be flushed to disk prior to inserting into the map. The project hasn't covered that yet, but I think it needs to.

If the data is immediately flushed then is the BufWriter doing something useful? I think it depends on how serde treats the writer, whether it writes in small increments, or whether it writes in big chunks.

Probably it writes in small pieces and you are right to use the BufWriter. But I don't know.

That's all I've got. Good stuff.

@sticnarf
Copy link
Collaborator Author

sticnarf commented Mar 29, 2019

@brson After some investigation, I confirm serde_json writes in small pieces, so a BufWriter counts.

You're right. To ensure we do not lose data in the buffer, we need a flush on every write of the user.

Signed-off-by: Yilin Chen <sticnarf@gmail.com>
@sticnarf sticnarf requested a review from brson March 29, 2019 09:52
@brson brson merged commit d0d1254 into pingcap:master Mar 31, 2019
@brson
Copy link
Contributor

brson commented Mar 31, 2019

Thanks @sticnarf. I went ahead and merged. Please continue the project in a new branch.

@sticnarf sticnarf deleted the file-io-code branch April 1, 2019 02:15
@sticnarf sticnarf restored the file-io-code branch April 1, 2019 02:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants