Skip to content

Commit d43936b

Browse files
authored
Merge pull request #5495 from rmosolgo/reduce-field-definition-memory
Remove Field.from_options to reduce memory usage
2 parents 65de110 + 6f31be9 commit d43936b

12 files changed

Lines changed: 50 additions & 62 deletions

File tree

.github/workflows/ci.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ jobs:
5353
ruby: 3.3
5454
graphql_reject_numbers_followed_by_names: 1
5555
- gemfile: gemfiles/rails_8.1.gemfile
56-
ruby: 3.5
56+
ruby: 4.0
5757
graphql_reject_numbers_followed_by_names: 1
5858
redis: 1
5959
- gemfile: gemfiles/rails_master.gemfile

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ end
1515

1616
if RUBY_VERSION >= "3.2.0"
1717
gem "async", "~>2.0"
18+
gem "minitest-mock"
1819
end
1920

2021
# Required for running `jekyll algolia ...` (via `rake site:update_search_index`)

gemfiles/mongoid_8.gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ gem "libev_scheduler"
1212
gem "evt"
1313
gem "async"
1414
gem "concurrent-ruby", "1.3.4"
15+
gem "minitest-mock"
1516

1617
gemspec path: "../"

gemfiles/mongoid_9.gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ gem "mongoid", "~> 9.0"
1010
gem "libev_scheduler"
1111
gem "evt"
1212
gem "async"
13+
gem "minitest-mock"
1314

1415
gemspec path: "../"

gemfiles/rails_8.0.gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ gem "sequel"
1313
gem "evt"
1414
gem "async"
1515
gem "google-protobuf"
16+
gem "minitest-mock"
1617

1718
gemspec path: "../"

gemfiles/rails_8.1.gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ gem "sequel"
1313
gem "evt"
1414
gem "async"
1515
gem "google-protobuf"
16+
gem "minitest-mock"
1617

1718
gemspec path: "../"

gemfiles/rails_master.gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ gem 'puma'
2222
gem 'sprockets-rails'
2323
gem 'capybara'
2424
gem 'selenium-webdriver'
25+
gem "minitest-mock"
2526

2627
gemspec path: "../"
2728

graphql.gemspec

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ Gem::Specification.new do |s|
3737

3838
s.add_development_dependency "minitest"
3939
s.add_development_dependency "minitest-focus"
40-
s.add_development_dependency "minitest-mock"
4140
s.add_development_dependency "minitest-reporters"
4241
s.add_development_dependency "ostruct"
4342
s.add_development_dependency "rake"

lib/graphql/schema/field.rb

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -109,52 +109,6 @@ def subscription_scope
109109
end
110110
attr_writer :subscription_scope
111111

112-
# Create a field instance from a list of arguments, keyword arguments, and a block.
113-
#
114-
# This method implements prioritization between the `resolver` or `mutation` defaults
115-
# and the local overrides via other keywords.
116-
#
117-
# It also normalizes positional arguments into keywords for {Schema::Field#initialize}.
118-
# @param resolver [Class] A {GraphQL::Schema::Resolver} class to use for field configuration
119-
# @param mutation [Class] A {GraphQL::Schema::Mutation} class to use for field configuration
120-
# @param subscription [Class] A {GraphQL::Schema::Subscription} class to use for field configuration
121-
# @return [GraphQL::Schema:Field] an instance of `self`
122-
# @see {.initialize} for other options
123-
def self.from_options(name = nil, type = nil, desc = nil, comment: nil, resolver: nil, mutation: nil, subscription: nil,**kwargs, &block)
124-
if (resolver_class = resolver || mutation || subscription)
125-
# Add a reference to that parent class
126-
kwargs[:resolver_class] = resolver_class
127-
end
128-
129-
if name
130-
kwargs[:name] = name
131-
end
132-
133-
if comment
134-
kwargs[:comment] = comment
135-
end
136-
137-
if !type.nil?
138-
if desc
139-
if kwargs[:description]
140-
raise ArgumentError, "Provide description as a positional argument or `description:` keyword, but not both (#{desc.inspect}, #{kwargs[:description].inspect})"
141-
end
142-
143-
kwargs[:description] = desc
144-
kwargs[:type] = type
145-
elsif (resolver || mutation) && type.is_a?(String)
146-
# The return type should be copied from the resolver, and the second positional argument is the description
147-
kwargs[:description] = type
148-
else
149-
kwargs[:type] = type
150-
end
151-
if type.is_a?(Class) && type < GraphQL::Schema::Mutation
152-
raise ArgumentError, "Use `field #{name.inspect}, mutation: Mutation, ...` to provide a mutation to this field instead"
153-
end
154-
end
155-
new(**kwargs, &block)
156-
end
157-
158112
# Can be set with `connection: true|false` or inferred from a type name ending in `*Connection`
159113
# @return [Boolean] if true, this field will be wrapped with Relay connection behavior
160114
def connection?

lib/graphql/schema/member/has_fields.rb

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,42 @@ class Member
66
# Shared code for Objects, Interfaces, Mutations, Subscriptions
77
module HasFields
88
# Add a field to this object or interface with the given definition
9-
# @see {GraphQL::Schema::Field#initialize} for method signature
9+
# @param name_positional [Symbol] Keyword `name:` also supported
10+
# @param type_positional [Class, Array<Class>] Keyword `type:` also supported
11+
# @param desc_positional [String] Keyword `description:` also supported
12+
# @see {GraphQL::Schema::Field#initialize} for keywords
1013
# @return [GraphQL::Schema::Field]
11-
def field(*args, **kwargs, &block)
12-
field_defn = field_class.from_options(*args, owner: self, **kwargs, &block)
14+
def field(name_positional = nil, type_positional = nil, desc_positional = nil, **kwargs, &block)
15+
resolver = kwargs.delete(:resolver)
16+
mutation = kwargs.delete(:mutation)
17+
subscription = kwargs.delete(:subscription)
18+
if (resolver_class = resolver || mutation || subscription)
19+
# Add a reference to that parent class
20+
kwargs[:resolver_class] = resolver_class
21+
end
22+
23+
kwargs[:name] ||= name_positional
24+
if !type_positional.nil?
25+
if desc_positional
26+
if kwargs[:description]
27+
raise ArgumentError, "Provide description as a positional argument or `description:` keyword, but not both (#{desc_positional.inspect}, #{kwargs[:description].inspect})"
28+
end
29+
30+
kwargs[:description] = desc_positional
31+
kwargs[:type] = type_positional
32+
elsif (resolver || mutation) && type_positional.is_a?(String)
33+
# The return type should be copied from the resolver, and the second positional argument is the description
34+
kwargs[:description] = type_positional
35+
else
36+
kwargs[:type] = type_positional
37+
end
38+
39+
if type_positional.is_a?(Class) && type_positional < GraphQL::Schema::Mutation
40+
raise ArgumentError, "Use `field #{name_positional.inspect}, mutation: Mutation, ...` to provide a mutation to this field instead"
41+
end
42+
end
43+
44+
field_defn = field_class.new(owner: self, **kwargs, &block)
1345
add_field(field_defn)
1446
field_defn
1547
end

0 commit comments

Comments
 (0)