-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Autoload nested constants #5178
Conversation
Looks like I have some tests to fix. I'm on it 👀 |
f9617b3
to
c97ce16
Compare
I think the rest are happening on the main branch. Let me know if I'm wrong. |
c97ce16
to
4173f26
Compare
Hey, thanks so much for putting in the time on this. It's been in the back of my mind for a long time to improve the organization of all those
This seems alright to me. I'm trying to think if we can detect these and warn in cases where this should be called. Are there other setups that come to mind besides Sinatra and Hanami? (I mean, there's plain Rack, and a long tail of other possibilities, but any other big ones?)
I'm comfortable assuming that all_constants = GraphQL.constants.map { |const_name| GraphQL.const_get(const_name) }
eager_loadable_constants = all_constants - [
# Any specific exceptions to autoloading can go here, along with a comment for why they're skipped
]
assert_equal eager_loadable_constants, GraphQL.eager_load! And then do something similar for Yes, those other tests are failing on |
I'll investigate this. Let's narrow the scope to Sinatra, Hanami, and Rails. Everything else can be supported later, and we can instruct folks to call that method themselves in more exotic cases. I'll add this to the docs.
Sounds good. I'll re-implement a minimal version of |
Reduces require time from ~160ms to ~5ms. Autoloads all constants under `GraphQL` to optimize boot time. Also autoloads `GraphQL::Types` and `GraphQL::Query` because they can't be required in sequence. Autoloads are automatically managed with `GraphQL::Autoload` similar to `ActiveSupport::Autoload`.
4173f26
to
11799e0
Compare
I wrote a document page, added |
Looks good, thanks again for this improvement! I'm going to shuffle the doc around a bit before I publish. |
I'm looking over it one more time and adding more docs... it seems like |
🚢 in 2.4.5! Thanks again. |
Ah, you're right. Thanks for the correction! |
GraphQL gem 2.4.5 includes some changes related to code loading: rmosolgo/graphql-ruby#5178 I've made a few changes to deal with that: * I've introduced `::GraphQL.eager_load!` where we do eager loading for production. * I've stopped requiring files nested under `graphql`--instead, we should load `graphql` and rely on the autoloading.
GraphQL gem 2.4.5 includes some changes related to code loading: rmosolgo/graphql-ruby#5178 I've made a few changes to deal with that: * I've introduced `::GraphQL.eager_load!` where we do eager loading for production. * I've stopped requiring files nested under `graphql`--instead, we should load `graphql` and rely on the autoloading.
Hey @sealabcore, no... it's not supposed to show that all the time :S I was able to replicate this immediately with First, Rails calls Then, it does Here's the source for that: https://github.com/rails/rails/blob/91d456366638ac6c3f6dec38670c8ada5e7c69b1/railties/lib/rails/application/finisher.rb#L79-L81 So I think everything works -- everything is loaded when the application starts -- but the integration needs to be improved. I'll take a closer look tomorrow, sorry for the trouble! |
Hm, the application could reference any GraphQL constant in theory, so it might make more sense to use |
I can confirm this fixes the issue. If we want to make sure the gem is eager loaded before we eager load the app, I think this is our best bet, so I'll issue the patch. Sorry for the problems folks. |
Thanks for taking care of it, @gmcgibbon! I just shipped that patch in 2.4.6. @sealabcore, thanks for reporting this and sorry for the trouble. Please give that new version a try and let me know if it gives you any more issues! |
Thanks to you both for the quick resolution! I’ll give this a try today. |
We've had a report that this change breaks constant loading if any of the nested files are required during app boot (I can open a new issue on this if necessary). Here's a minimal reproduction: require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'graphql', '2.4.7'
end
require 'graphql'
require 'graphql/tracing/active_support_notifications_trace'
GraphQL.eager_load! What I think is happening is that the nested graphql/tracing/**.rb files don't require their parent (tracing.rb). So requiring this file:
I believe all of these nested files should include a top-level |
Reduces require time from ~160ms to ~5ms. Autoloads all constants under
GraphQL
to optimize boot time. Also autoloadsGraphQL::Types
andGraphQL::Query
because they can't be required in sequence.Script:
Before:
After:
Rails will automatically eager load GraphQL, but other frameworks / setups will need to call
GraphQL.eager_load!
. If we agree with the approach, I can document this. Because we don't require on Active Support, we need to manually implement eager loading.ActiveSupport::Autoload
implements theeager_load!
method for you.Also, if you're interested, I can implement testing for eager loading (example), but we'll need to roll our own test isolation feature.