-
Notifications
You must be signed in to change notification settings - Fork 32
/
cacher.rb
71 lines (57 loc) · 1.78 KB
/
cacher.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
68
69
70
71
# frozen_string_literal: true
module GraphQL
module FragmentCache
using Ext
class WriteError < StandardError
attr_reader :key, :value, :original_error
def initialize(original_error, key, value)
@original_error = original_error
@key = key
@value = value
super(original_error.message)
end
end
class WriteMultiError < StandardError
attr_reader :values, :original_error
def initialize(original_error, values)
@original_error = original_error
@values = values
super(original_error.message)
end
end
# Saves resolved fragment values to cache store
module Cacher
class << self
def call(query)
return unless query.context.fragments?
if FragmentCache.cache_store.respond_to?(:write_multi)
batched_persist(query)
else
persist(query)
end
end
private
def batched_persist(query)
select_valid_fragments(query).group_by(&:options).each do |options, group|
hash = group.map { |fragment| [fragment.cache_key, fragment.value] }.to_h
begin
FragmentCache.cache_store.write_multi(hash, options)
rescue => e
raise WriteMultiError.new(e, hash)
end
end
end
def persist(query)
select_valid_fragments(query).each do |fragment|
FragmentCache.cache_store.write(fragment.cache_key, fragment.value, fragment.options)
rescue => e
raise WriteError.new(e, fragment.cache_key, fragment.value), e
end
end
def select_valid_fragments(query)
query.context.fragments.select(&:with_final_value?)
end
end
end
end
end