graphql 1.10.1 → 1.13.0
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/core.rb +18 -2
- data/lib/generators/graphql/install_generator.rb +36 -6
- data/lib/generators/graphql/loader_generator.rb +1 -0
- data/lib/generators/graphql/mutation_generator.rb +2 -1
- data/lib/generators/graphql/object_generator.rb +54 -9
- data/lib/generators/graphql/relay.rb +63 -0
- data/lib/generators/graphql/relay_generator.rb +21 -0
- data/lib/generators/graphql/templates/base_argument.erb +2 -0
- data/lib/generators/graphql/templates/base_connection.erb +8 -0
- data/lib/generators/graphql/templates/base_edge.erb +8 -0
- data/lib/generators/graphql/templates/base_enum.erb +2 -0
- data/lib/generators/graphql/templates/base_field.erb +2 -0
- data/lib/generators/graphql/templates/base_input_object.erb +2 -0
- data/lib/generators/graphql/templates/base_interface.erb +2 -0
- data/lib/generators/graphql/templates/base_mutation.erb +2 -0
- data/lib/generators/graphql/templates/base_object.erb +2 -0
- data/lib/generators/graphql/templates/base_scalar.erb +2 -0
- data/lib/generators/graphql/templates/base_union.erb +2 -0
- data/lib/generators/graphql/templates/enum.erb +2 -0
- data/lib/generators/graphql/templates/graphql_controller.erb +16 -12
- data/lib/generators/graphql/templates/interface.erb +2 -0
- data/lib/generators/graphql/templates/loader.erb +2 -0
- data/lib/generators/graphql/templates/mutation.erb +2 -0
- data/lib/generators/graphql/templates/mutation_type.erb +2 -0
- data/lib/generators/graphql/templates/node_type.erb +9 -0
- data/lib/generators/graphql/templates/object.erb +3 -1
- data/lib/generators/graphql/templates/query_type.erb +3 -3
- data/lib/generators/graphql/templates/scalar.erb +2 -0
- data/lib/generators/graphql/templates/schema.erb +21 -33
- data/lib/generators/graphql/templates/union.erb +3 -1
- data/lib/generators/graphql/type_generator.rb +1 -1
- data/lib/graphql/analysis/analyze_query.rb +7 -0
- data/lib/graphql/analysis/ast/field_usage.rb +24 -1
- data/lib/graphql/analysis/ast/query_complexity.rb +126 -109
- data/lib/graphql/analysis/ast/visitor.rb +13 -5
- data/lib/graphql/analysis/ast.rb +11 -2
- data/lib/graphql/argument.rb +3 -3
- data/lib/graphql/backtrace/inspect_result.rb +0 -1
- data/lib/graphql/backtrace/legacy_tracer.rb +56 -0
- data/lib/graphql/backtrace/table.rb +34 -3
- data/lib/graphql/backtrace/traced_error.rb +0 -1
- data/lib/graphql/backtrace/tracer.rb +40 -9
- data/lib/graphql/backtrace.rb +28 -19
- data/lib/graphql/backwards_compatibility.rb +2 -1
- data/lib/graphql/base_type.rb +1 -1
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +2 -2
- data/lib/graphql/compatibility/execution_specification.rb +1 -0
- data/lib/graphql/compatibility/lazy_execution_specification.rb +2 -0
- data/lib/graphql/compatibility/query_parser_specification.rb +2 -0
- data/lib/graphql/compatibility/schema_parser_specification.rb +2 -0
- data/lib/graphql/dataloader/null_dataloader.rb +22 -0
- data/lib/graphql/dataloader/request.rb +19 -0
- data/lib/graphql/dataloader/request_all.rb +19 -0
- data/lib/graphql/dataloader/source.rb +155 -0
- data/lib/graphql/dataloader.rb +308 -0
- data/lib/graphql/define/assign_global_id_field.rb +2 -2
- data/lib/graphql/define/defined_object_proxy.rb +1 -1
- data/lib/graphql/define/instance_definable.rb +34 -4
- data/lib/graphql/define/type_definer.rb +5 -5
- data/lib/graphql/deprecated_dsl.rb +18 -5
- data/lib/graphql/deprecation.rb +9 -0
- data/lib/graphql/directive.rb +4 -4
- data/lib/graphql/enum_type.rb +7 -1
- data/lib/graphql/execution/errors.rb +110 -7
- data/lib/graphql/execution/execute.rb +8 -1
- data/lib/graphql/execution/instrumentation.rb +1 -1
- data/lib/graphql/execution/interpreter/argument_value.rb +28 -0
- data/lib/graphql/execution/interpreter/arguments.rb +88 -0
- data/lib/graphql/execution/interpreter/arguments_cache.rb +103 -0
- data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
- data/lib/graphql/execution/interpreter/resolve.rb +37 -25
- data/lib/graphql/execution/interpreter/runtime.rb +685 -421
- data/lib/graphql/execution/interpreter.rb +42 -13
- data/lib/graphql/execution/lazy.rb +5 -1
- data/lib/graphql/execution/lookahead.rb +25 -110
- data/lib/graphql/execution/multiplex.rb +37 -25
- data/lib/graphql/field.rb +5 -1
- data/lib/graphql/function.rb +4 -0
- data/lib/graphql/input_object_type.rb +6 -0
- data/lib/graphql/integer_decoding_error.rb +17 -0
- data/lib/graphql/integer_encoding_error.rb +18 -2
- data/lib/graphql/interface_type.rb +7 -0
- data/lib/graphql/internal_representation/document.rb +2 -2
- data/lib/graphql/internal_representation/rewrite.rb +1 -1
- data/lib/graphql/internal_representation/scope.rb +2 -2
- data/lib/graphql/internal_representation/visit.rb +2 -2
- data/lib/graphql/introspection/directive_type.rb +8 -4
- data/lib/graphql/introspection/entry_points.rb +2 -2
- data/lib/graphql/introspection/enum_value_type.rb +2 -2
- data/lib/graphql/introspection/field_type.rb +9 -5
- data/lib/graphql/introspection/input_value_type.rb +15 -3
- data/lib/graphql/introspection/introspection_query.rb +6 -92
- data/lib/graphql/introspection/schema_type.rb +4 -4
- data/lib/graphql/introspection/type_type.rb +16 -12
- data/lib/graphql/introspection.rb +96 -0
- data/lib/graphql/invalid_null_error.rb +18 -0
- data/lib/graphql/language/block_string.rb +20 -5
- data/lib/graphql/language/cache.rb +37 -0
- data/lib/graphql/language/document_from_schema_definition.rb +73 -25
- data/lib/graphql/language/lexer.rb +4 -3
- data/lib/graphql/language/lexer.rl +3 -3
- data/lib/graphql/language/nodes.rb +51 -89
- data/lib/graphql/language/parser.rb +552 -530
- data/lib/graphql/language/parser.y +114 -99
- data/lib/graphql/language/printer.rb +7 -2
- data/lib/graphql/language/sanitized_printer.rb +222 -0
- data/lib/graphql/language/token.rb +0 -4
- data/lib/graphql/language/visitor.rb +2 -2
- data/lib/graphql/language.rb +2 -0
- data/lib/graphql/name_validator.rb +2 -7
- data/lib/graphql/object_type.rb +44 -35
- data/lib/graphql/pagination/active_record_relation_connection.rb +14 -1
- data/lib/graphql/pagination/array_connection.rb +2 -2
- data/lib/graphql/pagination/connection.rb +75 -20
- data/lib/graphql/pagination/connections.rb +83 -31
- data/lib/graphql/pagination/relation_connection.rb +34 -14
- data/lib/graphql/parse_error.rb +0 -1
- data/lib/graphql/query/arguments.rb +4 -3
- data/lib/graphql/query/arguments_cache.rb +1 -2
- data/lib/graphql/query/context.rb +42 -7
- data/lib/graphql/query/executor.rb +0 -1
- data/lib/graphql/query/fingerprint.rb +26 -0
- data/lib/graphql/query/input_validation_result.rb +23 -6
- data/lib/graphql/query/literal_input.rb +1 -1
- data/lib/graphql/query/null_context.rb +24 -8
- data/lib/graphql/query/serial_execution/field_resolution.rb +1 -1
- data/lib/graphql/query/serial_execution.rb +1 -0
- data/lib/graphql/query/validation_pipeline.rb +5 -2
- data/lib/graphql/query/variable_validation_error.rb +1 -1
- data/lib/graphql/query/variables.rb +14 -4
- data/lib/graphql/query.rb +68 -13
- data/lib/graphql/railtie.rb +9 -1
- data/lib/graphql/rake_task.rb +12 -9
- data/lib/graphql/relay/array_connection.rb +10 -12
- data/lib/graphql/relay/base_connection.rb +26 -13
- data/lib/graphql/relay/connection_instrumentation.rb +4 -4
- data/lib/graphql/relay/connection_type.rb +1 -1
- data/lib/graphql/relay/edges_instrumentation.rb +0 -1
- data/lib/graphql/relay/mutation.rb +1 -0
- data/lib/graphql/relay/node.rb +3 -0
- data/lib/graphql/relay/range_add.rb +23 -9
- data/lib/graphql/relay/relation_connection.rb +8 -10
- data/lib/graphql/relay/type_extensions.rb +2 -0
- data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
- data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
- data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
- data/lib/graphql/rubocop.rb +4 -0
- data/lib/graphql/scalar_type.rb +16 -1
- data/lib/graphql/schema/addition.rb +247 -0
- data/lib/graphql/schema/argument.rb +210 -12
- data/lib/graphql/schema/base_64_encoder.rb +2 -0
- data/lib/graphql/schema/build_from_definition/resolve_map.rb +3 -1
- data/lib/graphql/schema/build_from_definition.rb +213 -86
- data/lib/graphql/schema/default_type_error.rb +2 -0
- data/lib/graphql/schema/directive/deprecated.rb +1 -1
- data/lib/graphql/schema/directive/feature.rb +1 -1
- data/lib/graphql/schema/directive/flagged.rb +57 -0
- data/lib/graphql/schema/directive/include.rb +1 -1
- data/lib/graphql/schema/directive/skip.rb +1 -1
- data/lib/graphql/schema/directive/transform.rb +14 -2
- data/lib/graphql/schema/directive.rb +78 -2
- data/lib/graphql/schema/enum.rb +80 -9
- data/lib/graphql/schema/enum_value.rb +17 -6
- data/lib/graphql/schema/field/connection_extension.rb +46 -30
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +285 -133
- data/lib/graphql/schema/find_inherited_value.rb +4 -1
- data/lib/graphql/schema/finder.rb +5 -5
- data/lib/graphql/schema/input_object.rb +97 -89
- data/lib/graphql/schema/interface.rb +24 -19
- data/lib/graphql/schema/late_bound_type.rb +2 -2
- data/lib/graphql/schema/list.rb +7 -1
- data/lib/graphql/schema/loader.rb +137 -103
- data/lib/graphql/schema/member/accepts_definition.rb +8 -1
- data/lib/graphql/schema/member/base_dsl_methods.rb +15 -19
- data/lib/graphql/schema/member/build_type.rb +14 -7
- data/lib/graphql/schema/member/has_arguments.rb +205 -12
- data/lib/graphql/schema/member/has_ast_node.rb +4 -1
- data/lib/graphql/schema/member/has_deprecation_reason.rb +25 -0
- data/lib/graphql/schema/member/has_directives.rb +98 -0
- data/lib/graphql/schema/member/has_fields.rb +95 -30
- data/lib/graphql/schema/member/has_interfaces.rb +90 -0
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
- data/lib/graphql/schema/member/has_validators.rb +31 -0
- data/lib/graphql/schema/member/instrumentation.rb +0 -1
- data/lib/graphql/schema/member/type_system_helpers.rb +3 -3
- data/lib/graphql/schema/member.rb +6 -0
- data/lib/graphql/schema/middleware_chain.rb +1 -1
- data/lib/graphql/schema/mutation.rb +4 -0
- data/lib/graphql/schema/non_null.rb +5 -0
- data/lib/graphql/schema/object.rb +47 -46
- data/lib/graphql/schema/possible_types.rb +9 -4
- data/lib/graphql/schema/printer.rb +16 -34
- data/lib/graphql/schema/relay_classic_mutation.rb +32 -4
- data/lib/graphql/schema/resolver/has_payload_type.rb +34 -4
- data/lib/graphql/schema/resolver.rb +123 -63
- data/lib/graphql/schema/scalar.rb +11 -1
- data/lib/graphql/schema/subscription.rb +57 -21
- data/lib/graphql/schema/timeout.rb +29 -15
- data/lib/graphql/schema/timeout_middleware.rb +3 -1
- data/lib/graphql/schema/type_expression.rb +1 -1
- data/lib/graphql/schema/type_membership.rb +18 -4
- data/lib/graphql/schema/union.rb +41 -1
- data/lib/graphql/schema/unique_within_type.rb +1 -2
- data/lib/graphql/schema/validation.rb +12 -2
- data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
- data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
- data/lib/graphql/schema/validator/exclusion_validator.rb +33 -0
- data/lib/graphql/schema/validator/format_validator.rb +48 -0
- data/lib/graphql/schema/validator/inclusion_validator.rb +35 -0
- data/lib/graphql/schema/validator/length_validator.rb +59 -0
- data/lib/graphql/schema/validator/numericality_validator.rb +82 -0
- data/lib/graphql/schema/validator/required_validator.rb +68 -0
- data/lib/graphql/schema/validator.rb +174 -0
- data/lib/graphql/schema/warden.rb +153 -28
- data/lib/graphql/schema.rb +364 -330
- data/lib/graphql/static_validation/all_rules.rb +1 -0
- data/lib/graphql/static_validation/base_visitor.rb +8 -5
- data/lib/graphql/static_validation/definition_dependencies.rb +0 -1
- data/lib/graphql/static_validation/error.rb +3 -1
- data/lib/graphql/static_validation/literal_validator.rb +51 -26
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +44 -87
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +22 -6
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +28 -22
- data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +4 -2
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +79 -43
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
- data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
- data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +1 -1
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +6 -7
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +9 -10
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +8 -8
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +4 -2
- data/lib/graphql/static_validation/validation_context.rb +9 -3
- data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
- data/lib/graphql/static_validation/validator.rb +42 -8
- data/lib/graphql/static_validation.rb +1 -0
- data/lib/graphql/string_encoding_error.rb +13 -3
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +118 -19
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +21 -0
- data/lib/graphql/subscriptions/event.rb +81 -30
- data/lib/graphql/subscriptions/instrumentation.rb +0 -1
- data/lib/graphql/subscriptions/serialize.rb +33 -6
- data/lib/graphql/subscriptions/subscription_root.rb +15 -4
- data/lib/graphql/subscriptions.rb +88 -45
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +2 -1
- data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
- data/lib/graphql/tracing/appsignal_tracing.rb +15 -0
- data/lib/graphql/tracing/new_relic_tracing.rb +1 -12
- data/lib/graphql/tracing/platform_tracing.rb +43 -17
- data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +4 -1
- data/lib/graphql/tracing/scout_tracing.rb +11 -0
- data/lib/graphql/tracing/skylight_tracing.rb +1 -1
- data/lib/graphql/tracing/statsd_tracing.rb +42 -0
- data/lib/graphql/tracing.rb +9 -33
- data/lib/graphql/types/big_int.rb +5 -1
- data/lib/graphql/types/int.rb +10 -3
- data/lib/graphql/types/iso_8601_date.rb +3 -3
- data/lib/graphql/types/iso_8601_date_time.rb +25 -10
- data/lib/graphql/types/relay/base_connection.rb +6 -90
- data/lib/graphql/types/relay/base_edge.rb +2 -34
- data/lib/graphql/types/relay/connection_behaviors.rb +156 -0
- data/lib/graphql/types/relay/default_relay.rb +27 -0
- data/lib/graphql/types/relay/edge_behaviors.rb +53 -0
- data/lib/graphql/types/relay/has_node_field.rb +41 -0
- data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
- data/lib/graphql/types/relay/node.rb +2 -4
- data/lib/graphql/types/relay/node_behaviors.rb +15 -0
- data/lib/graphql/types/relay/node_field.rb +2 -20
- data/lib/graphql/types/relay/nodes_field.rb +2 -20
- data/lib/graphql/types/relay/page_info.rb +2 -14
- data/lib/graphql/types/relay/page_info_behaviors.rb +25 -0
- data/lib/graphql/types/relay.rb +11 -3
- data/lib/graphql/types/string.rb +8 -2
- data/lib/graphql/unauthorized_error.rb +2 -2
- data/lib/graphql/union_type.rb +2 -0
- data/lib/graphql/upgrader/member.rb +1 -0
- data/lib/graphql/upgrader/schema.rb +1 -0
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +65 -31
- data/readme.md +3 -6
- metadata +77 -112
- data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
- data/lib/graphql/literal_validation_error.rb +0 -6
- data/lib/graphql/types/relay/base_field.rb +0 -22
- data/lib/graphql/types/relay/base_interface.rb +0 -29
- data/lib/graphql/types/relay/base_object.rb +0 -26
@@ -1,12 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require "securerandom"
|
3
|
+
require "graphql/subscriptions/broadcast_analyzer"
|
3
4
|
require "graphql/subscriptions/event"
|
4
5
|
require "graphql/subscriptions/instrumentation"
|
5
6
|
require "graphql/subscriptions/serialize"
|
6
|
-
|
7
|
-
require "graphql/subscriptions/action_cable_subscriptions"
|
8
|
-
end
|
7
|
+
require "graphql/subscriptions/action_cable_subscriptions"
|
9
8
|
require "graphql/subscriptions/subscription_root"
|
9
|
+
require "graphql/subscriptions/default_subscription_resolve_extension"
|
10
10
|
|
11
11
|
module GraphQL
|
12
12
|
class Subscriptions
|
@@ -16,6 +16,13 @@ module GraphQL
|
|
16
16
|
class InvalidTriggerError < GraphQL::Error
|
17
17
|
end
|
18
18
|
|
19
|
+
# Raised when either:
|
20
|
+
# - An initial subscription didn't have a value for `context[subscription_scope]`
|
21
|
+
# - Or, an update didn't pass `.trigger(..., scope:)`
|
22
|
+
# When raised, the initial subscription or update fails completely.
|
23
|
+
class SubscriptionScopeMissingError < GraphQL::Error
|
24
|
+
end
|
25
|
+
|
19
26
|
# @see {Subscriptions#initialize} for options, concrete implementations may add options.
|
20
27
|
def self.use(defn, options = {})
|
21
28
|
schema = defn.is_a?(Class) ? defn : defn.target
|
@@ -26,17 +33,30 @@ module GraphQL
|
|
26
33
|
|
27
34
|
instrumentation = Subscriptions::Instrumentation.new(schema: schema)
|
28
35
|
defn.instrument(:query, instrumentation)
|
29
|
-
|
36
|
+
if !schema.is_a?(Class)
|
37
|
+
defn.instrument(:field, instrumentation)
|
38
|
+
end
|
30
39
|
options[:schema] = schema
|
31
40
|
schema.subscriptions = self.new(**options)
|
41
|
+
schema.add_subscription_extension_if_necessary
|
32
42
|
nil
|
33
43
|
end
|
34
44
|
|
35
45
|
# @param schema [Class] the GraphQL schema this manager belongs to
|
36
|
-
def initialize(schema:, **rest)
|
46
|
+
def initialize(schema:, broadcast: false, default_broadcastable: false, **rest)
|
47
|
+
if broadcast
|
48
|
+
if !schema.using_ast_analysis?
|
49
|
+
raise ArgumentError, "`broadcast: true` requires AST analysis, add `using GraphQL::Analysis::AST` to your schema or see https://graphql-ruby.org/queries/ast_analysis.html."
|
50
|
+
end
|
51
|
+
schema.query_analyzer(Subscriptions::BroadcastAnalyzer)
|
52
|
+
end
|
53
|
+
@default_broadcastable = default_broadcastable
|
37
54
|
@schema = schema
|
38
55
|
end
|
39
56
|
|
57
|
+
# @return [Boolean] Used when fields don't have `broadcastable:` explicitly set
|
58
|
+
attr_reader :default_broadcastable
|
59
|
+
|
40
60
|
# Fetch subscriptions matching this field + arguments pair
|
41
61
|
# And pass them off to the queue.
|
42
62
|
# @param event_name [String]
|
@@ -63,7 +83,8 @@ module GraphQL
|
|
63
83
|
end
|
64
84
|
|
65
85
|
# Normalize symbol-keyed args to strings, try camelizing them
|
66
|
-
|
86
|
+
# Should this accept a real context somehow?
|
87
|
+
normalized_args = normalize_arguments(normalized_event_name, field, args, GraphQL::Query::NullContext)
|
67
88
|
|
68
89
|
event = Subscriptions::Event.new(
|
69
90
|
name: normalized_event_name,
|
@@ -77,40 +98,59 @@ module GraphQL
|
|
77
98
|
# `event` was triggered on `object`, and `subscription_id` was subscribed,
|
78
99
|
# so it should be updated.
|
79
100
|
#
|
80
|
-
# Load `subscription_id`'s GraphQL data, re-evaluate the query
|
81
|
-
#
|
82
|
-
# This is where a queue may be inserted to push updates in the background.
|
101
|
+
# Load `subscription_id`'s GraphQL data, re-evaluate the query and return the result.
|
83
102
|
#
|
84
103
|
# @param subscription_id [String]
|
85
104
|
# @param event [GraphQL::Subscriptions::Event] The event which was triggered
|
86
105
|
# @param object [Object] The value for the subscription field
|
87
|
-
# @return [
|
88
|
-
def
|
106
|
+
# @return [GraphQL::Query::Result]
|
107
|
+
def execute_update(subscription_id, event, object)
|
89
108
|
# Lookup the saved data for this subscription
|
90
109
|
query_data = read_subscription(subscription_id)
|
110
|
+
if query_data.nil?
|
111
|
+
delete_subscription(subscription_id)
|
112
|
+
return nil
|
113
|
+
end
|
114
|
+
|
91
115
|
# Fetch the required keys from the saved data
|
92
116
|
query_string = query_data.fetch(:query_string)
|
93
117
|
variables = query_data.fetch(:variables)
|
94
118
|
context = query_data.fetch(:context)
|
95
119
|
operation_name = query_data.fetch(:operation_name)
|
96
|
-
# Re-evaluate the saved query
|
97
120
|
result = @schema.execute(
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
root_value: object,
|
105
|
-
}
|
121
|
+
query: query_string,
|
122
|
+
context: context,
|
123
|
+
subscription_topic: event.topic,
|
124
|
+
operation_name: operation_name,
|
125
|
+
variables: variables,
|
126
|
+
root_value: object,
|
106
127
|
)
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
128
|
+
subscriptions_context = result.context.namespace(:subscriptions)
|
129
|
+
if subscriptions_context[:no_update]
|
130
|
+
result = nil
|
131
|
+
end
|
132
|
+
|
133
|
+
unsubscribed = subscriptions_context[:unsubscribed]
|
134
|
+
|
135
|
+
if unsubscribed
|
136
|
+
# `unsubscribe` was called, clean up on our side
|
137
|
+
# TODO also send `{more: false}` to client?
|
138
|
+
delete_subscription(subscription_id)
|
139
|
+
result = nil
|
140
|
+
end
|
141
|
+
|
142
|
+
result
|
143
|
+
end
|
144
|
+
|
145
|
+
# Run the update query for this subscription and deliver it
|
146
|
+
# @see {#execute_update}
|
147
|
+
# @see {#deliver}
|
148
|
+
# @return [void]
|
149
|
+
def execute(subscription_id, event, object)
|
150
|
+
res = execute_update(subscription_id, event, object)
|
151
|
+
if !res.nil?
|
152
|
+
deliver(subscription_id, res)
|
153
|
+
end
|
114
154
|
end
|
115
155
|
|
116
156
|
# Event `event` occurred on `object`,
|
@@ -119,16 +159,6 @@ module GraphQL
|
|
119
159
|
# @param object [Object]
|
120
160
|
# @return [void]
|
121
161
|
def execute_all(event, object)
|
122
|
-
each_subscription_id(event) do |subscription_id|
|
123
|
-
execute(subscription_id, event, object)
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
# Get each `subscription_id` subscribed to `event.topic` and yield them
|
128
|
-
# @param event [GraphQL::Subscriptions::Event]
|
129
|
-
# @yieldparam subscription_id [String]
|
130
|
-
# @return [void]
|
131
|
-
def each_subscription_id(event)
|
132
162
|
raise GraphQL::RequiredImplementationMissingError
|
133
163
|
end
|
134
164
|
|
@@ -183,6 +213,16 @@ module GraphQL
|
|
183
213
|
Schema::Member::BuildType.camelize(event_or_arg_name.to_s)
|
184
214
|
end
|
185
215
|
|
216
|
+
# @return [Boolean] if true, then a query like this one would be broadcasted
|
217
|
+
def broadcastable?(query_str, **query_options)
|
218
|
+
query = GraphQL::Query.new(@schema, query_str, **query_options)
|
219
|
+
if !query.valid?
|
220
|
+
raise "Invalid query: #{query.validation_errors.map(&:to_h).inspect}"
|
221
|
+
end
|
222
|
+
GraphQL::Analysis::AST.analyze_query(query, @schema.query_analyzers)
|
223
|
+
query.context.namespace(:subscriptions)[:subscription_broadcastable]
|
224
|
+
end
|
225
|
+
|
186
226
|
private
|
187
227
|
|
188
228
|
# Recursively normalize `args` as belonging to `arg_owner`:
|
@@ -191,7 +231,7 @@ module GraphQL
|
|
191
231
|
# @param arg_owner [GraphQL::Field, GraphQL::BaseType]
|
192
232
|
# @param args [Hash, Array, Any] some GraphQL input value to coerce as `arg_owner`
|
193
233
|
# @return [Any] normalized arguments value
|
194
|
-
def normalize_arguments(event_name, arg_owner, args)
|
234
|
+
def normalize_arguments(event_name, arg_owner, args, context)
|
195
235
|
case arg_owner
|
196
236
|
when GraphQL::Field, GraphQL::InputObjectType, GraphQL::Schema::Field, Class
|
197
237
|
if arg_owner.is_a?(Class) && !arg_owner.kind.input_object?
|
@@ -202,19 +242,19 @@ module GraphQL
|
|
202
242
|
missing_arg_names = []
|
203
243
|
args.each do |k, v|
|
204
244
|
arg_name = k.to_s
|
205
|
-
arg_defn = arg_owner.
|
245
|
+
arg_defn = arg_owner.get_argument(arg_name, context)
|
206
246
|
if arg_defn
|
207
247
|
normalized_arg_name = arg_name
|
208
248
|
else
|
209
249
|
normalized_arg_name = normalize_name(arg_name)
|
210
|
-
arg_defn = arg_owner.
|
250
|
+
arg_defn = arg_owner.get_argument(normalized_arg_name, context)
|
211
251
|
end
|
212
252
|
|
213
253
|
if arg_defn
|
214
254
|
if arg_defn.loads
|
215
255
|
normalized_arg_name = arg_defn.keyword.to_s
|
216
256
|
end
|
217
|
-
normalized = normalize_arguments(event_name, arg_defn.type, v)
|
257
|
+
normalized = normalize_arguments(event_name, arg_defn.type, v, context)
|
218
258
|
normalized_args[normalized_arg_name] = normalized
|
219
259
|
else
|
220
260
|
# Couldn't find a matching argument definition
|
@@ -224,9 +264,12 @@ module GraphQL
|
|
224
264
|
|
225
265
|
# Backfill default values so that trigger arguments
|
226
266
|
# match query arguments.
|
227
|
-
arg_owner.arguments.each do |
|
267
|
+
arg_owner.arguments(context).each do |_name, arg_defn|
|
228
268
|
if arg_defn.default_value? && !normalized_args.key?(arg_defn.name)
|
229
|
-
|
269
|
+
default_value = arg_defn.default_value
|
270
|
+
# We don't have an underlying "object" here, so it can't call methods.
|
271
|
+
# This is broken.
|
272
|
+
normalized_args[arg_defn.name] = arg_defn.prepare_value(nil, default_value, context: context)
|
230
273
|
end
|
231
274
|
end
|
232
275
|
|
@@ -245,9 +288,9 @@ module GraphQL
|
|
245
288
|
|
246
289
|
normalized_args
|
247
290
|
when GraphQL::ListType, GraphQL::Schema::List
|
248
|
-
args.map { |a| normalize_arguments(event_name, arg_owner.of_type, a) }
|
291
|
+
args.map { |a| normalize_arguments(event_name, arg_owner.of_type, a, context) }
|
249
292
|
when GraphQL::NonNullType, GraphQL::Schema::NonNull
|
250
|
-
normalize_arguments(event_name, arg_owner.of_type, args)
|
293
|
+
normalize_arguments(event_name, arg_owner.of_type, args, context)
|
251
294
|
else
|
252
295
|
args
|
253
296
|
end
|
@@ -3,8 +3,9 @@
|
|
3
3
|
module GraphQL
|
4
4
|
module Tracing
|
5
5
|
# This implementation forwards events to ActiveSupport::Notifications
|
6
|
-
# with a `graphql
|
6
|
+
# with a `graphql` suffix.
|
7
7
|
#
|
8
|
+
# @see KEYS for event names
|
8
9
|
module ActiveSupportNotificationsTracing
|
9
10
|
# A cache of frequently-used keys to avoid needless string allocations
|
10
11
|
KEYS = {
|
@@ -0,0 +1,173 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module Tracing
|
5
|
+
|
6
|
+
# This class uses the AppopticsAPM SDK from the appoptics_apm gem to create
|
7
|
+
# traces for GraphQL.
|
8
|
+
#
|
9
|
+
# There are 4 configurations available. They can be set in the
|
10
|
+
# appoptics_apm config file or in code. Please see:
|
11
|
+
# {https://docs.appoptics.com/kb/apm_tracing/ruby/configure}
|
12
|
+
#
|
13
|
+
# AppOpticsAPM::Config[:graphql][:enabled] = true|false
|
14
|
+
# AppOpticsAPM::Config[:graphql][:transaction_name] = true|false
|
15
|
+
# AppOpticsAPM::Config[:graphql][:sanitize_query] = true|false
|
16
|
+
# AppOpticsAPM::Config[:graphql][:remove_comments] = true|false
|
17
|
+
class AppOpticsTracing < GraphQL::Tracing::PlatformTracing
|
18
|
+
# These GraphQL events will show up as 'graphql.prep' spans
|
19
|
+
PREP_KEYS = ['lex', 'parse', 'validate', 'analyze_query', 'analyze_multiplex'].freeze
|
20
|
+
# These GraphQL events will show up as 'graphql.execute' spans
|
21
|
+
EXEC_KEYS = ['execute_multiplex', 'execute_query', 'execute_query_lazy'].freeze
|
22
|
+
|
23
|
+
# During auto-instrumentation this version of AppOpticsTracing is compared
|
24
|
+
# with the version provided in the appoptics_apm gem, so that the newer
|
25
|
+
# version of the class can be used
|
26
|
+
|
27
|
+
def self.version
|
28
|
+
Gem::Version.new('1.0.0')
|
29
|
+
end
|
30
|
+
|
31
|
+
self.platform_keys = {
|
32
|
+
'lex' => 'lex',
|
33
|
+
'parse' => 'parse',
|
34
|
+
'validate' => 'validate',
|
35
|
+
'analyze_query' => 'analyze_query',
|
36
|
+
'analyze_multiplex' => 'analyze_multiplex',
|
37
|
+
'execute_multiplex' => 'execute_multiplex',
|
38
|
+
'execute_query' => 'execute_query',
|
39
|
+
'execute_query_lazy' => 'execute_query_lazy'
|
40
|
+
}
|
41
|
+
|
42
|
+
def platform_trace(platform_key, _key, data)
|
43
|
+
return yield if !defined?(AppOpticsAPM) || gql_config[:enabled] == false
|
44
|
+
|
45
|
+
layer = span_name(platform_key)
|
46
|
+
kvs = metadata(data, layer)
|
47
|
+
kvs[:Key] = platform_key if (PREP_KEYS + EXEC_KEYS).include?(platform_key)
|
48
|
+
|
49
|
+
transaction_name(kvs[:InboundQuery]) if kvs[:InboundQuery] && layer == 'graphql.execute'
|
50
|
+
|
51
|
+
::AppOpticsAPM::SDK.trace(layer, kvs) do
|
52
|
+
kvs.clear # we don't have to send them twice
|
53
|
+
yield
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def platform_field_key(type, field)
|
58
|
+
"graphql.#{type.graphql_name}.#{field.graphql_name}"
|
59
|
+
end
|
60
|
+
|
61
|
+
def platform_authorized_key(type)
|
62
|
+
"graphql.authorized.#{type.graphql_name}"
|
63
|
+
end
|
64
|
+
|
65
|
+
def platform_resolve_type_key(type)
|
66
|
+
"graphql.resolve_type.#{type.graphql_name}"
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def gql_config
|
72
|
+
::AppOpticsAPM::Config[:graphql] ||= {}
|
73
|
+
end
|
74
|
+
|
75
|
+
def transaction_name(query)
|
76
|
+
return if gql_config[:transaction_name] == false ||
|
77
|
+
::AppOpticsAPM::SDK.get_transaction_name
|
78
|
+
|
79
|
+
split_query = query.strip.split(/\W+/, 3)
|
80
|
+
split_query[0] = 'query' if split_query[0].empty?
|
81
|
+
name = "graphql.#{split_query[0..1].join('.')}"
|
82
|
+
|
83
|
+
::AppOpticsAPM::SDK.set_transaction_name(name)
|
84
|
+
end
|
85
|
+
|
86
|
+
def multiplex_transaction_name(names)
|
87
|
+
return if gql_config[:transaction_name] == false ||
|
88
|
+
::AppOpticsAPM::SDK.get_transaction_name
|
89
|
+
|
90
|
+
name = "graphql.multiplex.#{names.join('.')}"
|
91
|
+
name = "#{name[0..251]}..." if name.length > 254
|
92
|
+
|
93
|
+
::AppOpticsAPM::SDK.set_transaction_name(name)
|
94
|
+
end
|
95
|
+
|
96
|
+
def span_name(key)
|
97
|
+
return 'graphql.prep' if PREP_KEYS.include?(key)
|
98
|
+
return 'graphql.execute' if EXEC_KEYS.include?(key)
|
99
|
+
|
100
|
+
key[/^graphql\./] ? key : "graphql.#{key}"
|
101
|
+
end
|
102
|
+
|
103
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
104
|
+
def metadata(data, layer)
|
105
|
+
data.keys.map do |key|
|
106
|
+
case key
|
107
|
+
when :context
|
108
|
+
graphql_context(data[key], layer)
|
109
|
+
when :query
|
110
|
+
graphql_query(data[key])
|
111
|
+
when :query_string
|
112
|
+
graphql_query_string(data[key])
|
113
|
+
when :multiplex
|
114
|
+
graphql_multiplex(data[key])
|
115
|
+
when :path
|
116
|
+
[key, data[key].join(".")]
|
117
|
+
else
|
118
|
+
[key, data[key]]
|
119
|
+
end
|
120
|
+
end.flatten(2).each_slice(2).to_h.merge(Spec: 'graphql')
|
121
|
+
end
|
122
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
123
|
+
|
124
|
+
def graphql_context(context, layer)
|
125
|
+
context.errors && context.errors.each do |err|
|
126
|
+
AppOpticsAPM::API.log_exception(layer, err)
|
127
|
+
end
|
128
|
+
|
129
|
+
[[:Path, context.path.join('.')]]
|
130
|
+
end
|
131
|
+
|
132
|
+
def graphql_query(query)
|
133
|
+
return [] unless query
|
134
|
+
|
135
|
+
query_string = query.query_string
|
136
|
+
query_string = remove_comments(query_string) if gql_config[:remove_comments] != false
|
137
|
+
query_string = sanitize(query_string) if gql_config[:sanitize_query] != false
|
138
|
+
|
139
|
+
[[:InboundQuery, query_string],
|
140
|
+
[:Operation, query.selected_operation_name]]
|
141
|
+
end
|
142
|
+
|
143
|
+
def graphql_query_string(query_string)
|
144
|
+
query_string = remove_comments(query_string) if gql_config[:remove_comments] != false
|
145
|
+
query_string = sanitize(query_string) if gql_config[:sanitize_query] != false
|
146
|
+
|
147
|
+
[:InboundQuery, query_string]
|
148
|
+
end
|
149
|
+
|
150
|
+
def graphql_multiplex(data)
|
151
|
+
names = data.queries.map(&:operations).map(&:keys).flatten.compact
|
152
|
+
multiplex_transaction_name(names) if names.size > 1
|
153
|
+
|
154
|
+
[:Operations, names.join(', ')]
|
155
|
+
end
|
156
|
+
|
157
|
+
def sanitize(query)
|
158
|
+
return unless query
|
159
|
+
|
160
|
+
# remove arguments
|
161
|
+
query.gsub(/"[^"]*"/, '"?"') # strings
|
162
|
+
.gsub(/-?[0-9]*\.?[0-9]+e?[0-9]*/, '?') # ints + floats
|
163
|
+
.gsub(/\[[^\]]*\]/, '[?]') # arrays
|
164
|
+
end
|
165
|
+
|
166
|
+
def remove_comments(query)
|
167
|
+
return unless query
|
168
|
+
|
169
|
+
query.gsub(/#[^\n\r]*/, '')
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
@@ -14,7 +14,22 @@ module GraphQL
|
|
14
14
|
"execute_query_lazy" => "execute.graphql",
|
15
15
|
}
|
16
16
|
|
17
|
+
# @param set_action_name [Boolean] If true, the GraphQL operation name will be used as the transaction name.
|
18
|
+
# This is not advised if you run more than one query per HTTP request, for example, with `graphql-client` or multiplexing.
|
19
|
+
# It can also be specified per-query with `context[:set_appsignal_action_name]`.
|
20
|
+
def initialize(options = {})
|
21
|
+
@set_action_name = options.fetch(:set_action_name, false)
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
17
25
|
def platform_trace(platform_key, key, data)
|
26
|
+
if key == "execute_query"
|
27
|
+
set_this_txn_name = data[:query].context[:set_appsignal_action_name]
|
28
|
+
if set_this_txn_name == true || (set_this_txn_name.nil? && @set_action_name)
|
29
|
+
Appsignal::Transaction.current.set_action(transaction_name(data[:query]))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
18
33
|
Appsignal.instrument(platform_key) do
|
19
34
|
yield
|
20
35
|
end
|
@@ -26,18 +26,7 @@ module GraphQL
|
|
26
26
|
if key == "execute_query"
|
27
27
|
set_this_txn_name = data[:query].context[:set_new_relic_transaction_name]
|
28
28
|
if set_this_txn_name == true || (set_this_txn_name.nil? && @set_transaction_name)
|
29
|
-
|
30
|
-
# Set the transaction name based on the operation type and name
|
31
|
-
selected_op = query.selected_operation
|
32
|
-
if selected_op
|
33
|
-
op_type = selected_op.operation_type
|
34
|
-
op_name = selected_op.name || "anonymous"
|
35
|
-
else
|
36
|
-
op_type = "query"
|
37
|
-
op_name = "anonymous"
|
38
|
-
end
|
39
|
-
|
40
|
-
NewRelic::Agent.set_transaction_name("GraphQL/#{op_type}.#{op_name}")
|
29
|
+
NewRelic::Agent.set_transaction_name(transaction_name(data[:query]))
|
41
30
|
end
|
42
31
|
end
|
43
32
|
|
@@ -32,17 +32,19 @@ module GraphQL
|
|
32
32
|
trace_field = true # implemented with instrumenter
|
33
33
|
else
|
34
34
|
field = data[:field]
|
35
|
-
cache = platform_key_cache(data.fetch(:query).context)
|
36
|
-
platform_key = cache.fetch(field) do
|
37
|
-
cache[field] = platform_field_key(data[:owner], field)
|
38
|
-
end
|
39
|
-
|
40
35
|
return_type = field.type.unwrap
|
41
36
|
trace_field = if return_type.kind.scalar? || return_type.kind.enum?
|
42
37
|
(field.trace.nil? && @trace_scalars) || field.trace
|
43
38
|
else
|
44
39
|
true
|
45
40
|
end
|
41
|
+
|
42
|
+
platform_key = if trace_field
|
43
|
+
context = data.fetch(:query).context
|
44
|
+
cached_platform_key(context, field) { platform_field_key(data[:owner], field) }
|
45
|
+
else
|
46
|
+
nil
|
47
|
+
end
|
46
48
|
end
|
47
49
|
|
48
50
|
if platform_key && trace_field
|
@@ -53,20 +55,16 @@ module GraphQL
|
|
53
55
|
yield
|
54
56
|
end
|
55
57
|
when "authorized", "authorized_lazy"
|
56
|
-
cache = platform_key_cache(data.fetch(:context))
|
57
58
|
type = data.fetch(:type)
|
58
|
-
|
59
|
-
|
60
|
-
end
|
59
|
+
context = data.fetch(:context)
|
60
|
+
platform_key = cached_platform_key(context, type) { platform_authorized_key(type) }
|
61
61
|
platform_trace(platform_key, key, data) do
|
62
62
|
yield
|
63
63
|
end
|
64
64
|
when "resolve_type", "resolve_type_lazy"
|
65
|
-
cache = platform_key_cache(data.fetch(:context))
|
66
65
|
type = data.fetch(:type)
|
67
|
-
|
68
|
-
|
69
|
-
end
|
66
|
+
context = data.fetch(:context)
|
67
|
+
platform_key = cached_platform_key(context, type) { platform_resolve_type_key(type) }
|
70
68
|
platform_trace(platform_key, key, data) do
|
71
69
|
yield
|
72
70
|
end
|
@@ -97,16 +95,44 @@ module GraphQL
|
|
97
95
|
end
|
98
96
|
|
99
97
|
def self.use(schema_defn, options = {})
|
100
|
-
tracer = self.new(options)
|
101
|
-
schema_defn.
|
98
|
+
tracer = self.new(**options)
|
99
|
+
if !schema_defn.is_a?(Class)
|
100
|
+
schema_defn.instrument(:field, tracer)
|
101
|
+
end
|
102
102
|
schema_defn.tracer(tracer)
|
103
103
|
end
|
104
104
|
|
105
105
|
private
|
106
|
+
|
107
|
+
# Get the transaction name based on the operation type and name
|
108
|
+
def transaction_name(query)
|
109
|
+
selected_op = query.selected_operation
|
110
|
+
if selected_op
|
111
|
+
op_type = selected_op.operation_type
|
112
|
+
op_name = selected_op.name || "anonymous"
|
113
|
+
else
|
114
|
+
op_type = "query"
|
115
|
+
op_name = "anonymous"
|
116
|
+
end
|
117
|
+
"GraphQL/#{op_type}.#{op_name}"
|
118
|
+
end
|
119
|
+
|
106
120
|
attr_reader :options
|
107
121
|
|
108
|
-
|
109
|
-
|
122
|
+
# Different kind of schema objects have different kinds of keys:
|
123
|
+
#
|
124
|
+
# - Object types: `.authorized`
|
125
|
+
# - Union/Interface types: `.resolve_type`
|
126
|
+
# - Fields: execution
|
127
|
+
#
|
128
|
+
# So, they can all share one cache.
|
129
|
+
#
|
130
|
+
# If the key isn't present, the given block is called and the result is cached for `key`.
|
131
|
+
#
|
132
|
+
# @return [String]
|
133
|
+
def cached_platform_key(ctx, key)
|
134
|
+
cache = ctx.namespace(self.class)[:platform_key_cache] ||= {}
|
135
|
+
cache.fetch(key) { cache[key] = yield }
|
110
136
|
end
|
111
137
|
end
|
112
138
|
end
|
@@ -16,7 +16,10 @@ module GraphQL
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def collect(object)
|
19
|
-
|
19
|
+
default_labels = { key: object['key'], platform_key: object['platform_key'] }
|
20
|
+
custom = object['custom_labels']
|
21
|
+
labels = custom.nil? ? default_labels : default_labels.merge(custom)
|
22
|
+
|
20
23
|
@graphql_gauge.observe object['duration'], labels
|
21
24
|
end
|
22
25
|
|
@@ -16,12 +16,23 @@ module GraphQL
|
|
16
16
|
"execute_query_lazy" => "execute.graphql",
|
17
17
|
}
|
18
18
|
|
19
|
+
# @param set_transaction_name [Boolean] If true, the GraphQL operation name will be used as the transaction name.
|
20
|
+
# This is not advised if you run more than one query per HTTP request, for example, with `graphql-client` or multiplexing.
|
21
|
+
# It can also be specified per-query with `context[:set_scout_transaction_name]`.
|
19
22
|
def initialize(options = {})
|
20
23
|
self.class.include ScoutApm::Tracer
|
24
|
+
@set_transaction_name = options.fetch(:set_transaction_name, false)
|
21
25
|
super(options)
|
22
26
|
end
|
23
27
|
|
24
28
|
def platform_trace(platform_key, key, data)
|
29
|
+
if key == "execute_query"
|
30
|
+
set_this_txn_name = data[:query].context[:set_scout_transaction_name]
|
31
|
+
if set_this_txn_name == true || (set_this_txn_name.nil? && @set_transaction_name)
|
32
|
+
ScoutApm::Transaction.rename(transaction_name(data[:query]))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
25
36
|
self.class.instrument("GraphQL", platform_key, INSTRUMENT_OPTS) do
|
26
37
|
yield
|
27
38
|
end
|
@@ -18,7 +18,7 @@ module GraphQL
|
|
18
18
|
# This is not advised if you run more than one query per HTTP request, for example, with `graphql-client` or multiplexing.
|
19
19
|
# It can also be specified per-query with `context[:set_skylight_endpoint_name]`.
|
20
20
|
def initialize(options = {})
|
21
|
-
warn("GraphQL::Tracing::SkylightTracing is deprecated, please enable Skylight's GraphQL probe instead: https://www.skylight.io/support/getting-more-from-skylight#graphql.")
|
21
|
+
GraphQL::Deprecation.warn("GraphQL::Tracing::SkylightTracing is deprecated and will be removed in GraphQL-Ruby 2.0, please enable Skylight's GraphQL probe instead: https://www.skylight.io/support/getting-more-from-skylight#graphql.")
|
22
22
|
@set_endpoint_name = options.fetch(:set_endpoint_name, false)
|
23
23
|
super
|
24
24
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module Tracing
|
5
|
+
class StatsdTracing < PlatformTracing
|
6
|
+
self.platform_keys = {
|
7
|
+
'lex' => "graphql.lex",
|
8
|
+
'parse' => "graphql.parse",
|
9
|
+
'validate' => "graphql.validate",
|
10
|
+
'analyze_query' => "graphql.analyze_query",
|
11
|
+
'analyze_multiplex' => "graphql.analyze_multiplex",
|
12
|
+
'execute_multiplex' => "graphql.execute_multiplex",
|
13
|
+
'execute_query' => "graphql.execute_query",
|
14
|
+
'execute_query_lazy' => "graphql.execute_query_lazy",
|
15
|
+
}
|
16
|
+
|
17
|
+
# @param statsd [Object] A statsd client
|
18
|
+
def initialize(statsd:, **rest)
|
19
|
+
@statsd = statsd
|
20
|
+
super(**rest)
|
21
|
+
end
|
22
|
+
|
23
|
+
def platform_trace(platform_key, key, data)
|
24
|
+
@statsd.time(platform_key) do
|
25
|
+
yield
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def platform_field_key(type, field)
|
30
|
+
"graphql.#{type.graphql_name}.#{field.graphql_name}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def platform_authorized_key(type)
|
34
|
+
"graphql.authorized.#{type.graphql_name}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def platform_resolve_type_key(type)
|
38
|
+
"graphql.resolve_type.#{type.graphql_name}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|