Class: GraphQL::Dataloader::Source

Inherits:
Object
  • Object
show all
Defined in:
lib/graphql/dataloader/source.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#dataloaderObject (readonly)

Returns the value of attribute dataloader.



14
15
16
# File 'lib/graphql/dataloader/source.rb', line 14

def dataloader
  @dataloader
end

Instance Method Details

#fetch(keys) ⇒ Array<Object>

Subclasses must implement this method to return a value for each of keys

Parameters:

Returns:

  • (Array<Object>)

    A loaded value for each of keys. The array must match one-for-one to the list of keys.



58
59
60
61
# File 'lib/graphql/dataloader/source.rb', line 58

def fetch(keys)
  # somehow retrieve these from the backend
  raise "Implement `#{self.class}#fetch(#{keys.inspect}) to return a record for each of the keys"
end

#load(key) ⇒ Object

Returns The result from #fetch for key. If key hasn’t been loaded yet, the Fiber will yield until it’s loaded.

Parameters:

  • key (Object)

    A loading key which will be passed to #fetch if it isn’t already in the internal cache.

Returns:

  • (Object)

    The result from #fetch for key. If key hasn’t been loaded yet, the Fiber will yield until it’s loaded.



33
34
35
36
37
38
39
40
41
# File 'lib/graphql/dataloader/source.rb', line 33

def load(key)
  if @results.key?(key)
    result_for(key)
  else
    @pending_keys << key
    sync
    result_for(key)
  end
end

#load_all(keys) ⇒ Object

Returns The result from #fetch for keys. If keys haven’t been loaded yet, the Fiber will yield until they’re loaded.

Parameters:

  • keys (Array<Object>)

    Loading keys which will be passed to #fetch (or read from the internal cache).

Returns:

  • (Object)

    The result from #fetch for keys. If keys haven’t been loaded yet, the Fiber will yield until they’re loaded.



45
46
47
48
49
50
51
52
53
# File 'lib/graphql/dataloader/source.rb', line 45

def load_all(keys)
  if keys.any? { |k| !@results.key?(k) }
    pending_keys = keys.select { |k| !@results.key?(k) }
    @pending_keys.concat(pending_keys)
    sync
  end

  keys.map { |k| result_for(k) }
end

#pending?Boolean

Returns True if this source has any pending requests for data.

Returns:

  • (Boolean)

    True if this source has any pending requests for data.



71
72
73
# File 'lib/graphql/dataloader/source.rb', line 71

def pending?
  @pending_keys.any?
end

#request(key) ⇒ Dataloader::Request

Returns a pending request for a value from key. Call .load on that object to wait for the result.

Returns:

  • (Dataloader::Request)

    a pending request for a value from key. Call .load on that object to wait for the result.



17
18
19
20
21
22
# File 'lib/graphql/dataloader/source.rb', line 17

def request(key)
  if !@results.key?(key)
    @pending_keys << key
  end
  Dataloader::Request.new(self, key)
end

#request_all(keys) ⇒ Dataloader::Request

Returns a pending request for a values from keys. Call .load on that object to wait for the results.

Returns:

  • (Dataloader::Request)

    a pending request for a values from keys. Call .load on that object to wait for the results.



25
26
27
28
29
# File 'lib/graphql/dataloader/source.rb', line 25

def request_all(keys)
  pending_keys = keys.select { |k| !@results.key?(k) }
  @pending_keys.concat(pending_keys)
  Dataloader::RequestAll.new(self, keys)
end

#run_pending_keysvoid

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Called by GraphQL::Dataloader to resolve and pending requests to this source.



78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/graphql/dataloader/source.rb', line 78

def run_pending_keys
  return if @pending_keys.empty?
  fetch_keys = @pending_keys.uniq
  @pending_keys = []
  results = fetch(fetch_keys)
  fetch_keys.each_with_index do |key, idx|
    @results[key] = results[idx]
  end
rescue StandardError => error
  fetch_keys.each { |key| @results[key] = error }
ensure
  nil
end

#setup(dataloader) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Called by GraphQL::Dataloader to prepare the GraphQL::Dataloader::Source’s internal state



8
9
10
11
12
# File 'lib/graphql/dataloader/source.rb', line 8

def setup(dataloader)
  @pending_keys = []
  @results = {}
  @dataloader = dataloader
end

#syncvoid

This method returns an undefined value.

Wait for a batch, if there’s anything to batch. Then run the batch and update the cache.



66
67
68
# File 'lib/graphql/dataloader/source.rb', line 66

def sync
  @dataloader.yield
end