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

Improve handling of chaining #require_relative patch #401

Closed
wants to merge 3 commits into from

Conversation

harrycis
Copy link

@harrycis harrycis commented Feb 4, 2022

Kernel.require_relative could be patched again by other Gems initialized after bootsnap. This change supports the chaining of Kernel.require_relative

@ghost ghost added the cla-needed label Feb 4, 2022
location = caller_locations(1..1).first
location = caller_locations.find { |x| x.base_label != "require_relative" }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hum this increase the cost quite significantly.

Out of curiosity what else decorates require_relative? Maybe we could do something like caller_locations(1..3) to support up to two extra decorators?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly, not aware of any public Gem decorate it, but our projects internally is about to decorate it to track some state change pre/post file load, and it's blocked by the decorator in bootnap.

Only traverse the first few caller seems fine to me. The chaining of require_relative may not happen that often probably.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll have to look on Monday if we even still need to decorate require_relative. I think it we might be able to remove this decorator entirely.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, so this is the change I remembered that may allow us to remove the require_relative decorator: ruby/ruby@79a4484. It shipped with Ruby 3.1, so that wouldn't remove it for everyone, but I'm much less concerned about a small perf impact if it doesn't apply to the newest rubies.

The decorator was added in #136, I'll have to dig more to see what it would take to remove it on 3.1+.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hum, the more I dig into #136, the more it seems like we tried to limit a Ruby bug more than a Bootsnap bug.

Assuming a/test.rb and b/test.rb symlink each others, the following load the file twice on all rubies but 3.1:

require_relative "b/test.rb"
require_relative "a/test.rb"

So I don't think we should have done this at all.

@casperisfine
Copy link
Contributor

So after digging into it for most of the day, I confirm that we can simply get rid of the require_relative decorator entirely: #402.

@harrycis
Copy link
Author

harrycis commented Feb 8, 2022

That would work. I am closing the PR then.

Thanks for the investigation, folks!

@harrycis harrycis closed this Feb 8, 2022
@casperisfine
Copy link
Contributor

Welcome. I might not release this right away as there's a couple other things I'd like to include. I recommend using the main branch in your Gemfile if you need a fix right away.

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

Successfully merging this pull request may close these issues.

None yet

3 participants