graphql 2.0.24 → 2.0.25

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7c97d63232efb5f7ecdaef0f8102a73ceaa4a4b0a3b06c7ab1f613735efafa59
4
- data.tar.gz: aff3df56a3db15d97f457e92fffab33f29440fed5ca84b0515794ad051e5631e
3
+ metadata.gz: 289b06689b36a3673c053d13d2ce0835a089e92db60e3e24e8af791fdd934d81
4
+ data.tar.gz: 3c5257c0732d0729b97ac92376427ccba26ef66397f9b9d07c18e9792ea03251
5
5
  SHA512:
6
- metadata.gz: 3cf33d0ed4df848c57e459f9ee023b0a6b2814d14ef09d7c304120a595cd62e65f25b05b3f16448c89cfb9479d06e550611c42fa76b3fb92a677c788f31f713e
7
- data.tar.gz: 28b8d5e3fb2d6cc0bc3ebbdaf6f6d53dc16b0225bcafcc0fe72d4956afb9ff0fdb1ca929093ad466951dc28a30d893e643c8fb68bff69df374e41e1c43e2980b
6
+ metadata.gz: 72ad503ed008aa168a63c1a40ac9e44dbb9b2d6a7871f1cd6191a692d6275506ce17f0df3135ae0a2ef95fe695a457d76239a2623f477cf7cd7f27cc124888c7
7
+ data.tar.gz: 90976b77a4230bf8a7d3fe5470deae70082e6caac1d3b30c799e958621cd2177283d0f83eb06128081e7e2179e33e718a1ba9353ab388fac83553e0988e7b4bc
@@ -6,7 +6,7 @@ module Graphql
6
6
  # TODO: What other options should be supported?
7
7
  #
8
8
  # @example Generate a `GraphQL::Schema::RelayClassicMutation` by name
9
- # rails g graphql:mutation CreatePostMutation
9
+ # rails g graphql:mutation DeletePostMutation
10
10
  class MutationDeleteGenerator < OrmMutationsBase
11
11
 
12
12
  desc "Scaffold a Relay Classic ORM delete mutation for the given model class"
@@ -6,7 +6,7 @@ module Graphql
6
6
  # TODO: What other options should be supported?
7
7
  #
8
8
  # @example Generate a `GraphQL::Schema::RelayClassicMutation` by name
9
- # rails g graphql:mutation CreatePostMutation
9
+ # rails g graphql:mutation UpdatePostMutation
10
10
  class MutationUpdateGenerator < OrmMutationsBase
11
11
 
12
12
  desc "Scaffold a Relay Classic ORM update mutation for the given model class"
@@ -7,9 +7,9 @@ module GraphQL
7
7
  # @api private
8
8
  def setup(dataloader)
9
9
  # These keys have been requested but haven't been fetched yet
10
- @pending_keys = []
10
+ @pending = {}
11
11
  # These keys have been passed to `fetch` but haven't been finished yet
12
- @fetching_keys = []
12
+ @fetching = {}
13
13
  # { key => result }
14
14
  @results = {}
15
15
  @dataloader = dataloader
@@ -18,42 +18,66 @@ module GraphQL
18
18
  attr_reader :dataloader
19
19
 
20
20
  # @return [Dataloader::Request] a pending request for a value from `key`. Call `.load` on that object to wait for the result.
21
- def request(key)
22
- if !@results.key?(key)
23
- @pending_keys << key
21
+ def request(value)
22
+ res_key = result_key_for(value)
23
+ if !@results.key?(res_key)
24
+ @pending[res_key] ||= value
24
25
  end
25
- Dataloader::Request.new(self, key)
26
+ Dataloader::Request.new(self, value)
27
+ end
28
+
29
+ # Implement this method to return a stable identifier if different
30
+ # key objects should load the same data value.
31
+ #
32
+ # @param value [Object] A value passed to `.request` or `.load`, for which a value will be loaded
33
+ # @return [Object] The key for tracking this pending data
34
+ def result_key_for(value)
35
+ value
26
36
  end
27
37
 
28
38
  # @return [Dataloader::Request] a pending request for a values from `keys`. Call `.load` on that object to wait for the results.
