-
Notifications
You must be signed in to change notification settings - Fork 498
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
Run modify scripts in parallel #2814
Comments
This is similar to #2740. chezmoi runs scripts sequentially in a strict order for transparency and repeatability. Writing scripts that perform correctly when run concurrently is extremely difficult, and running them concurrently is not repeatable. You can run things concurrently in a single script, for an example see #2740 (comment). |
This might be true in the general case, and for However, there is of course that someone doesn't do something silly in their modification scripts! Maybe the feature could be opt-in? Still I understand you are probably thinking about getting annoying bug reports from users who blame the problems on chezmoi itself...
This is true in general, but not for The only option to parallelise my use case would be convert to a single
At that point all chezmoi is doing is calling my program, I'm essentially not able to reuse/piggy back on any functionality from chezmoi. |
Ah, thanks for the extra detail. I'd somehow missed that this was specific to This is effectively concurrent generation of the target state. It's something that I'd like to implement eventually but it will require a significant refactor/rewrite of chezmoi's internals. Currently the source state is generated concurrently, but the target state generation and application to the destination directory are not. So, it's likely a chezmoi version 3 feature. In the short term, is it possible to replace your Python |
I very much doubt it (or it will be exceedingly silly and painful). My script parses a source copy of the file as well as the target state of the file as INI, then merges those according to rules. See https://github.com/VorpalBlade/chezmoi_modify_manager I think the best course of action for me would be to rewrite this in a compiled language (i.e. Rust, I'm on that bandwagon currently) and then make the modify scripts not be bash scripts that call the rust program but instead do something like this chezmoi template as the
That is, pretend to the system/chezmoi that my rust program is an "interpreter" of this file which is actually just the config file that describes how and what to merge. I would love to not need to rely on chezmoi templating here (since presumably that takes some time as well), but I really don't see a way around it, without hard coding in the path of my home directory (which may vary between systems!). Plus I need different binaries for different architectures anyway. This will likely be faster than a bash script that calls python (which is what currently happens). But the future concurrency support would be really nice, there is only so much I can do on my end. Right now chezmoi is quite slow, taking almost a second on this laptop that is a few years old (with an i7-8550U, so not a low end laptop by any means): $ hyperfine "chezmoi diff"
Benchmark 1: chezmoi diff
Time (mean ± σ): 898.6 ms ± 12.6 ms [User: 743.0 ms, System: 164.3 ms]
Range (min … max): 888.9 ms … 932.0 ms 10 runs |
Note to self: some template functions are not threadsafe, for example |
That seems odd, surely it would be sense to be able to execute a glob relative any directory, not just the current working directory? That said, expanding the templates however it is done currently followed by running the actual processes async concurrently should work, right? I don't know Go but I believe it has async support (just like Rust does)? At the OS level it would probably be something like a posix_spawn call (so you don't have to deal with the mess that is fork+exec in a multi-threaded program). |
The
It's not just |
Is your feature request related to a problem? Please describe.
I have a few modify scripts (to deal with KDE):
and I have noticed the performance of operations like
chezmoi diff
seem to degrade linearly with the number of scripts.I used strace to figure out what was going on, and to me it looks like chezmoi waits for each script to run before starting the next one. There is no reason modify scripts could not be run in parallel (as they do not affect each other). Even if the scripts are completely CPU bound this would be a big speedup (8x - 16x in my case, depending on the computer). In practise my scripts perform a mix of IO and CPU, so the speedup could be even bigger (or smaller).
Describe the solution you'd like
I propose that modify scripts should be executed in parallel by chezmoi. That would interfer with the proposed solution of using
/dev/tty
in #2244 (which I have not yet implemented) but that is a non-standard thing to do and could be solved with the scripts themselves using locking between themselves when they rarely need to interact with the terminal.Describe alternatives you've considered
I considered rewriting my python script in Rust. This would undoubtedly speed it up, and I might end up doing this in the end anyway. It is however harder to distribute (need to have x86, x86-64, ARM32 and ARM64 versions for just my own personal needs for example).
My script does not however allow much internal parallelisation, so it would still not be able to make efficient use of all cores. Running multiple modify scripts in parallel would still be beneficial regardless.
Additional context
It would be interesting to think about if there are any other areas of chezmoi that would benefit from parallelisation as well, but I feel that is the topic of another issue.
The text was updated successfully, but these errors were encountered: