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 +4 -4
- data/lib/generators/graphql/mutation_delete_generator.rb +1 -1
- data/lib/generators/graphql/mutation_update_generator.rb +1 -1
- data/lib/graphql/dataloader/source.rb +68 -43
- data/lib/graphql/dataloader.rb +4 -4
- data/lib/graphql/schema.rb +69 -15
- data/lib/graphql/tracing/appoptics_trace.rb +32 -12
- data/lib/graphql/tracing/data_dog_trace.rb +42 -17
- data/lib/graphql/tracing/platform_trace.rb +22 -13
- data/lib/graphql/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 289b06689b36a3673c053d13d2ce0835a089e92db60e3e24e8af791fdd934d81
|
4
|
+
data.tar.gz: 3c5257c0732d0729b97ac92376427ccba26ef66397f9b9d07c18e9792ea03251
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
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
|
-
@
|
10
|
+
@pending = {}
|
11
11
|
# These keys have been passed to `fetch` but haven't been finished yet
|
12
|
-
@
|
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(
|
22
|
-
|
23
|
-
|
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,
|
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(
|
30
|
-
|
31
|
-
|
32
|
-
|
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
|
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(
|
38
|
-
|
39
|
-
|
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
|
-
@
|
42
|
-
sync([
|
43
|
-
result_for(
|
56
|
+
@pending[result_key] ||= value
|
57
|
+
sync([result_key])
|
58
|
+
result_for(result_key)
|
44
59
|
end
|
45
60
|
end
|
46
61
|
|
47
|
-
# @param
|
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(
|
50
|
-
|
51
|
-
|
52
|
-
|
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
|
-
|
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(
|
94
|
+
def sync(pending_result_keys)
|
71
95
|
@dataloader.yield
|
72
96
|
iterations = 0
|
73
|
-
while
|
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 (#{
|
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
|
-
!@
|
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
|
114
|
+
# @param new_results [Hash<Object => Object>] key-value pairs to cache in this source
|
91
115
|
# @return [void]
|
92
|
-
def merge(
|
93
|
-
|
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 !@
|
102
|
-
@
|
128
|
+
if !@fetching.empty?
|
129
|
+
@fetching.each_key { |k| @pending.delete(k) }
|
103
130
|
end
|
104
|
-
return if @
|
105
|
-
|
106
|
-
@
|
107
|
-
@
|
108
|
-
results = fetch(
|
109
|
-
|
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
|
-
|
141
|
+
fetch_h.each_key { |key| @results[key] = error }
|
115
142
|
ensure
|
116
|
-
|
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 :
|
164
|
+
attr_reader :pending
|
140
165
|
|
141
166
|
private
|
142
167
|
|
data/lib/graphql/dataloader.rb
CHANGED
@@ -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.
|
115
|
-
batched_source_instance.
|
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,
|
131
|
-
source_instance.
|
130
|
+
prev_pending_keys.each do |source_instance, pending|
|
131
|
+
source_instance.pending.merge!(pending)
|
132
132
|
end
|
133
133
|
end
|
134
134
|
|
data/lib/graphql/schema.rb
CHANGED
@@ -158,16 +158,24 @@ module GraphQL
|
|
158
158
|
def trace_class_for(mode)
|
159
159
|
@trace_modes ||= {}
|
160
160
|
@trace_modes[mode] ||= begin
|
161
|
-
|
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
|
-
|
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
|
-
|
999
|
-
|
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
|
-
|
1003
|
-
|
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
|
-
|
1007
|
-
|
1008
|
-
|
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
|
-
|
1014
|
-
|
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
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
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
|
-
|
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
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
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
|
-
|
84
|
-
|
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
|
89
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
9
|
-
@
|
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
|
-
|
28
|
-
|
29
|
-
|
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
|
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
|
data/lib/graphql/version.rb
CHANGED
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.
|
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-
|
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.
|
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
|