29
- def request_all(keys)
30
- pending_keys = keys.select { |k| !@results.key?(k) }
31
- @pending_keys.concat(pending_keys)
32
- Dataloader::RequestAll.new(self, keys)
39
+ def request_all(values)
40
+ values.each do |v|
41
+ res_key = result_key_for(v)
42
+ if !@results.key?(res_key)
43
+ @pending[res_key] ||= v
44
+ end
45
+ end
46
+ Dataloader::RequestAll.new(self, values)
33
47
  end
34
48
 
35
- # @param key [Object] A loading key which will be passed to {#fetch} if it isn't already in the internal cache.
49
+ # @param value [Object] A loading value which will be passed to {#fetch} if it isn't already in the internal cache.
36
50
  # @return [Object] The result from {#fetch} for `key`. If `key` hasn't been loaded yet, the Fiber will yield until it's loaded.
37
- def load(key)
38
- if @results.key?(key)
39
- result_for(key)
51
+ def load(value)
52
+ result_key = result_key_for(value)
53
+ if @results.key?(result_key)
54
+ result_for(result_key)
40
55
  else
41
- @pending_keys << key
42
- sync([key])
43
- result_for(key)
56
+ @pending[result_key] ||= value
57
+ sync([result_key])
58
+ result_for(result_key)
44
59
  end
45
60
  end
46
61
 
47
- # @param keys [Array<Object>] Loading keys which will be passed to `#fetch` (or read from the internal cache).
62
+ # @param values [Array<Object>] Loading keys which will be passed to `#fetch` (or read from the internal cache).
48
63
  # @return [Object] The result from {#fetch} for `keys`. If `keys` haven't been loaded yet, the Fiber will yield until they're loaded.
49
- def load_all(keys)
50
- if keys.any? { |k| !@results.key?(k) }
51
- pending_keys = keys.select { |k| !@results.key?(k) }
52
- @pending_keys.concat(pending_keys)
64
+ def load_all(values)
65
+ result_keys = []
66
+ pending_keys = []
67
+ values.each { |v|
68
+ k = result_key_for(v)
69
+ result_keys << k
70
+ if !@results.key?(k)
71
+ @pending[k] ||= v
72
+ pending_keys << k
73
+ end
74
+ }
75
+
76
+ if pending_keys.any?
53
77
  sync(pending_keys)
54
78
  end
55
79
 
56
- keys.map { |k| result_for(k) }
80
+ result_keys.map { |k| result_for(k) }
57
81
  end
58
82
 
59
83
  # Subclasses must implement this method to return a value for each of `keys`
@@ -67,13 +91,13 @@ module GraphQL
67
91
  # Wait for a batch, if there's anything to batch.
68
92
  # Then run the batch and update the cache.
69
93
  # @return [void]
70
- def sync(pending_keys)
94
+ def sync(pending_result_keys)
71
95
  @dataloader.yield
72
96
  iterations = 0
73
- while pending_keys.any? { |k| !@results.key?(k) }
97
+ while pending_result_keys.any? { |key| !@results.key?(key) }
74
98
  iterations += 1
75
99
  if iterations > 1000
76
- raise "#{self.class}#sync tried 1000 times to load pending keys (#{pending_keys}), but they still weren't loaded. There is likely a circular dependency."
100
+ raise "#{self.class}#sync tried 1000 times to load pending keys (#{pending_result_keys}), but they still weren't loaded. There is likely a circular dependency."
77
101
  end
78
102
  @dataloader.yield
79
103
  end
@@ -82,15 +106,18 @@ module GraphQL
82
106
 
83
107
  # @return [Boolean] True if this source has any pending requests for data.
84
108
  def pending?
85
- !@pending_keys.empty?
109
+ !@pending.empty?
86
110
  end
87
111
 
88
112
  # Add these key-value pairs to this source's cache
89
113
  # (future loads will use these merged values).
90
- # @param results [Hash<Object => Object>] key-value pairs to cache in this source
114
+ # @param new_results [Hash<Object => Object>] key-value pairs to cache in this source
91
115
  # @return [void]
92
- def merge(results)
93
- @results.merge!(results)
116
+ def merge(new_results)
117
+ new_results.each do |new_k, new_v|
118
+ key = result_key_for(new_k)
119
+ @results[key] = new_v
120
+ end
94
121
  nil
95
122
  end
96
123
 
@@ -98,24 +125,22 @@ module GraphQL
98
125
  # @api private
99
126
  # @return [void]
100
127
  def run_pending_keys
