Class: Dataloader
- Inherits:
-
Object
- Object
- Dataloader
- Defined in:
- lib/dataloader.rb
Instance Attribute Summary collapse
-
#cache ⇒ Object
Returns the internal cache that can be overridden with ‘:cache` option (see constructor) This field is writable, so you can reset the cache with something like:.
Class Method Summary collapse
-
.wait ⇒ Object
Forces all currently pending promises to be executed and resolved.
Instance Method Summary collapse
-
#initialize(options = {}) {|array| ... } ⇒ Dataloader
constructor
Creates new dataloader.
-
#load(key) ⇒ Promise<Object>
Loads a key, returning a [Promise](github.com/lgierth/promise.rb) for the value represented by that key.
-
#load_many(keys) ⇒ Promise<Object>
Loads multiple keys, promising an array of values:.
Constructor Details
#initialize(options = {}) {|array| ... } ⇒ Dataloader
Creates new dataloader
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/dataloader.rb', line 117 def initialize( = {}, &batch_load) Thread.current[:pending_batches] ||= [] unless block_given? raise TypeError, "Dataloader must be constructed with a block which accepts " \ "Array and returns either Array or Hash of the same size (or Promise)" end @batch_promise = Batch.new(self) @batch_load = batch_load @key = .fetch(:key, lambda { |key| key }) @cache = .fetch(:cache, Concurrent::Map.new) @max_batch_size = .fetch(:max_batch_size, Float::INFINITY) if @cache.nil? @cache = NoCache.new end end |
Instance Attribute Details
#cache ⇒ Object
Returns the internal cache that can be overridden with ‘:cache` option (see constructor) This field is writable, so you can reset the cache with something like:
loader.cache = Concurrent::Map.new
Defaults to Concurrent::Map.new
102 103 104 |
# File 'lib/dataloader.rb', line 102 def cache @cache end |
Class Method Details
.wait ⇒ Object
Forces all currently pending promises to be executed and resolved
This method is invoked automatically when value of any promise is requested with ‘.sync`
146 147 148 149 150 151 152 |
# File 'lib/dataloader.rb', line 146 def self.wait until Thread.current[:pending_batches].empty? pending = Thread.current[:pending_batches] Thread.current[:pending_batches] = [] pending.each(&:dispatch) end end |
Instance Method Details
#load(key) ⇒ Promise<Object>
Loads a key, returning a [Promise](github.com/lgierth/promise.rb) for the value represented by that key.
You can resolve this promise when you actually need the value with ‘promise.sync`.
All calls to ‘#load` are batched until the first `#sync` is encountered. Then is starts batching again, et caetera.
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/dataloader.rb', line 172 def load(key) if key.nil? raise TypeError, "#load must be called with a key, but got: nil" end result = compute_if_absent(key) do batch_promise.queue(key) end unless result.is_a?(Promise) return Promise.new.fulfill(result) end result end |
#load_many(keys) ⇒ Promise<Object>
Loads multiple keys, promising an array of values:
“‘ruby promise = loader.load_many([’a’, ‘b’]) object_a, object_b = promise.sync “‘
This is equivalent to the more verbose:
“‘ruby promise = Promise.all([loader.load(’a’), loader.load(‘b’)]) object_a, object_b = promise.sync “‘
214 215 216 217 218 219 220 |
# File 'lib/dataloader.rb', line 214 def load_many(keys) unless keys.is_a?(Array) raise TypeError, "#load_many must be called with an Array, but got: #{keys.class.name}" end Promise.all(keys.map(&method(:load))) end |