deploy-rs icon indicating copy to clipboard operation
deploy-rs copied to clipboard

add support for asynchronous building and pushing of profiles

Open PhilTaken opened this issue 10 months ago • 6 comments

NB: I have opened this Pull Request as a draft since I intend to continue working on it by improving the logging output. Since the builds are started concurrently, the build progress information is pretty much useless and flickers a lot.

Problem

The current implementation builds every single profile synchronously, including remote builds. Since remote builds were introduced back in #175, remote builds could be pipelined to deploy new configurations in a more time-efficient manner.

Solution

Build configurations that support remote builds concurrently.


Sidenote: I have decided to continue building local builds in a synchronous manner because I have run into hardware deadlocks previously when trying to evaluate and/or build multiple systems at the same time.

I have tested this code by deploying to my personal infrastructure (https://github.com/philtaken/dotfiles) and it works as intended.

PhilTaken avatar Apr 18 '24 21:04 PhilTaken

mentioning #46 for visibility

the current version works as expected, the only issue is the log flickering with multiple invocations of nix writing to stdout in parallel. I was considering utilising the raw-internal-json output similarly to how nix-output-monitor does it but that might be out of scope here 🤔

PhilTaken avatar Jun 10 '24 18:06 PhilTaken

activation is fully synchronous but that is usually the part that takes the least amount of time

PhilTaken avatar Jun 10 '24 18:06 PhilTaken

The new approach seems good 👍

rvem avatar Jun 14 '24 10:06 rvem

there are a still lot of unwraps that need to be handled better, this pr is still far from finished but progress has been made:

I added some progress indicators using the indicatif crate for each concurrent build 🥳

This is what they look like (image the spinner spinning and the text changing as nix builds stuff:

image (1)

For remote and builds each host gets its own progress spinner that is reused for all of that hosts profiles since they are built in order anyways. This could be adjusted for multi-profile hosts since indicatif also supports nested tree-like progress bars.

I changed some data structures around to make working with them in async contexts easier. The nested references are somewhat ok until you have to make them work in a async context where you need send objects. deep cloning by hand really isn't a great solution and it really doesnt make any difference performance-wise to add some clones here and there. Nobody is going to deploy to >10k hosts and if they would, cloning the deploy data a few times would be the least of their problems. This also removes a bunch of generic lifetime specifiers which I am not sad about.

PhilTaken avatar Sep 13 '24 06:09 PhilTaken

With these two last commits I would declare this PR somewhat usable 🥳

If anyone wants to try it out with their own setups I would be very happy to hear how it works for you, I am always open for feedback of any kind

PhilTaken avatar Sep 18 '24 11:09 PhilTaken

Hi all, I tried this out, with my setup in ManoftheSea/SeaofDirac/trunk, on targets [littlecreek, crunchbits, technetium]. I saw that it ran the checks for all the systems, which meant building them locally, then proceeded with pushing profiles to the systems in parallel (which resulted in building them remotely, I believe). After all three were ready, they deployed in sequence, and as it was just an update, they all completed happily.

This works well for these three systems, which are a pair of VPSes and a local (to me) server; were I trying to deploy all the systems in my home network, I would prefer instead that my development machine (personal laptop) be able to push the profiles to a single server (technetium), so that it can then act as a substituter for e.g. aluminium and nickel. Maybe provide a "build-host" attribute per-host, with a default of the hostself? e.g. deploy.nickel.buildHost = "technetium"; deploy.littlecreek.buildHost = "littlecreek";

ManoftheSea avatar Sep 18 '24 16:09 ManoftheSea