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
:cacheoption (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 |