101
- if !@fetching_keys.empty?
102
- @pending_keys -= @fetching_keys
128
+ if !@fetching.empty?
129
+ @fetching.each_key { |k| @pending.delete(k) }
103
130
  end
104
- return if @pending_keys.empty?
105
- fetch_keys = @pending_keys.uniq
106
- @fetching_keys.concat(fetch_keys)
107
- @pending_keys = []
108
- results = fetch(fetch_keys)
109
- fetch_keys.each_with_index do |key, idx|
131
+ return if @pending.empty?
132
+ fetch_h = @pending
133
+ @pending = {}
134
+ @fetching.merge!(fetch_h)
135
+ results = fetch(fetch_h.values)
136
+ fetch_h.each_with_index do |(key, _value), idx|
110
137
  @results[key] = results[idx]
111
138
  end
112
139
  nil
113
140
  rescue StandardError => error
114
- fetch_keys.each { |key| @results[key] = error }
141
+ fetch_h.each_key { |key| @results[key] = error }
115
142
  ensure
116
- if fetch_keys
117
- @fetching_keys -= fetch_keys
118
- end
143
+ fetch_h && fetch_h.each_key { |k| @fetching.delete(k) }
119
144
  end
120
145
 
121
146
  # These arguments are given to `dataloader.with(source_class, ...)`. The object
@@ -136,7 +161,7 @@ module GraphQL
136
161
  [*batch_args, **batch_kwargs]
137
162
  end
138
163
 
139
- attr_reader :pending_keys
164
+ attr_reader :pending
140
165
 
141
166
  private
142
167
 
@@ -111,8 +111,8 @@ module GraphQL
111
111
  @source_cache.each do |source_class, batched_sources|
112
112
  batched_sources.each do |batch_args, batched_source_instance|
113
113
  if batched_source_instance.pending?
114
- prev_pending_keys[batched_source_instance] = batched_source_instance.pending_keys.dup
115
- batched_source_instance.pending_keys.clear
114
+ prev_pending_keys[batched_source_instance] = batched_source_instance.pending.dup
115
+ batched_source_instance.pending.clear
116
116
  end
117
117
  end
118
118
  end
@@ -127,8 +127,8 @@ module GraphQL
127
127
  res
128
128
  ensure
129
129
  @pending_jobs = prev_queue
130
- prev_pending_keys.each do |source_instance, pending_keys|
131
- source_instance.pending_keys.concat(pending_keys)
130
+ prev_pending_keys.each do |source_instance, pending|
131
+ source_instance.pending.merge!(pending)
132
132
  end
133
133
  end
134
134
 
@@ -158,16 +158,24 @@ module GraphQL
158
158
  def trace_class_for(mode)
159
159
  @trace_modes ||= {}
160
160
  @trace_modes[mode] ||= begin
161
- if mode == :default_backtrace
161
+ case mode
162
+ when :default
163
+ superclass_base_class = if superclass.respond_to?(:trace_class_for)
164
+ superclass.trace_class_for(mode)
165
+ else
166
+ GraphQL::Tracing::Trace
167
+ end
168
+ Class.new(superclass_base_class)
169
+ when :default_backtrace
162
170
  schema_base_class = trace_class_for(:default)
163
171
  Class.new(schema_base_class) do
164
172
  include(GraphQL::Backtrace::Trace)
165
173
  end
166
- elsif superclass.respond_to?(:trace_class_for)
167
- superclass_base_class = superclass.trace_class_for(mode)
168
- Class.new(superclass_base_class)
169
174
  else
170
- Class.new(GraphQL::Tracing::Trace)
175
+ mods = trace_modules_for(mode)
176
+ Class.new(trace_class_for(:default)) do
177
+ mods.any? && include(*mods)
178
+ end
171
179
  end
172
180
  end
173
181
  end
@@ -183,6 +191,19 @@ module GraphQL
183
191
  nil
184
192
  end
185
193
 
194
+ def own_trace_modules
195
+ @own_trace_modules ||= Hash.new { |h, k| h[k] = [] }
196
+ end
197
+
198
+ # @return [Array<Module>] Modules added for tracing in `trace_mode`, including inherited ones
199
+ def trace_modules_for(trace_mode)
200
+ modules = own_trace_modules[trace_mode]
201
+ if superclass.respond_to?(:trace_modules_for)
202
+ modules += superclass.trace_modules_for(trace_mode)
203
+ end
204
+ modules
205
+ end
206
+
186
207
 
