-
Notifications
You must be signed in to change notification settings - Fork 52
/
batch_loader.rb
68 lines (56 loc) · 1.41 KB
/
batch_loader.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
require "batch_loader/version"
require "batch_loader/executor_proxy"
require "batch_loader/middleware"
class BatchLoader
NoBatchError = Class.new(StandardError)
BatchAlreadyExistsError = Class.new(StandardError)
def self.for(item)
new(item: item)
end
def self.sync!(value)
case value
when Array
value.map! { |v| sync!(v) }
when Hash
value.each { |k, v| value[k] = sync!(v) }
when BatchLoader
sync!(value.sync)
else
value
end
end
attr_reader :item, :batch_block, :cache
def initialize(item:)
@item = item
end
def batch(cache: true, &batch_block)
raise BatchAlreadyExistsError if @batch_block
@cache = cache
@batch_block = batch_block
executor_proxy.add(item: item)
self
end
def load(item, value)
executor_proxy.load(item: item, value: value)
end
def sync
unless executor_proxy.value_loaded?(item: item)
batch_block.call(executor_proxy.list_items, self)
executor_proxy.delete_items
end
result = executor_proxy.loaded_value(item: item)
purge_cache unless cache
result
end
private
def executor_proxy
@executor_proxy ||= begin
raise NoBatchError.new("Please provide a batch block first") unless batch_block
BatchLoader::ExecutorProxy.new(&batch_block)
end
end
def purge_cache
executor_proxy.unload_value(item: item)
executor_proxy.add(item: item)
end
end