-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Add paths to the store asynchronously #13798
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
base: master
Are you sure you want to change the base?
Conversation
Adding paths to the store can be slow due to I/O overhead, but especially when going through the daemon because of the round-trip latency of every wopAddToStore call. So we now do the addToStore() calls asynchronously from a separate thread from the evaluator. This slightly speeds up the local store, and makes going through the daemon almost as fast as a local store.
Shouldn't we just send the daemon a file path or file descriptor and then it can add the data itself? I would think serializing local files over NARs to be unpacked by the daemon (on the same system) is bad performance whether synchronous or asynchronous, compared to letting the OS move the files around. |
@edef1c reminds me of https://en.wikipedia.org/wiki/Confused_deputy_problem, so yes it should be a file descriptor, not path, to cleanly avoid all these problems. (The way this PR does it is still good for the ssh/non-local case, to be clear.) |
Are there not also remote daemons where this doesn't work? There this eval store option. |
cc @NaN-git |
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.
At this point we could just look into porting the kj-async based refactoring to the store layer that Lix has done. Coroutines seem very fitting for this sort of thing. It would require more up-front effort, but it seems worthwhile in the long run. Doing ad-hoc async is going to become more painful as we have more of it.
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2025-08-20-nix-team-meeting-minutes-242-241/68245/1 |
// FIXME: use addMultipeToStore() once it doesn't require a | ||
// NAR hash from the client for CA objects. | ||
|
||
for (auto & item : items) { | ||
StringSource source(item.contents); | ||
auto storePath = store->addToStoreFromDump( | ||
source, | ||
item.storePath.name(), | ||
FileSerialisationMethod::Flat, | ||
ContentAddressMethod::Raw::Text, | ||
HashAlgorithm::SHA256, | ||
item.references, | ||
item.repair); | ||
assert(storePath == item.storePath); | ||
} |
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.
As we discussed briefly in the meeting, we could instead implement pipelining, which does not require an update to the worker protocol.
Another benefit of pipelining that was not brought up is that it also allows the first response to come in before any of the other requests, reducing the latency of individual add operations.
In principle yes, but converting the whole evaluator to coroutines might not be the right thing to do, or at least not the first thing to do. I do agree that an async refactor would benefit the code a lot, just by virtue of getting to use better control flow primitives/abstractions than what |
Something we should discuss in a team meeting I think, so that we are all aligned on it. |
Motivation
Adding paths to the store can be slow due to I/O overhead, but especially when going through the daemon because of the round-trip latency of every
wopAddToStore
call.So we now do the
addToStore()
calls asynchronously from a separate thread from the evaluator. This slightly speeds up the local store, and makes going through the daemon almost as fast as a local store.Timings doing
nix eval github:NixOS/hydra/b812bb5017cac055fa56ffeac5440b6365830d67#nixosConfigurations.container.config.system.build.toplevel
:The async path writer is currently only used by
writeDerivation()
(i.e. for adding.drv
files) but can be extended in the future to handle other source files.Includes DeterminateSystems#162 and DeterminateSystems#176.
Context
Add 👍 to pull requests you find important.
The Nix maintainer team uses a GitHub project board to schedule and track reviews.