Skip to content

Instantly share code, notes, and snippets.

@dhotson
Created October 19, 2020 22:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dhotson/8114f7219b75f82a74bf8f01cdebee7a to your computer and use it in GitHub Desktop.
Save dhotson/8114f7219b75f82a74bf8f01cdebee7a to your computer and use it in GitHub Desktop.
require "set"
class Batch
def initialize(results = {}, &blk)
@ids = ::Set.new
@blk = blk
@promises = {}
@results = results
end
def load(id)
@ids << id
@promises[id] ||= -> {
sync unless @results[id]
@results[id]
}
end
private
def sync
loader = ->(id, result) {
@results[id] = result
}
@blk.call(@ids, loader)
@ids.clear
end
end
# main
my_loader = Batch.new { |ids, loader|
puts "Loading for #{ids.inspect}"
ids.map { |id| loader.call(id, "cool #{id}") }
}
a = my_loader.load(1)
b = my_loader.load(2)
c = my_loader.load(2)
puts "a: #{a.call.inspect}"
puts "b: #{b.call.inspect}"
puts "c: #{c.call.inspect}"
d = my_loader.load(4)
puts "d: #{d.call.inspect}"
# Output
# Loading for #<Set: {1, 2}>
# a: "cool 1"
# b: "cool 2"
# c: "cool 2"
# Loading for #<Set: {4}>
# d: "cool 4"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment