class MasterLoader::Batch

Attributes

fulfilled[RW]
name[RW]

Public Class Methods

new(loader_block, name: nil, max_batch_size: Float::INFINITY) click to toggle source
# File lib/master_loader.rb, line 47
def initialize(loader_block, name: nil, max_batch_size: Float::INFINITY)
  @name = name
  @queue = Concurrent::Array.new
  @lock = Concurrent::ReadWriteLock.new
  @loader_block = loader_block
  @max_batch_size = max_batch_size
  @fulfilled = false
  @results = nil
end

Public Instance Methods

fulfilled?() click to toggle source
# File lib/master_loader.rb, line 89
def fulfilled?
  @fulfilled
end
queue(key) click to toggle source
# File lib/master_loader.rb, line 57
def queue(key)
  @queue << key

  DelayedResult.new do
    results = if @fulfilled
                @lock.with_read_lock do
                  @results
                end
              else
                @lock.with_write_lock do
                  if @fulfilled
                    @results
                  else
                    @fulfilled = true
                    r = @loader_block.(@queue)
                    @results = if r.is_a?(DelayedResult)
                      normalize_results(r.value!)
                    else
                      normalize_results(r)
                    end
                  end
                end
              end

    unless results.key?(key)
      raise StandardError, "Batch loader didn't resolve a key: #{key}. Resolved keys: #{results.keys}"
    end

    results[key]
  end
end

Private Instance Methods

normalize_results(results) click to toggle source
# File lib/master_loader.rb, line 95
def normalize_results(results)
  unless results.is_a?(Array) || results.is_a?(Hash)
    raise TypeError, "Batch loader must return an Array or Hash, but returned: #{results.class.name}"
  end

  if @queue.size != results.size
    raise StandardError, "Batch loader must be instantiated with function that returns Array or Hash " \
      "of the same size as provided to it Array of keys" \
      "\n\nProvided keys:\n#{@queue}" \
      "\n\nReturned values:\n#{results}"
  end

  if results.is_a?(Array)
    Hash[@queue.zip(results)]
  elsif results.is_a?(Hash)
    results
  end
end