187
208
  # Returns the JSON response of {Introspection::INTROSPECTION_QUERY}.
188
209
  # @see {#as_json}
@@ -992,26 +1013,58 @@ module GraphQL
992
1013
  # will be called at runtime.
993
1014
  #
994
1015
  # @param trace_mod [Module] A module that implements tracing methods
1016
+ # @param mode [Symbol] Trace module will only be used for this trade mode
995
1017
  # @param options [Hash] Keywords that will be passed to the tracing class during `#initialize`
996
1018
  # @return [void]
997
- def trace_with(trace_mod, **options)
998
- trace_options.merge!(options)
999
- trace_class.include(trace_mod)
1019
+ def trace_with(trace_mod, mode: :default, **options)
1020
+ if mode.is_a?(Array)
1021
+ mode.each { |m| trace_with(trace_mod, mode: m, **options) }
1022
+ else
1023
+ tc = trace_class_for(mode)
1024
+ tc.include(trace_mod)
1025
+ if mode != :default
1026
+ own_trace_modules[mode] << trace_mod
1027
+ end
1028
+ t_opts = trace_options_for(mode)
1029
+ t_opts.merge!(options)
1030
+ end
1031
+ nil
1000
1032
  end
1001
1033
 
1002
- def trace_options
1003
- @trace_options ||= superclass.respond_to?(:trace_options) ? superclass.trace_options.dup : {}
1034
+ # The options hash for this trace mode
1035
+ # @return [Hash]
1036
+ def trace_options_for(mode)
1037
+ @trace_options_for_mode ||= {}
1038
+ @trace_options_for_mode[mode] ||= begin
1039
+ if superclass.respond_to?(:trace_options_for)
1040
+ superclass.trace_options_for(mode).dup
1041
+ else
1042
+ {}
1043
+ end
1044
+ end
1004
1045
  end
1005
1046
 
1006
- def new_trace(**options)
1007
- options = trace_options.merge(options)
1008
- trace_mode = if (target = options[:query] || options[:multiplex]) && target.context[:backtrace]
1047
+ # Create a trace instance which will include the trace modules specified for the optional mode.
1048
+ #
1049
+ # @param mode [Symbol] Trace modules for this trade mode will be included
1050
+ # @param options [Hash] Keywords that will be passed to the tracing class during `#initialize`
1051
+ # @return [Tracing::Trace]
1052
+ def new_trace(mode: nil, **options)
1053
+ target = options[:query] || options[:multiplex]
1054
+ mode ||= target && target.context[:trace_mode]
1055
+
1056
+ trace_mode = if mode
1057
+ mode
1058
+ elsif target && target.context[:backtrace]
1009
1059
  :default_backtrace
1010
1060
  else
1011
1061
  :default
1012
1062
  end
1013
- trace = trace_class_for(trace_mode).new(**options)
1014
- trace
1063
+
1064
+ base_trace_options = trace_options_for(trace_mode)
1065
+ trace_options = base_trace_options.merge(options)
1066
+ trace_class_for_mode = trace_class_for(trace_mode)
1067
+ trace_class_for_mode.new(**trace_options)
1015
1068
  end
1016
1069
 
1017
1070
  def query_analyzer(new_analyzer)
@@ -1052,6 +1105,7 @@ module GraphQL
1052
1105
  tracers: ctx[:tracers],
1053
1106
  trace: ctx[:trace],
1054
1107
  dataloader: ctx[:dataloader],
1108
+ trace_mode: ctx[:trace_mode],
1055
1109
  }
1056
1110
  else
1057
1111
  {}
@@ -55,20 +55,39 @@ module GraphQL
55
55
  RUBY
56
56
  end
57
57
 
