-
Notifications
You must be signed in to change notification settings - Fork 460
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
terraform executions delayed by ~ 1 second #196
Comments
I think this has to do with the logging calls and the subshells, would be nice to add an option to short circuit even before all the local assignments in the |
It's a very unfortunately good point. In all the hard work to improve the visibility and logging, the performance has been overlooked, mostly as it's not been considered a critical issue, however the language server is indeed pushing this issue. I will take a look at the code shortly and see what we can do to at least shortcut the performance drains when desirable. We are frankly at the point where bash is the wrong language for this solution, and a Go implementation would make much more sense. I'm kinda hoping Hashicorp want to step up to the plate on that one as I have no Go development experience and a proper versioning mechanism managed in-house would be a much more joined up experience. |
Ok, this is what I'm thinking: if [ -n "${BASHLOG_DISABLE:-""}" ]; then
function log () {
case "${1}" in
'error')
echo "[${1}] ${@:2}" 2>&1;
exit 1;
;;
'info')
echo "[${1}] ${@:2}";
;;
esac;
};
export -f log;
else
source "${TFENV_ROOT}/lib/bashlog.sh";
fi; |
(My VM has very poor I/O performance :D ) |
This may be useful for you, we have a forthcoming tiny binary called We could probably augment that to also be able to install from a .terraform-version file or something, or at least be integrated in to the existing scripts. Not a full Go solution, but a partial one at least. We are not looking to replicate the full |
Have you thought about refactoring tfenv to operate the same way as more modern version managers, such as chruby and chnode? Instead of having a shim executable (the (Now that I checked, there is actually a Terraform version manager, aptly called chtf, that already does this.) |
@Zordrak I think the workaround with However I still believe that executions should just be quick by default for all users. |
For me on Windows 10 in Cygwin (bash) this has been driving me nuts...
BASHLOG_DISABLE does nothing for me. |
@Zordrak any additional progress on this front? I use tfenv extensively and I'm just realizing now that tfenv is the reason my bash prompt (which utilizes If not direct progress is being made on this front... Do you know if there is any fast way to collect the current Terraform version from tfenv without the lag being discussed here? |
@Zordrak friendly ping on this one. |
Oh wow, all this time I was thinking terraform slowed down over the years. Turns out I've made my own basic version manager a few months ago as an experiment and now having tried that one, it doesn't seem to suffer from this issue: https://gist.github.com/reegnz/e11a5c9b4bce0cb02e287e2327799466 So I'll probably integrate that into my CI instead of tfenv, but I'd be glad if tfenv would also fix this, I'd rather use a version manager with a community behind it. |
@Zordrak I prepared two PR-s to fix this annoying issue. #312 implements loading bashlog.sh conditionally. I regard this one as the inferior solution as it breaks backward compatibility with logging to file, syslog and json. #313 is fixing bashlog.sh itself, resulting in almost the exact same performance characteristics, without breaking backward compatibility. Only one of the above two needs merging, I'd rather have #313 be that change. Everyone in this thread is welcome to test-drive #313 so we can merge it ASAP. The more people verify it, the bigger the confidence in the change not breaking anything. |
I tried replacing my Widnows 10 + Cygwin
|
I have created a dead-simple terraform installer and wrapper in case someone is really blocked by the overhead and needs a dead-simple out-of-your-way wrapper to use multiple terraform-versions. It's less featureful, doesn't try to infer the version from any .tf file, but also tries very hard to be as least intrusive as possible. I have measured the overhead of the wrapper to be close to non-existant: Terraform v1.1.5
on darwin_amd64
terraform version 0.04s user 0.03s system 108% cpu 0.058 total vs without the wrapper I'm seeing around 0.045, so the overhead is around 10ms it seems. PR-s are welcome. |
I have a very strong feeling now, that bashlog should be completely eliminated from the I did some measurements comparing tfenv to my ❯ hyperfine '~/github/reegnz/terraform-install/terraform version' '~/.cache/terraform/versions/1.1.5/terraform version' '~/github/reegnz/tfenv/bin/terraform version'
Benchmark 1: ~/github/reegnz/terraform-install/terraform version
Time (mean ± σ): 43.0 ms ± 1.3 ms [User: 32.0 ms, System: 14.7 ms]
Range (min … max): 36.8 ms … 46.4 ms 60 runs
Benchmark 2: ~/.cache/terraform/versions/1.1.5/terraform version
Time (mean ± σ): 32.1 ms ± 0.9 ms [User: 29.3 ms, System: 10.8 ms]
Range (min … max): 30.5 ms … 34.9 ms 77 runs
Benchmark 3: ~/github/reegnz/tfenv/bin/terraform version
Time (mean ± σ): 1.490 s ± 0.009 s [User: 0.441 s, System: 0.472 s]
Range (min … max): 1.477 s … 1.508 s 10 runs
Summary
'~/.cache/terraform/versions/1.1.5/terraform version' ran
1.34 ± 0.06 times faster than '~/github/reegnz/terraform-install/terraform version'
46.40 ± 1.38 times faster than '~/github/reegnz/tfenv/bin/terraform version' Even with the perf improvements to bashlog in #313 it's still significantly slower: ❯ hyperfine '~/github/reegnz/terraform-install/terraform version' '~/.cache/terraform/versions/1.1.5/terraform version' '~/github/reegnz/tfenv/bin/terraform version'
Benchmark 1: ~/github/reegnz/terraform-install/terraform version
Time (mean ± σ): 43.6 ms ± 1.0 ms [User: 32.9 ms, System: 15.0 ms]
Range (min … max): 41.7 ms … 46.7 ms 58 runs
Benchmark 2: ~/.cache/terraform/versions/1.1.5/terraform version
Time (mean ± σ): 31.9 ms ± 0.8 ms [User: 29.5 ms, System: 10.7 ms]
Range (min … max): 30.1 ms … 33.7 ms 75 runs
Benchmark 3: ~/github/reegnz/tfenv/bin/terraform version
Time (mean ± σ): 132.3 ms ± 3.1 ms [User: 69.4 ms, System: 37.3 ms]
Range (min … max): 126.8 ms … 138.1 ms 21 runs
Summary
'~/.cache/terraform/versions/1.1.5/terraform version' ran
1.36 ± 0.05 times faster than '~/github/reegnz/terraform-install/terraform version'
4.15 ± 0.14 times faster than '~/github/reegnz/tfenv/bin/terraform version' Keep in mind that |
Am I correct that tfenv internally uses a bunch of subprocesses, since it calls out to its own libexec scripts a lot? And each of those needs to repeat bootstrapping tasks? Seems like refactoring into functions that can each be lazy-loaded into a single bash process might help, on top of removing bashlog as @reegnz has suggested. |
@cspotcode yes, you're correct in that assumption, currently it forks subprocesses on each logger call, which results in a huge overhead. I think that's not a problem during tfenv calls (eg. install, list, etc), but the |
Music to my ears @reegnz. Thanks for your PR (https://github.com/tfutils/tfenv/pull/313/files to anyone interested) and I hope it gets merged soon because my organization is absolutely getting killed by the performance of tfenv. Using IntelliJ file watchers with a tfenv-terraform-wrapper backed script is a lesson in brutal pain, and its adding significant time to our CD pipeline, too. |
Note that anyone can start using these improvements today. Use the Manual installation instructions and checkout the appropriate branch. |
I also have a homebrew-installable alternative for those who don't shy away from new things: https://github.com/reegnz/terraform-install |
FYI fix is now released as part of https://github.com/tfutils/tfenv/releases/tag/v3.0.0 |
True, the logger calls fork a lot. But I was also thinking about how it
forks the various binaries declared in ./libexec
…On Tue, Mar 8, 2022, 6:03 AM Zoltán Reegn ***@***.***> wrote:
@cspotcode <https://github.com/cspotcode> yes, you're correct in that
assumption, currently it forks subprocesses on each logger call, which
results in a huge overhead. I think that's not a problem during tfenv
calls, but the terraform shim should probably eliminate the entirety of
bashlog calls and do the bare minimum it needs to do (select the
appropriate binary version, and reexec with that binary).
—
Reply to this email directly, view it on GitHub
<#196 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAC35OGNEVYMSFKIRQLMHXLU64XWJANCNFSM4OVSFJ5Q>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Whenever I execute any
terraform
command (even a simpleterraform version
) there is a noticeable ~1 second delay.0.12.28 installed via tfenv
executed via tfenv
tfenv 2.0.0 installed from Homebrew via
brew install tfenv
terraform installed via
tfenv install 0.12.28 && tfenv use 0.12.28
executed directly
0.12.28 installed directly
Installed from Homebrew via
brew install terraform
Besides negatively impacting the UX overall, it more specifically impacts users of the Terraform language server, because some editors (e.g. Sublime Text) expect the server to respond within 1 second and they drop the response otherwise, hence breaking e.g. auto-formatting capability.
Environment
macOS Catalina (10.15.5)
Processor: 3.5 GHz Dual-Core Intel Core i7
Memory: 16 GB 2133 MHz LPDDR3
The text was updated successfully, but these errors were encountered: