-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Give nix daemon
and nix-store --serve
protocols separate serializers with version info
#6223
Give nix daemon
and nix-store --serve
protocols separate serializers with version info
#6223
Conversation
e50da53
to
13b17d1
Compare
Rebased this on top! |
I’m quite scared by these raw A nicer way to do that might be to
|
13b17d1
to
38a26a1
Compare
@thufschmitt Those files are gone! Also, less boilerplate to handle versions now. Combined with #6312 and likewise for valid path info, this will be much nicer. |
I do like the overall idea, but I find this really complex, and I don’t see what justifies all this this complexity. Do we really need all that cpp and namespace mangling? I’d much rather use plain inheritance or templating, even it it comes with more boilerplate |
@thufschmitt What CPP mangling is there now? I agree the namespace tricks are unfortunate --- if we have just had Rust's Traits this would all be so much easier --- but I thought quite long about alternatives and I can't think of much different unless it become unextendable (e.g. fit set of method on some serializer, lots of virtual), which doesn't sit right with me but also is just feels like far more churn. The namespace tricks are roughly how nlohmann json works, too, fwiw. I would like to do this more more less as-is, and just hope we can get rid of the |
No CPP mangling, just namespace mangling ;).
Is it that bad? After all we’re in control of everything, so it’s fine to have one master-class declaring all the methods (beside it’s easier to have a view of everything that’s implemented) (Just to be clear: I’m not saying that this approach is wrong. There’s a lot of nasty complexity here and I’m all ready to believe that we don’t have a choice. But in that case it deserves a clear justification) |
You are right its not a problem in practice. Just the non-modularity of it sits very uncomfortably with me. If we ever want to make a greenfield new protocol that is e.g. Protobuf or JSON, and easier for other tools I understand, to those tools usually take the open world approach so I feel like it's good to match it too. The tricky parts here are trying to share code between daemon protocol / serve protocol / hooks / import/export / whatever else. As soon as we stop/don't need to do that, it gets easier again. |
Well, these new protocols wouldn’t share anything with the current one, would they?
Unfortunately that will probably have to stay for at least a couple years, so we’d better not treat this as too temporary |
Yes they wouldn't, and thus the downsides of the current approach would hopefully be avoided
Perhaps I just need to overcome the "ick" reflex and just duplicate the code. Then the status quo will also be simpler and modular. I think once Hydra can use |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/a-proposal-for-replacing-the-nix-worker-protocol/20926/12 |
38a26a1
to
aac2270
Compare
nix-store ---serve
protocol its own serializers
nix-store ---serve
protocol its own serializersnix-store --serve
protocol its own serializers
In many cases we are dealing with a collection of realisations, they are all outputs of the same derivation. In that case, we don't need "derivation hashes modulos" to be part of our map key, because the output names alone will be unique. Those hashes are still part of the realisation proper, so we aren't loosing any information, we're just "normalizing our schema" by narrowing the "primary key". Besides making our data model a bit "tighter" this allows us to avoid a double `for` loop in `DerivationGoal::waiteeDone`. The inner `for` loop was previously just to select the output we cared about without knowing its hash. Now we can just select the output by name directly. Note that neither protocol is changed as part of this: we are still transferring `DrvOutputs` over the wire for `BuildResult`s. I would only consider revising this once NixOS#6223 is merged, and we can mention protocol versions inside factored-out serialization logic. Until then it is better not change anything because it would come a the cost of code reuse.
nix-store --serve
protocol its own serializersnix daemon
and nix-store --serve
protocols have separate serializers with version info
aac2270
to
8f29241
Compare
d5028d4
to
df9cff2
Compare
2a6b1f8
to
98c5476
Compare
98c5476
to
0cb0060
Compare
0cb0060
to
ade5b21
Compare
ade5b21
to
061a09d
Compare
e4661d6
to
e058ce5
Compare
8d07f2a
to
ac860fd
Compare
🎉 All dependencies have been resolved ! |
It was some ad-hoc functions to account for versions, while the already factored-out serializer just supported the latest version. Now, we can fold that version-specific logic into the factored out one, and so we do.
Worker Protocol: Note that the worker protocol already had a serialization for `BuildResult`; this was added in a4604f1. It didn't have any versioning support because at that time reusable seralizers were not away for the protocol version. It could thus only be used for new messages also introduced in that commit. Now that we do support versioning in reusable serializers, we can expand it to support all known versions and use it in many more places. The exist test data becomes the version 1.29 tests: note that those files' contents are unchanged. 1.28 and 1.27 tests are added to cover the older code-paths. The keyered build result test only has 1.29 because the keying was also added in a4604f1; the older serializations are always used unkeyed. Serve Protocol: Conversely, no attempt was made to factor out such a serializer for the serve protocol, so our work there in this commit for that protocol proceeds from scratch.
It does not belong with the data type itself. This also materializes the fact that `copyPath` does not do any version negotiation just just hard-codes "16". The non-standard interface of these serializers makes it harder to test, but this is fixed in the next commit which then adds those tests.
This makes the path info serialisers ideomatic again, which allows me to test them.
ac860fd
to
70f8b96
Compare
…version Give `nix daemon` and `nix-store --serve` protocols separate serializers with version info (cherry picked from commit 8b68bbb) Change-Id: Ia3d3b9fbaf9f0ae62ab225020b7d14790e793655
This allows that the versioning parts for it to actually be correct.
Version agnostic serializers are deduped in
common-protocol.hh
/namespace nix::common_proto
, while version-specific ones written separately in{worker,serve-proto.hh
/namespace nix::{worker,serve}_proto
.Motivation
For me, these are main motivations for this:
No more perverse incentives. fe1f34f did some awkward things because the serializers did not store the version. I don't want anyone making changes to be pushed towards keeping the serialization logic with the core data types because it's easier.
I am confident with the incremental approach I tried out in Factoring out parts of the serve protocol for Hydra to share #6134, we can get Hydra using
ssh-ng://
(and theStore
abstraction) pretty quickly. After that, I hope we can deprecatessh://
for a few releases and then remove it. I don't want to worry about accidentally changing it / breaking it during that time, and having separated codes ensures it stays out of the way!In general, for anyone else implementing the daemon protocol, the more we factor out logic from
daemon.cc
,remote-store.cc
, etc., the easier things will be to understand. There are a number of projects looking to reimplement the daemon protocol, and this helps them.The last two commits are especially notable, because they use the serialization refactoring to dedup and factor out / improves factored out seralizers for:
BuildResult
PathInfo
This demonstrates the sort of cleanup that this is supposed t enable
Context
The history in this PR has been delicately preserved to allow reviewing commit-by-commit. Please do so!
If a certain prefix of commits seems good, we can always merge them first too.
depends on #8360
depends on #9197
Checklist for maintainers
Maintainers: tick if completed or explain if not relevant
tests/**.sh
src/*/tests
tests/nixos/*