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

Async Store #5117

Merged
merged 8 commits into from
Nov 20, 2017
Merged

Async Store #5117

merged 8 commits into from
Nov 20, 2017

Conversation

stuhood
Copy link
Member

@stuhood stuhood commented Nov 18, 2017

Problem

Store executes IO, but was doing so synchronously on the main thread, which might block other operations.

Solution

Give Store a reference to a ResettablePool, and execute all database operations on the pool.

It was also necessary to apply the "Arc<Inner*> pattern" (maybe it has a name?) to allow the Store to be cloned into the pool... this pattern seems much cleaner than the "impl Trait for Arc<Struct> pattern" that we've used with the VFS implementations... should consider switching those over at some point.

Finally, I added Store::load_bytes_with to support copying directly from LMDB buffers into a destination to avoid copying, and execute the copy on the IO pool.

Result

save_directory and materialize_directory in fs_util, and DigestFile in nodes will execute concurrently. Helps to unblock #5105 and #5106.

@stuhood
Copy link
Member Author

stuhood commented Nov 18, 2017

The individual commits should be useful to review independently.

Copy link
Contributor

@illicitonion illicitonion left a comment

Choose a reason for hiding this comment

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

Very nice :) Thanks!

let mut hasher = Sha256::default();
hasher.input(&bytes);
let fingerprint = Fingerprint::from_bytes_unsafe(hasher.fixed_result().as_slice());
fn store_bytes(&self, bytes: Vec<u8>, db: Database) -> CpuFuture<Fingerprint, String> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why a CpuFuture not a BoxFuture?

Copy link
Member Author

Choose a reason for hiding this comment

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

If this were a crate-public API, it would be good to expose BoxFuture to avoid leaking implementation details... but since it isn't, avoiding the boxing is just nice.

});
match mkdir {
Ok(()) => {}
Err(e) => return future::result(Err(e)).to_boxed(),
Copy link
Contributor

Choose a reason for hiding this comment

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

future::err(e)?

.into_iter()
.map(|file_node| {
let path = destination.join(file_node.get_name());
materialize_file(store.clone(), path, file_node)
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems odd that this takes a FileNode rather than a Fingerprint.

(And similarly odd that this take_files()s and into_iter()s rather than just iterating over a read-only view, which I think it only does because you're passing a FileNode here rather than a Fingerprint)

Copy link
Member Author

Choose a reason for hiding this comment

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

Good call... this looked necessary before I extracted the method, but was not. This improved the symmetry quite a bit.

@illicitonion
Copy link
Contributor

Great, thanks! :)

@stuhood stuhood merged commit 9ebddaf into pantsbuild:master Nov 20, 2017
@stuhood stuhood deleted the stuhood/async-store branch November 20, 2017 18:24
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.

2 participants