postmodern/chruby

chruby <version> is slow when internet is slow

grosser opened this issue · 14 comments

I have ruby 2.6.5 installed locally and had an internet issue that made my connection slow, but not "dead", using cd or opening a new shell got slow and I dug in why, turns out it's chruby doing some kind of internet connection or dns.

time chruby 2.6.5

real	0m1.097s
user	0m0.058s
sys	0m0.019s

Can this get removed ? ... it seems unnecessary and it works fine when internet is completely down anyway.

chruby.sh and auto.sh do not perform any kind of internet access. It's likely something else in your shell or possibly a rubygems plugin that's loaded by default. Try set -x in your shell or running the 2.6.5 ruby command under strace to try to find what internet access is happening and to what exactly.

switching was what caused the slowness, not running ruby ... set -x did not help and none of my network monitoring tools worked out .. so closing this until I have more info :)

reproduced it now:

  eval "$("$RUBY_ROOT/bin/ruby" - <<EOF
puts "export RUBY_ENGINE=#{defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'};"
puts "export RUBY_VERSION=#{RUBY_VERSION};"
begin; require 'rubygems'; puts "export GEM_ROOT=#{Gem.default_dir.inspect};"; rescue LoadError; end
EOF
)"

causes it ... more specific: any call to ruby with a long body like this (with FOO it worked fine)

	  eval "$("$RUBY_ROOT/bin/ruby" - <<EOF
puts "echo FOOFOOFOO=#{'ruby'};"
EOF
)"

... can we just avoid these calls to ruby when switching ruby somehow ?

for example replacing it with this works fine:

# /usr/local/Cellar/chruby/0.3.9/share/chruby/chruby.sh
  export RUBY_VERSION=$(basename $1)
  export RUBY_ENGINE=ruby
  export GEM_ROOT="$1/lib/ruby/gems/${RUBY_VERSION:0:3}.0"

... basically just need to redo some logic and bash and we are good to go :)

chruby still has to query the ruby to figure out the RUBY_ENGINE, RUBY_VERSION, etc, which may not always be available from the directory name.

This implies that ruby is doing something with the network on startup? Could you run strace ruby -e "p 1" to see what it's calling out to? DNS? rubygems.org?

it's something about dns resolution being slow since that's atm the only thing that is weird on my machine (weird hotel internet)

was unable to use strace/dtruss since I got weird errors that lead me nowhere :(

codesign --remove-signature /usr/bin/ruby
/usr/bin/ruby: the codesign_allocate helper tool cannot be found or used

😞

I'd still think it would be nice to not call ruby when switching rubies as a general rabbit hole and loop avoidance (maybe only do it for simple cases somehow)

Not a macOS user, but it might be that macOS is trying to verify the signature of ruby when it's ran? I thought macOS only did signature verification for .apps?

could totally be something like that, the sus thing is that it only happens for longer inputs

sounds like something is being logged or phoned-home. Is this a work laptop? 🤨

yeah, totally possible.
... I guess just close if you think it's not a good idea or not feasible to remove the "calling ruby" part :)

In 1.0.0 we will be relying less on RUBY_ENGINE and RUBY_VERSION to set the GEM_HOME/GEM_PATH, however those variables are exposed so people can set custom prompts that are ruby-version aware. The puts -> eval trick, while tricky, is the quickest way to get that data from ruby and into variables.

PS: if you're really interested, there are off-the-shelf Wifi MITM hardware that would allow you to inspect all of the traffic going to/from the laptop.
https://www.techtarget.com/searchsecurity/definition/Wi-Fi-Pineapple

FWIW in https://github.com/eregon/chruby/tree/do-no-set-gem-home I avoid the call to ruby, which also e.g. makes switching to JRuby faster.