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

fix(cache): Add back in the marker at the beginning of malformed cache entries #586

Merged
merged 6 commits into from
Nov 30, 2021

Conversation

relaxolotl
Copy link
Contributor

@relaxolotl relaxolotl commented Nov 30, 2021

Primarily fixes a regression from the shared cache PR (#581) which was no longer writing the sentinel/"header" for malformed entries in caches.

Also includes a minor fix that ensures that other non-positive entries in the cache are truncated in case they are overwriting some other content that is slightly longer than their new value. This is highly unlikely to occur, but this is added in as a safeguard if this does ever occur.

This also renames the helper because there's no need for the user to know about the existence of markers at the abstraction level where that would be invoked.

Unit tests have been written because they would have caught this error assuming that they weren't deleted or commented out during the original function's refactor. Proper integration tests would most likely test compute itself, which is a pretty complicated function to test.

@relaxolotl relaxolotl requested a review from a team November 30, 2021 00:00
Comment on lines +1235 to +1237
// rewinding and then reading to the end of async_file throws bad file
// descriptor errors, so just reopen the file
let mut final_file = File::open(&path)?;
Copy link
Member

Choose a reason for hiding this comment

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

I’m wondering why though? This reads like a bug in itself.

Copy link
Contributor

@flub flub left a comment

Choose a reason for hiding this comment

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

Looks good, especially the tests. i'm also shocked this wasn't caught by integration tests, but that doesn't have to be a blocker for this fix.

@@ -104,12 +104,21 @@ impl CacheStatus {
}
CacheStatus::Malformed(details) => {
file.rewind().await?;
file.write_all(MALFORMED_MARKER).await?;
Copy link
Contributor

Choose a reason for hiding this comment

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

whoops 🙈

file.write_all(details.as_bytes()).await?;

let new_len = MALFORMED_MARKER.len().saturating_add(details.len());
Copy link
Contributor

Choose a reason for hiding this comment

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

file.stream_position() would give the same, and i have a slight preference for it because it doesn't rely on getting the maths right. but i don't mind.
(i think it might also avoid the cast)

#[tokio::test]
async fn test_cache_status_write_positive() -> Result<()> {
let dir = tempdir()?;
create_dir_all(&dir).unwrap();
Copy link
Contributor

Choose a reason for hiding this comment

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

surely this is duplicate of the line above?


// make sure write doesn't change the pre-existing contents of the file
// rewinding and then reading to the end of async_file throws bad file
// descriptor errors, so just reopen the file
Copy link
Contributor

Choose a reason for hiding this comment

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

It throws an error because you opened the file in write-only mode: File::create(&path).

OpenOptions::new().read(true).write(true).create(true).open(&path) would fix that

Copy link
Contributor

Choose a reason for hiding this comment

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

@Swatinem answer to your question ^

Comment on lines +1237 to +1239
let mut final_file = File::open(&path)?;
let mut contents = Vec::new();
final_file.read_to_end(&mut contents)?;
Copy link
Contributor

Choose a reason for hiding this comment

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

let contents = std::fs::read(&path).unwrap() could replace this entire block.

let sync_file = File::create(&path)?;
let mut async_file = tokio::fs::File::from_std(sync_file);
async_file.write_all(b"beep").await?;
async_file.rewind().await?;
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd not even rewind, status.write() should handle that


async_file
.write_all(
b"i'm a little teapot short and stout here is my handle and here is my spout",
Copy link
Contributor

Choose a reason for hiding this comment

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

💯

@flub flub enabled auto-merge (squash) November 30, 2021 12:01
@flub flub merged commit 0c776dc into master Nov 30, 2021
@flub flub deleted the fix/write-malformed-marker branch November 30, 2021 12:05
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.

3 participants