58
- def platform_execute_field(platform_key, data)
59
- return super if !defined?(AppOpticsAPM) || gql_config[:enabled] == false
60
- layer = platform_key
61
- kvs = metadata(data, layer)
62
-
63
- ::AppOpticsAPM::SDK.trace(layer, kvs) do
64
- kvs.clear # we don't have to send them twice
65
- yield
58
+ def execute_field(query:, field:, ast_node:, arguments:, object:)
59
+ return_type = field.type.unwrap
60
+ trace_field = if return_type.kind.scalar? || return_type.kind.enum?
61
+ (field.trace.nil? && @trace_scalars) || field.trace
62
+ else
63
+ true
64
+ end
65
+ platform_key = if trace_field
66
+ @platform_key_cache[AppOpticsTrace].platform_field_key_cache[field]
67
+ else
68
+ nil
69
+ end
70
+ if platform_key && trace_field
71
+ return super if !defined?(AppOpticsAPM) || gql_config[:enabled] == false
72
+ layer = platform_key
73
+ kvs = metadata({query: query, field: field, ast_node: ast_node, arguments: arguments, object: object}, layer)
74
+
75
+ ::AppOpticsAPM::SDK.trace(layer, kvs) do
76
+ kvs.clear # we don't have to send them twice
77
+ super
78
+ end
79
+ else
80
+ super
66
81
  end
67
82
  end
68
83
 
84
+ def execute_field_lazy(query:, field:, ast_node:, arguments:, object:)
85
+ execute_field(query: query, field: field, ast_node: ast_node, arguments: arguments, object: object)
86
+ end
87
+
69
88
  def authorized(**data)
70
89
  return super if !defined?(AppOpticsAPM) || gql_config[:enabled] == false
71
- layer = @platform_authorized_key_cache[data[:type]]
90
+ layer = @platform_key_cache[AppOpticsTrace].platform_authorized_key_cache[data[:type]]
72
91
  kvs = metadata(data, layer)
73
92
 
74
93
  ::AppOpticsAPM::SDK.trace(layer, kvs) do
@@ -79,7 +98,7 @@ module GraphQL
79
98
 
80
99
  def authorized_lazy(**data)
81
100
  return super if !defined?(AppOpticsAPM) || gql_config[:enabled] == false
82
- layer = @platform_authorized_key_cache[data[:type]]
101
+ layer = @platform_key_cache[AppOpticsTrace].platform_authorized_key_cache[data[:type]]
83
102
  kvs = metadata(data, layer)
84
103
 
85
104
  ::AppOpticsAPM::SDK.trace(layer, kvs) do
@@ -90,7 +109,8 @@ module GraphQL
90
109
 
91
110
  def resolve_type(**data)
92
111
  return super if !defined?(AppOpticsAPM) || gql_config[:enabled] == false
93
- layer = @platform_resolve_type_key_cache[data[:type]]
112
+ layer = @platform_key_cache[AppOpticsTrace].platform_resolve_type_key_cache[data[:type]]
113
+
94
114
  kvs = metadata(data, layer)
95
115
 
96
116
  ::AppOpticsAPM::SDK.trace(layer, kvs) do
@@ -101,7 +121,7 @@ module GraphQL
101
121
 
102
122
  def resolve_type_lazy(**data)
103
123
  return super if !defined?(AppOpticsAPM) || gql_config[:enabled] == false
104
- layer = @platform_resolve_type_key_cache[data[:type]]
124
+ layer = @platform_key_cache[AppOpticsTrace].platform_resolve_type_key_cache[data[:type]]
105
125
  kvs = metadata(data, layer)
106
126
 
107
127
  ::AppOpticsAPM::SDK.trace(layer, kvs) do
@@ -18,6 +18,7 @@ module GraphQL
18
18
  @analytics_enabled = analytics_available && Datadog::Contrib::Analytics.enabled?(analytics_enabled)
19
19
  @analytics_sample_rate = analytics_sample_rate
20
20
  @service_name = service
21
+ @has_prepare_span = respond_to?(:prepare_span)
21
22
  super
22
23
  end
23
24
 
@@ -66,38 +67,60 @@ module GraphQL
66
67
  RUBY
67
68
  end
68
69
  }
69
- prepare_span("#{trace_method.sub("platform_", "")}", data, span)
70
+ if @has_prepare_span
71
+ prepare_span("#{trace_method.sub("platform_", "")}", data, span)
72
+ end
70
73
  super
71
74
  end
72
75
  end
73
76
  RUBY
74
77
  end
75
78
 
