Skip to content
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

Programs using "bundle ruby" start slower with proprietary gemspec licenses #3664

Closed
hlascelles opened this issue May 28, 2020 · 1 comment · Fixed by #3668
Closed

Programs using "bundle ruby" start slower with proprietary gemspec licenses #3664

hlascelles opened this issue May 28, 2020 · 1 comment · Fixed by #3668
Labels

Comments

@hlascelles
Copy link

We have discovered that specifying a proprietary license in a gemspec causes bundle ruby programs to start slower. This happens independently of platform, bundler or ruby version.

This issue is related to:

  • [x ] Other
$ gem env version
3.0.3
$ bundler -v
Bundler version 1.17.3

I will abide by the code of conduct.

Problem description

We have a large monorepo with 50+ projects. All have gemspecs. We specified a proprietary license "Internal source code", as our application is closed source. We had noticed for some time that our invocation times were not great doing even simple commands.

  1. We invoke a bundle rake command that does nothing
  2. The project Gemfile refers to ~30+ other projects using path attributes
  3. The invocation takes ~ 2.5 seconds

Unintentional debugging

In unrelated work, we added license_finder to our project, and as part of cleanup for that we saw that the gemspec guidelines say that "Not specifying a license means all rights are reserved; others have no rights to use the code for any purpose."

We therefore removed our proprietary license form all of our internal gemspecs. Immediately all of our command execution times improved. In the example above it fell to 0.7 seconds.

The penny drops

Digging deeper, we found that during startup, the rubygems gem performs validate_licenses. As part of this, it tries to see if the license is known, and if it isn't it tries to find the best match by levenshtein distance.

This last algorithmic lookup is not cheap, and it is where the app was spending ~1.8 seconds during every startup, as every internal gem had an unknown license. It also isn't necessary for us when invoking bundle ruby commands, as the warning is never printed, as bundler silences them.

Next steps

This work yielded a number of threads, and overlaps slightly between bundler and rubygems, so I'm sure maintainers from each may be interested. I was starting down the process of creating a PR, but realised that since there a couple of ways of fixing this I should confer first.

At the very least, I'd like to clarify internal mono-repo license best practice. I will open a new issue for that if I may.

Possible actions:

  1. Change the lookup to cache levenshtein distance results for an unknown license.
  2. Change the validation to not do the levenshtein distance lookup if the result won't be used
  3. Something else

Try this at home

If you have a large mono repo with internal project gemspecs, get your sed on and replace all the licenses in all the gemspecs with "FooTest".

Everything will then start slower.

@hlascelles hlascelles changed the title Ruby programs start slower with proprietary gemspec licenses Programs using "bundle ruby" start slower with proprietary gemspec licenses May 28, 2020
@deivid-rodriguez
Copy link
Member

Hi @hlascelles! Thanks for reporting this ticket!

My preferred solution for this would be 2). I was looking at the validation code in rubygems and I see there's a packaging argument to Gem::Specification#validate:

##
# Checks that the specification contains all required fields, and does a
# very basic sanity check.
#
# Raises InvalidSpecificationException if the spec does not pass the
# checks..
def validate(packaging = true, strict = false)
normalize
validation_policy = Gem::SpecificationPolicy.new(self)
validation_policy.packaging = packaging
validation_policy.validate(strict)
end

In my opinion, validation warnings should only apply to a "packaging" (gem authoring) context, not to a general use context.

So my preferred fix would be to refactor rubygems gemspec validations to do this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants