graphql-batch 0.4.3 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fccdeee0358f45c6750102fa77b7537f11d4a269a40985be5e8c01db1314b346
4
- data.tar.gz: ca0737882a1d16189c262e30e113deffb46d4ed50faabca99f3b81f2c317ed9a
3
+ metadata.gz: afe26d607949310c337c3f88cb6f356ccd51923d841fa1e7e8840f0fa5b34012
4
+ data.tar.gz: 1f45b62562ef558a6f6b59479b198fdb548b8f03f061ebb0e6c51b6cff74c6b4
5
5
  SHA512:
6
- metadata.gz: 8edbbe8673b1581b2927fed0ed4af9370f7009d0662cac952bebe0cc00cec2bf32fafe4eee092af47666e61f3f8a09ec3298d95715a7d6436e91af4dacfc2f02
7
- data.tar.gz: 3b4cd32b2f65e7af83394a151df55f9880b8d0381d687c1135dfb541a9dd90e4bdaca8071d5aae68976ae176e3bc74304ae639f884dcad3e26249abd4e4c1334
6
+ metadata.gz: 7416844cffe48e01ca8640382e831cafdd1d64efcbcb927677a2d8833a3883400806cb94f16c8057d9c0f15ca543640b8084ba7616bb2b7376fa21f75a366179
7
+ data.tar.gz: 7473cb5eb3893fc61b0be940c28a8582a3316e912909ec7d2c8d1aeb9f01b1011b88c3ca754330f48152276ed0463e39508b625b5351800a53254dfc86669e5f
@@ -0,0 +1,28 @@
1
+ name: Tests
2
+
3
+ on:
4
+ - push
5
+ - pull_request
6
+
7
+ jobs:
8
+ test:
9
+ runs-on: ubuntu-latest
10
+ strategy:
11
+ fail-fast: false
12
+ matrix:
13
+ ruby: [2.7, 3.1, 3.3]
14
+ graphql_version: ['~> 1.12.18', '~> 1.13', '~> 2.0']
15
+ include:
16
+ - ruby: 2.4
17
+ graphql_version: '~> 1.12.18'
18
+ - ruby: 2.4
19
+ graphql_version: '~> 1.13'
20
+ steps:
21
+ - uses: actions/checkout@v2
22
+ - uses: ruby/setup-ruby@v1
23
+ with:
24
+ bundler-cache: true
25
+ ruby-version: ${{ matrix.ruby }}
26
+ env:
27
+ GRAPHQL_VERSION: ${{ matrix.graphql_version }}
28
+ - run: bundle exec rake
@@ -0,0 +1,22 @@
1
+ name: Contributor License Agreement (CLA)
2
+
3
+ on:
4
+ pull_request_target:
5
+ types: [opened, synchronize]
6
+ issue_comment:
7
+ types: [created]
8
+
9
+ jobs:
10
+ cla:
11
+ runs-on: ubuntu-latest
12
+ if: |
13
+ (github.event.issue.pull_request
14
+ && !github.event.issue.pull_request.merged_at
15
+ && contains(github.event.comment.body, 'signed')
16
+ )
17
+ || (github.event.pull_request && !github.event.pull_request.merged)
18
+ steps:
19
+ - uses: Shopify/shopify-cla-action@v1
20
+ with:
21
+ github-token: ${{ secrets.GITHUB_TOKEN }}
22
+ cla-token: ${{ secrets.CLA_TOKEN }}
data/.rubocop.yml CHANGED
@@ -1,6 +1,11 @@
1
+ inherit_gem:
2
+ rubocop-shopify: rubocop.yml
3
+
1
4
  inherit_from:
2
- - https://shopify.github.io/ruby-style-guide/rubocop.yml
3
5
  - .rubocop_todo.yml
4
6
 
5
7
  AllCops:
6
- TargetRubyVersion: 2.3
8
+ SuggestExtensions: false
9
+ TargetRubyVersion: 2.7
10
+ Exclude:
11
+ - vendor/**/*
data/.rubocop_todo.yml CHANGED
@@ -56,6 +56,13 @@ Layout/SpaceInsideParens:
56
56
  Exclude:
57
57
  - 'test/loader_test.rb'
58
58
 