76
- def platform_execute_field(platform_key, data, span_key = "execute_field")
77
- @tracer.trace(platform_key, service: @service_name) do |span|
78
- span.span_type = 'custom'
79
- if defined?(Datadog::Tracing::Metadata::Ext) # Introduced in ddtrace 1.0
80
- span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT, 'graphql')
81
- span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION, span_key)
79
+ def execute_field(span_key = "execute_field", query:, field:, ast_node:, arguments:, object:)
80
+ return_type = field.type.unwrap
81
+ trace_field = if return_type.kind.scalar? || return_type.kind.enum?
82
+ (field.trace.nil? && @trace_scalars) || field.trace
83
+ else
84
+ true
85
+ end
86
+ platform_key = if trace_field
87
+ @platform_key_cache[DataDogTrace].platform_field_key_cache[field]
88
+ else
89
+ nil
90
+ end
91
+ if platform_key && trace_field
92
+ @tracer.trace(platform_key, service: @service_name) do |span|
93
+ span.span_type = 'custom'
94
+ if defined?(Datadog::Tracing::Metadata::Ext) # Introduced in ddtrace 1.0
95
+ span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT, 'graphql')
96
+ span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION, span_key)
97
+ end
98
+ if @has_prepare_span
99
+ prepare_span_data = { query: query, field: field, ast_node: ast_node, arguments: arguments, object: object }
100
+ prepare_span(span_key, prepare_span_data, span)
101
+ end
102
+ super(query: query, field: field, ast_node: ast_node, arguments: arguments, object: object)
82
103
  end
83
- prepare_span(span_key, data, span)
84
- yield
104
+ else
105
+ super(query: query, field: field, ast_node: ast_node, arguments: arguments, object: object)
85
106
  end
86
107
  end
87
108
 
88
- def platform_execute_field_lazy(platform_key, data, &block)
89
- platform_execute_field(platform_key, data, "execute_field_lazy", &block)
109
+ def execute_field_lazy(query:, field:, ast_node:, arguments:, object:)
110
+ execute_field("execute_field_lazy", query: query, field: field, ast_node: ast_node, arguments: arguments, object: object)
90
111
  end
91
112
 
92
113
  def authorized(object:, type:, query:, span_key: "authorized")
93
- platform_key = @platform_authorized_key_cache[type]
114
+ platform_key = @platform_key_cache[DataDogTrace].platform_authorized_key_cache[type]
94
115
  @tracer.trace(platform_key, service: @service_name) do |span|
95
116
  span.span_type = 'custom'
96
117
  if defined?(Datadog::Tracing::Metadata::Ext) # Introduced in ddtrace 1.0
97
118
  span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT, 'graphql')
98
119
  span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION, span_key)
99
120
  end
100
- prepare_span(span_key, {object: object, type: type, query: query}, span)
121
+ if @has_prepare_span
122
+ prepare_span(span_key, {object: object, type: type, query: query}, span)
123
+ end
101
124
  super(query: query, type: type, object: object)
102
125
  end
103
126
  end
@@ -107,14 +130,16 @@ module GraphQL
107
130
  end
108
131
 
109
132
  def resolve_type(object:, type:, query:, span_key: "resolve_type")
110
- platform_key = @platform_resolve_type_key_cache[type]
133
+ platform_key = @platform_key_cache[DataDogTrace].platform_resolve_type_key_cache[type]
111
134
  @tracer.trace(platform_key, service: @service_name) do |span|
112
135
  span.span_type = 'custom'
113
136
  if defined?(Datadog::Tracing::Metadata::Ext) # Introduced in ddtrace 1.0
114
137
  span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT, 'graphql')
115
138
  span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION, span_key)
116
139
  end
117
- prepare_span(span_key, {object: object, type: type, query: query}, span)
140
+ if @has_prepare_span
141
+ prepare_span(span_key, {object: object, type: type, query: query}, span)
142
+ end
118
143
  super(query: query, type: type, object: object)
119
144
  end
120
145
  end
@@ -129,8 +154,8 @@ module GraphQL
129
154
  # @param key [String] The event being traced
130
155
  # @param data [Hash] The runtime data for this event (@see GraphQL::Tracing for keys for each event)
131
156
  # @param span [Datadog::Tracing::SpanOperation] The datadog span for this event
132
- def prepare_span(key, data, span)
133
- end
157
+ # def prepare_span(key, data, span)
158
+ # end
134
159
 
135
160
  def platform_field_key(field)
136
161
  field.path
@@ -5,12 +5,22 @@ module GraphQL
5
5
  module PlatformTrace
6
6
  def initialize(trace_scalars: false, **_options)
7
7
  @trace_scalars = trace_scalars
