graphql 2.0.24 → 2.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of graphql might be problematic. Click here for more details.

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