59
+ # Offense count: 3
60
+ Lint/MissingSuper:
61
+ Exclude:
62
+ - 'test/executor_test.rb'
63
+ - 'test/loader_test.rb'
64
+ - 'test/support/loaders.rb'
65
+
59
66
  # Offense count: 5
60
67
  # Cop supports --auto-correct.
61
68
  # Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments.
data/Gemfile CHANGED
@@ -3,4 +3,7 @@ source 'https://rubygems.org'
3
3
  gemspec
4
4
 
5
5
  gem 'graphql', ENV['GRAPHQL_VERSION'] if ENV['GRAPHQL_VERSION']
6
- gem 'rubocop', '~> 0.78.0', require: false
6
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.4.0')
7
+ gem 'rubocop', '~> 1.12.0', require: false
8
+ gem "rubocop-shopify", '~> 1.0.7', require: false
9
+ end
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # GraphQL::Batch
2
2
 
3
- [![Build Status](https://travis-ci.org/Shopify/graphql-batch.svg?branch=master)](https://travis-ci.org/Shopify/graphql-batch)
3
+ [![Build Status](https://github.com/Shopify/graphql-batch/actions/workflows/ci.yml/badge.svg)](https://github.com/Shopify/graphql-batch/actions)
4
4
  [![Gem Version](https://badge.fury.io/rb/graphql-batch.svg)](https://rubygems.org/gems/graphql-batch)
5
5
 
6
6
  Provides an executor for the [`graphql` gem](https://github.com/rmosolgo/graphql-ruby) which allows queries to be batched.
@@ -50,7 +50,7 @@ end
50
50
 
51
51
  Use `GraphQL::Batch` as a plugin in your schema _after_ specifying the mutation
52
52
  so that `GraphQL::Batch` can extend the mutation fields to clear the cache after
53
- they are resolved (for graphql >= `1.5.0`).
53
+ they are resolved.
54
54
 
55
55
  ```ruby
56
56
  class MySchema < GraphQL::Schema
@@ -61,16 +61,6 @@ class MySchema < GraphQL::Schema
61
61
  end
62
62
  ```
63
63
 
64
- For pre `1.5.0` versions:
65
-
66
- ```ruby
67
- MySchema = GraphQL::Schema.define do
68
- query MyQueryType
69
-
70
- GraphQL::Batch.use(self)
71
- end
72
- ```
73
-
74
64
  #### Field Usage
75
65
 
76
66
  The loader class can be used from the resolver for a graphql field by calling `.for` with the grouping arguments to get a loader instance, then call `.load` on that instance with the key to load.
@@ -132,9 +122,7 @@ def all_collections
132
122
  Promise.all([
133
123
  CountLoader.for(Shop, :smart_collections).load(context.shop_id),
134
124
  CountLoader.for(Shop, :custom_collections).load(context.shop_id),
135
- ]).then do |results|
136
- results.reduce(&:+)
137
- end
125
+ ]).then(&:sum)
138
126
  end
139
127
  ```
140
128
 
@@ -152,22 +140,38 @@ def product(id:)
152
140
  end
153
141
  ```
154
142
 
143
+ ### Priming the Cache
144
+
145
+ You can prime the loader cache with a specific value, which can be useful in certain situations.
146
+
147
+ ```ruby
148
+ def liked_products
149
+ liked_products = Product.where(liked: true).load
150
+ liked_products.each do |product|
151
+ RecordLoader.for(Product).prime(product.id, product)
152
+ end
153
+ end
154
+ ```
155
+
156
+ Priming will add key/value to the loader cache only if it didn't exist before.
157
+
158
+
155
159
  ## Unit Testing
156
160
 
157
161
  Your loaders can be tested outside of a GraphQL query by doing the
158
- batch loads in a block passed to GraphQL::Batch.batch. That method
162
+ batch loads in a block passed to `GraphQL::Batch.batch`. That method
159
163
  will set up thread-local state to store the loaders, batch load any
160
164
  promise returned from the block then clear the thread-local state
161
165
  to avoid leaking state between tests.
162
166
 
163
167
  ```ruby
164
- def test_single_query
165
- product = products(:snowboard)
166
- title = GraphQL::Batch.batch do
167
- RecordLoader.for(Product).load(product.id).then(&:title)
168
- end
169
- assert_equal product.title, title
168
+ def test_single_query
169
+ product = products(:snowboard)
170
+ title = GraphQL::Batch.batch do
171
+ RecordLoader.for(Product).load(product.id).then(&:title)
170
172
  end
173
+ assert_equal product.title, title
174
+ end
171
175
  ```
172
176
 
173
177
  ## Development
data/Rakefile CHANGED
@@ -7,9 +7,13 @@ Rake::TestTask.new(:test) do |t|
7
7
  t.test_files = FileList['test/**/*_test.rb']
8
8
  end
9
9
 
10
- task :rubocop do
11
- require 'rubocop/rake_task'
12
- RuboCop::RakeTask.new
13
- end
10
+ task(default: :test)
11
+
12
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.4.0')
13
+ task :rubocop do
14
+ require 'rubocop/rake_task'
15
+ RuboCop::RakeTask.new
16
+ end
14
17
 
15
- task(default: [:test, :rubocop])
18
+ task(default: :rubocop)
19
+ end
@@ -0,0 +1,75 @@
1
+ ####
2
+ # This is a loader for has_one_attached and has_many_attached Active Storage attachments
3
+ # To load a variant for an attachment, 2 queries are required
4
+ # Using preloading via the includes method.
5
+ ####
6
+
7
+ ####
8
+ # The model with an attached image and many attached pictures
9
+ ####
10
+
11
+ # class Event < ApplicationRecord
12
+ # has_one_attached :image
13
+ # has_many_attached :pictures
14
+ # end
15
+
16
+ ####
17
+ # An example data type using the Loaders::ActiveStorageLoader
18
+ ####
19
+
20
+ # class Types::EventType < Types::BaseObject
21
+ # graphql_name 'Event'
22
+ #
23
+ # field :id, ID, null: false
24
+ # field :image, String, null: true
25
+ # field :pictures, String, null: true
26
+ #
27
+ # def image
28
+ # Loaders::ActiveStorageLoader.for(:Event, :image).load(object.id).then do |image|
29
+ # Rails.application.routes.url_helpers.url_for(
30
+ # image.variant({ quality: 75 })
31
+ # )
32
+ # end
33
+ # end
34
+ #
35
+ # def pictures
36
+ # Loaders::ActiveStorageLoader.for(:Event, :pictures, association_type: :has_many_attached).load(object.id).then do |pictures|
37
+ # pictures.map do |picture|
38
+ # Rails.application.routes.url_helpers.url_for(
39
+ # picture.variant({ quality: 75 })
40
+ # )
41
+ # end
42
+ # end
43
+ # end
44
+ # end
45
+ module Loaders
46
+ class ActiveStorageLoader < GraphQL::Batch::Loader
47
+ attr_reader :record_type, :attachment_name, :association_type # should be has_one_attached or has_many_attached
48
+
49
+ def initialize(record_type, attachment_name, association_type: :has_one_attached)
50
+ super()
51
+ @record_type = record_type
52
+ @attachment_name = attachment_name
53
+ @association_type = association_type
54
+ end
55
+
56
+ def perform(record_ids)
57
+ # find records and fulfill promises
58
+ attachments = ActiveStorage::Attachment.includes(:blob).where(
59
+ record_type: record_type, record_id: record_ids, name: attachment_name
60
+ )
61
+
62
+ if @association_type == :has_one_attached
63
+ attachments.each do |attachment|
64
+ fulfill(attachment.record_id, attachment)
65
+ end
66
+
67
+ record_ids.each { |id| fulfill(id, nil) unless fulfilled?(id) }
68
+ else
69
+ record_ids.each do |record_id|
70
+ fulfill(record_id, attachments.select { |attachment| attachment.record_id == record_id })
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -5,6 +5,7 @@ class AssociationLoader < GraphQL::Batch::Loader
5
5
  end
6
6
 
7
7
  def initialize(model, association_name)
8
+ super()
8
9
  @model = model
9
10
  @association_name = association_name
10
11
  validate
@@ -35,7 +36,7 @@ class AssociationLoader < GraphQL::Batch::Loader
35
36
  end
36
37
 
37
38
  def preload_association(records)
38
- ::ActiveRecord::Associations::Preloader.new.preload(records, @association_name)
39
+ ::ActiveRecord::Associations::Preloader.new(records: records, associations: @association_name).call
39
40
  end
40
41
 
41
42
  def read_association(record)
@@ -35,22 +35,30 @@
35
35
  # }
36
36
  # GQL
37
37
 
38
+ # An example loader which is blocking and synchronous as a whole, but executes all of its operations concurrently.
38
39
  module Loaders
39
40
  class HTTPLoader < GraphQL::Batch::Loader
40
41
  def initialize(host:, size: 4, timeout: 4)
42
+ super()
41
43
  @host = host
42
44
  @size = size
43
45
  @timeout = timeout
44
46
  end
45
47
 
46
48
  def perform(operations)
49
+ # This fans out and starts off all the concurrent work, which starts and
50
+ # immediately returns Concurrent::Promises::Future` objects for each operation.
47
51
  futures = operations.map do |operation|
48
52
  Concurrent::Promises.future do
49
53
  pool.with { |connection| operation.call(connection) }
50
54
  end
51
55
  end
56
+ # At this point, all of the concurrent work has been started.
57
+
58
+ # This converges back in, waiting on each concurrent future to finish, and fulfilling each
59
+ # (non-concurrent) Promise.rb promise.
52
60
  operations.each_with_index.each do |operation, index|
53
- fulfill(operation, futures[index].value)
61
+ fulfill(operation, futures[index].value) # .value is a blocking call
54
62
  end
55
63
  end
56
64
 
@@ -1,5 +1,6 @@
1
1
  class RecordLoader < GraphQL::Batch::Loader
2
2
  def initialize(model, column: model.primary_key, where: nil)
3
+ super()
3
4
  @model = model
4
5
  @column = column.to_s
5
6
  @column_type = model.type_for_attribute(@column)
@@ -0,0 +1,81 @@
1
+ ####
2
+ # This is a has_many loader which takes advantage of Postgres'
3
+ # windowing functionality to load the first N records for
4
+ # a given relationship.
5
+ ####
6
+
7
+ ####
8
+ # An example data type using the WindowKeyLoader
9
+ ####
10
+
11
+ # class Types::CategoryType < Types::BaseObject
12
+ # graphql_name 'Category'
13
+
14
+ # field :id, ID, null: false
15
+ # field :events, [Types::EventType], null: false do
16
+ # argument :first, Int, required: false, default_value: 5
17
+ # end
18
+
19
+ # def events(first:)
20
+ # WindowKeyLoader.for(
21
+ # Event,
22
+ # :category_id,
23
+ # limit: first, order_col: :start_time, order_dir: :desc
24
+ # ).load(object.id)
25
+ # end
26
+ # end
27
+
28
+ ####
29
+ # The SQL that is produced
30
+ ####
31
+
32
+ # SELECT
33
+ # "events".*
34
+ # FROM (
35
+ # SELECT
36
+ # "events".*,
37
+ # row_number() OVER (PARTITION BY category_id ORDER BY start_time DESC) AS rank
38
+ # FROM
39
+ # "events"
40
+ # WHERE
41
+ # "events"."category_id" IN(1, 2, 3, 4, 5)) AS events
42
+ # WHERE (rank <= 5)
43
+
44
+ class WindowKeyLoader < GraphQL::Batch::Loader
45
+ attr_reader :model, :foreign_key, :limit, :order_col, :order_dir
46
+
47
+ def initialize(model, foreign_key, limit:, order_col:, order_dir: :asc)
48
+ super()
49
+ @model = model
50
+ @foreign_key = foreign_key
51
+ @limit = limit
52
+ @order_col = order_col
53
+ @order_dir = order_dir
54
+ end
55
+
56
+ def perform(foreign_ids)
57
+ # build the sub-query, limiting results by foreign key at this point
58
+ # we don't want to execute this query but get its SQL to be used later
59
+ ranked_from =
60
+ model.select(
61
+ "*",
62
+ "row_number() OVER (
63
+ PARTITION BY #{foreign_key} ORDER BY #{order_col} #{order_dir}
64
+ ) as rank"
65
+ ).where(foreign_key => foreign_ids).to_sql
66
+
67
+ # use the sub-query from above to query records which have a rank
68
+ # value less than or equal to our limit
69
+ records =
70
+ model.from("(#{ranked_from}) as #{model.table_name}").where(
71
+ "rank <= #{limit}"
72
+ ).to_a
73
+
74
+ # match records and fulfill promises
75
+ foreign_ids.each do |foreign_id|
76
+ matching_records =
77
+ records.select { |r| foreign_id == r.send(foreign_key) }
78
+ fulfill(foreign_id, matching_records)
79
+ end
80
+ end
81
+ end
@@ -1,7 +1,4 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'graphql/batch/version'
1
+ require_relative 'lib/graphql/batch/version'
5
2
 
6
3
  Gem::Specification.new do |spec|
7
4
  spec.name = "graphql-batch"
@@ -20,7 +17,7 @@ Gem::Specification.new do |spec|
20
17
 
21
18
  spec.metadata['allowed_push_host'] = "https://rubygems.org"
22
19
 
23
- spec.add_runtime_dependency "graphql", ">= 1.3", "< 2"
20
+ spec.add_runtime_dependency "graphql", ">= 1.12.18", "< 3"
24
21
  spec.add_runtime_dependency "promise.rb", "~> 0.7.2"
25
22
 
26
23
  spec.add_development_dependency "byebug" if RUBY_ENGINE == 'ruby'
@@ -34,7 +34,7 @@ module GraphQL::Batch
34
34
  unless executor
35
35
  raise GraphQL::Batch::NoExecutorError, 'Cannot create loader without'\
36
36
  ' an Executor. Wrap the call to `for` with `GraphQL::Batch.batch`'\
37
- ' or use `GraphQL::Batch::Setup` as a query instrumenter if'\
37
+ ' or use `GraphQL::Batch::SetupMultiplex` as a query instrumenter if'\
38
38
  ' using with `graphql-ruby`'
39
39
  end
40
40
 
@@ -44,6 +44,13 @@ module GraphQL::Batch
44
44
 
45
45
  attr_accessor :loader_key, :executor
46
46
 
47
+ def initialize
48
+ @loader_key = nil
49
+ @executor = nil
50
+ @queue = nil
51
+ @cache = nil
52
+ end
53
+
47
54
  def load(key)
48
55
  cache[cache_key(key)] ||= begin
49
56
  queue << key
@@ -55,16 +62,29 @@ module GraphQL::Batch
55
62
  ::Promise.all(keys.map { |key| load(key) })
56
63
  end
57
64
 
65
+ def prime(key, value)
66
+ cache[cache_key(key)] ||= ::Promise.resolve(value).tap { |p| p.source = self }
67
+ end
68
+
58
69
  def resolve #:nodoc:
59
70
  return if resolved?
60
71
  load_keys = queue
61
72
  @queue = nil
62
- perform(load_keys)
73
+
74
+ around_perform do
75
+ perform(load_keys)
76
+ end
77
+
63
78
  check_for_broken_promises(load_keys)
64
79
  rescue => err
65
80
  reject_pending_promises(load_keys, err)
66
81
  end
67
82
 
83
+ # Interface to add custom code for purposes such as instrumenting the performance of the loader.
84
+ def around_perform
85
+ yield
86
+ end
87
+
68
88
  # For Promise#sync
69
89
  def wait #:nodoc:
70
90
  if executor
@@ -95,7 +115,15 @@ module GraphQL::Batch
95
115
 
96
116
  # Returns true when the key has already been fulfilled, otherwise returns false
97
117
  def fulfilled?(key)
98
- promise_for(key).fulfilled?
118
+ promise = promise_for(key)
119
+ # When a promise is fulfilled through this class, it will either:
120
+ # become fulfilled, if fulfilled with a literal value
121
+ # become pending with a new source if fulfilled with a promise
122
+ # Either of these is acceptable, promise.rb will automatically re-wait
123
+ # on the new source promise as needed.
124
+ return true if promise.fulfilled?
125
+
126
+ promise.pending? && promise.source != self
99
127
  end
100
128
 
101
129
  # Must override to load the keys and call #fulfill for each key
@@ -140,7 +168,13 @@ module GraphQL::Batch
140
168
 
141
169
  def check_for_broken_promises(load_keys)
142
170
  load_keys.each do |key|
143
- next unless promise_for(key).pending?
171
+ promise = promise_for(key)
172
+ # When a promise is fulfilled through this class, it will either:
173
+ # become not pending, if fulfilled with a literal value
174
+ # become pending with a new source if fulfilled with a promise
175
+ # Either of these is acceptable, promise.rb will automatically re-wait
176
+ # on the new source promise as needed.
177
+ next unless promise.pending? && promise.source == self
144
178
 
145
179
  reject(key, ::Promise::BrokenError.new("#{self.class} didn't fulfill promise for key #{key.inspect}"))
146
180
  end
@@ -6,15 +6,25 @@ module GraphQL::Batch
6
6
  end
7
7
 
8
8
  def before_multiplex(multiplex)
9
- Setup.start_batching(@executor_class)
9
+ GraphQL::Batch::Executor.start_batch(@executor_class)
10
10
  end
11
11
 
12
12
  def after_multiplex(multiplex)
13
- Setup.end_batching
13
+ GraphQL::Batch::Executor.end_batch
14
14
  end
15
15
 
16
- def instrument(type, field)
17
- Setup.instrument_field(@schema, type, field)
16
+ module Trace
17
+ def initialize(executor_class:, **_rest)
18
+ @executor_class = executor_class
19
+ super
20
+ end
21
+
22
+ def execute_multiplex(multiplex:)
23
+ GraphQL::Batch::Executor.start_batch(@executor_class)
24
+ super
25
+ ensure
26
+ GraphQL::Batch::Executor.end_batch
27
+ end
18
28
  end
19
29
  end
20
30
  end
@@ -1,5 +1,5 @@
1
1
  module GraphQL
2
2
  module Batch
3
- VERSION = "0.4.3"
3
+ VERSION = "0.6.0"
4
4
  end
5
5
  end
data/lib/graphql/batch.rb CHANGED
@@ -16,29 +16,21 @@ module GraphQL
16
16
  end
17
17
 
18
18
  def self.use(schema_defn, executor_class: GraphQL::Batch::Executor)
19
- # Support 1.10+ which passes the class instead of the definition proxy
20
- schema = schema_defn.is_a?(Class) ? schema_defn : schema_defn.target
21
- current_gem_version = Gem::Version.new(GraphQL::VERSION)
22
- if current_gem_version >= Gem::Version.new("1.6.0")
23
- instrumentation = GraphQL::Batch::SetupMultiplex.new(schema, executor_class: executor_class)
19
+ if schema_defn.respond_to?(:trace_with)
20
+ schema_defn.trace_with(GraphQL::Batch::SetupMultiplex::Trace, executor_class: executor_class)
21
+ else
22
+ instrumentation = GraphQL::Batch::SetupMultiplex.new(schema_defn, executor_class: executor_class)
24
23
  schema_defn.instrument(:multiplex, instrumentation)
25
- if schema.mutation
26
- if current_gem_version >= Gem::Version.new('1.9.0.pre3') &&
27
- (schema.mutation.is_a?(Class) || schema.mutation.metadata[:type_class])
28
- require_relative "batch/mutation_field_extension"
29
- schema.mutation.fields.each do |name, f|
30
- field = f.respond_to?(:type_class) ? f.type_class : f.metadata[:type_class]
31
- field.extension(GraphQL::Batch::MutationFieldExtension)
32
- end
33
- else
34
- schema_defn.instrument(:field, instrumentation)
35
- end
24
+ end
25
+
26
+ if schema_defn.mutation
27
+ require_relative "batch/mutation_field_extension"
28
+
29
+ schema_defn.mutation.fields.each do |name, field|
30
+ field.extension(GraphQL::Batch::MutationFieldExtension)
36
31
  end
37
- else
38
- instrumentation = GraphQL::Batch::Setup.new(schema, executor_class: executor_class)
39
- schema_defn.instrument(:query, instrumentation)
40
- schema_defn.instrument(:field, instrumentation)
41
32
  end
33
+
42
34
  schema_defn.lazy_resolve(::Promise, :sync)
43
35
  end
44
36
  end
@@ -47,5 +39,4 @@ end
47
39
  require_relative "batch/version"
48
40
  require_relative "batch/loader"
49
41
  require_relative "batch/executor"
50
- require_relative "batch/setup"
51
42
  require_relative "batch/setup_multiplex"