8
- @platform_field_key_cache = Hash.new { |h, k| h[k] = platform_field_key(k) }
9
- @platform_authorized_key_cache = Hash.new { |h, k| h[k] = platform_authorized_key(k) }
10
- @platform_resolve_type_key_cache = Hash.new { |h, k| h[k] = platform_resolve_type_key(k) }
8
+
9
+ @platform_key_cache = Hash.new { |h, mod| h[mod] = mod::KeyCache.new }
11
10
  super
12
11
  end
13
12
 
13
+ module BaseKeyCache
14
+ def initialize
15
+ @platform_field_key_cache = Hash.new { |h, k| h[k] = platform_field_key(k) }
16
+ @platform_authorized_key_cache = Hash.new { |h, k| h[k] = platform_authorized_key(k) }
17
+ @platform_resolve_type_key_cache = Hash.new { |h, k| h[k] = platform_resolve_type_key(k) }
18
+ end
19
+
20
+ attr_reader :platform_field_key_cache, :platform_authorized_key_cache, :platform_resolve_type_key_cache
21
+ end
22
+
23
+
14
24
  def platform_execute_field_lazy(*args, &block)
15
25
  platform_execute_field(*args, &block)
16
26
  end
@@ -24,10 +34,11 @@ module GraphQL
24
34
  end
25
35
 
26
36
  def self.included(child_class)
27
- # Don't gather this unless necessary
28
- pass_data_to_execute_field = child_class.method_defined?(:platform_execute_field) &&
29
- child_class.instance_method(:platform_execute_field).arity != 1
30
-
37
+ key_methods_class = Class.new {
38
+ include(child_class)
39
+ include(BaseKeyCache)
40
+ }
41
+ child_class.const_set(:KeyCache, key_methods_class)
31
42
  [:execute_field, :execute_field_lazy].each do |field_trace_method|
32
43
  if !child_class.method_defined?(field_trace_method)
33
44
  child_class.module_eval <<-RUBY, __FILE__, __LINE__
@@ -39,12 +50,12 @@ module GraphQL
39
50
  true
40
51
  end
41
52
  platform_key = if trace_field
42
- @platform_field_key_cache[field]
53
+ @platform_key_cache[#{child_class}].platform_field_key_cache[field]
43
54
  else
44
55
  nil
45
56
  end
46
57
  if platform_key && trace_field
47
- platform_#{field_trace_method}(platform_key#{pass_data_to_execute_field ? ", { query: query, field: field, ast_node: ast_node, arguments: arguments, object: object }" : ""}) do
58
+ platform_#{field_trace_method}(platform_key) do
48
59
  super
49
60
  end
50
61
  else
@@ -60,7 +71,7 @@ module GraphQL
60
71
  if !child_class.method_defined?(auth_trace_method)
61
72
  child_class.module_eval <<-RUBY, __FILE__, __LINE__
62
73
  def #{auth_trace_method}(type:, query:, object:)
63
- platform_key = @platform_authorized_key_cache[type]
74
+ platform_key = @platform_key_cache[#{child_class}].platform_authorized_key_cache[type]
64
75
  platform_#{auth_trace_method}(platform_key) do
65
76
  super
66
77
  end
@@ -73,7 +84,7 @@ module GraphQL
73
84
  if !child_class.method_defined?(rt_trace_method)
74
85
  child_class.module_eval <<-RUBY, __FILE__, __LINE__
75
86
  def #{rt_trace_method}(query:, type:, object:)
76
- platform_key = @platform_resolve_type_key_cache[type]
87
+ platform_key = @platform_key_cache[#{child_class}].platform_resolve_type_key_cache[type]
77
88
  platform_#{rt_trace_method}(platform_key) do
78
89
  super
79
90
  end
@@ -83,8 +94,6 @@ module GraphQL
83
94
  end
84
95
  end
85
96
 
86
-
87
-
88
97
  private
89
98
 
90
99
  # Get the transaction name based on the operation type and name if possible, or fall back to a user provided
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "2.0.24"
3
+ VERSION = "2.0.25"
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.24
4
+ version: 2.0.25
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-27 00:00:00.000000000 Z
11
+ date: 2023-08-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: benchmark-ips
@@ -623,7 +623,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
623
623
  - !ruby/object:Gem::Version
624
624
  version: '0'
625
625
  requirements: []
626
- rubygems_version: 3.2.33
626
+ rubygems_version: 3.4.10
627
627
  signing_key:
628
628
  specification_version: 4
629
629
  summary: A GraphQL language and runtime for Ruby