-
-
Notifications
You must be signed in to change notification settings - Fork 632
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
Async Store #5117
Conversation
The individual commits should be useful to review independently. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice :) Thanks!
src/rust/engine/fs/src/store.rs
Outdated
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> { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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(), |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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.
Great, thanks! :) |
Problem
Store
executes IO, but was doing so synchronously on the main thread, which might block other operations.Solution
Give
Store
a reference to aResettablePool
, 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 theStore
to be cloned into the pool... this pattern seems much cleaner than the "impl Trait for Arc<Struct>
pattern" that we've used with theVFS
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
andmaterialize_directory
infs_util
, andDigestFile
innodes
will execute concurrently. Helps to unblock #5105 and #5106.