From 3994bce90d0e7c6638953044942ff4af35890a7a Mon Sep 17 00:00:00 2001 From: Jonathan Baker Date: Wed, 5 Nov 2025 16:51:10 -0500 Subject: [PATCH 1/2] Add rudimentary default resolver tracker. --- lib/graphql/schema/field.rb | 11 +++++++++ .../schema/field/default_resolver_tracker.rb | 23 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 lib/graphql/schema/field/default_resolver_tracker.rb diff --git a/lib/graphql/schema/field.rb b/lib/graphql/schema/field.rb index 98cf087d06b..d29d62edfbb 100644 --- a/lib/graphql/schema/field.rb +++ b/lib/graphql/schema/field.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require "graphql/schema/field/connection_extension" require "graphql/schema/field/scope_extension" +require "graphql/schema/field/default_resolver_tracker" module GraphQL class Schema @@ -737,7 +738,10 @@ def resolve(object, args, query_ctx) inner_object = obj.object + tracker = query_ctx[:default_resolver_tracker] + if !NOT_CONFIGURED.equal?(@hash_key) + tracker&.track(self, :hash_key) hash_value = if inner_object.is_a?(Hash) inner_object.key?(@hash_key) ? inner_object[@hash_key] : inner_object[@hash_key_str] elsif inner_object.respond_to?(:[]) @@ -751,6 +755,7 @@ def resolve(object, args, query_ctx) hash_value || (@fallback_value != NOT_CONFIGURED ? @fallback_value : nil) end elsif obj.respond_to?(resolver_method) + tracker&.track(self, :resolver_method) method_to_call = resolver_method method_receiver = obj # Call the method with kwargs, if there are any @@ -761,17 +766,22 @@ def resolve(object, args, query_ctx) end elsif inner_object.is_a?(Hash) if @dig_keys + tracker&.track(self, :hash_dig_keys) inner_object.dig(*@dig_keys) elsif inner_object.key?(@method_sym) + tracker&.track(self, :hash_method_sym) inner_object[@method_sym] elsif inner_object.key?(@method_str) || !inner_object.default_proc.nil? + tracker&.track(self, :hash_method_str) inner_object[@method_str] elsif @fallback_value != NOT_CONFIGURED + tracker&.track(self, :hash_fallback) @fallback_value else nil end elsif inner_object.respond_to?(@method_sym) + tracker&.track(self, :send_method_sym) method_to_call = @method_sym method_receiver = obj.object if !ruby_kwargs.empty? @@ -780,6 +790,7 @@ def resolve(object, args, query_ctx) inner_object.public_send(@method_sym) end elsif @fallback_value != NOT_CONFIGURED + tracker&.track(self, :fallback) @fallback_value else raise <<-ERR diff --git a/lib/graphql/schema/field/default_resolver_tracker.rb b/lib/graphql/schema/field/default_resolver_tracker.rb new file mode 100644 index 00000000000..31cae94ff31 --- /dev/null +++ b/lib/graphql/schema/field/default_resolver_tracker.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module GraphQL + class Schema + class Field + class DefaultResolverTracker + attr_reader :counts_by_field + + def initialize + @counts_by_field = Hash.new do |h, k| + h[k] = Hash.new do |h2, k2| + h2[k2] = 0 + end + end + end + + def track(field, strategy) + @counts_by_field[field.path][strategy] += 1 + end + end + end + end +end From 1902327c8a0dd9a287cc8772bffbc942ab64582b Mon Sep 17 00:00:00 2001 From: Jonathan Baker Date: Fri, 7 Nov 2025 14:37:50 -0500 Subject: [PATCH 2/2] Track usage by strategy --- lib/graphql/schema/field/default_resolver_tracker.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/graphql/schema/field/default_resolver_tracker.rb b/lib/graphql/schema/field/default_resolver_tracker.rb index 31cae94ff31..21ac1ae450c 100644 --- a/lib/graphql/schema/field/default_resolver_tracker.rb +++ b/lib/graphql/schema/field/default_resolver_tracker.rb @@ -5,6 +5,7 @@ class Schema class Field class DefaultResolverTracker attr_reader :counts_by_field + attr_reader :strategy_by_field def initialize @counts_by_field = Hash.new do |h, k| @@ -12,10 +13,14 @@ def initialize h2[k2] = 0 end end + @strategy_by_field = Hash.new do |h, k| + h[k] = Set.new + end end def track(field, strategy) @counts_by_field[field.path][strategy] += 1 + @strategy_by_field[strategy] << field.path end end end