Skip to content

Commit 1072857

Browse files
committed
trefactor batch_cache code
1 parent 1517381 commit 1072857

File tree

3 files changed

+53
-20
lines changed

3 files changed

+53
-20
lines changed

lib/active_model/serializer/adapter/attributes.rb

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,31 @@ def fragment_cache(cached_hash, non_cached_hash)
2424
private
2525

2626
def serializable_hash_for_collection(options)
27-
if options[:batch_cache].blank? && ActiveModelSerializers.config.cache_store.present?
28-
keys = CachedSerializer.object_cache_keys(serializer, @include_tree)
29-
if keys.present?
30-
values = ActiveModelSerializers.config.cache_store.read_multi(*keys)
31-
32-
options.merge!(batch_cache: values)
33-
end
34-
end
27+
options.merge!(batch_cache(options))
3528

3629
serializer.map { |s| Attributes.new(s, instance_options).serializable_hash(options) }
3730
end
3831

32+
# Read cache from cache_store, and set those into options[:batch_cache]
33+
# @return [Hash] a batch of cache
34+
def batch_cache(options)
35+
return {} if options[:batch_cache].present? || ActiveModelSerializers.config.cache_store.blank?
36+
37+
keys = CachedSerializer.object_cache_keys(serializer, @include_tree)
38+
39+
return {} if keys.blank?
40+
41+
{ batch_cache: ActiveModelSerializers.config.cache_store.read_multi(*keys) }
42+
end
43+
44+
# Get attributes from options[:batch_cache].
45+
# @return [Hash] cached attributes
46+
def batch_cache_for(cached_serializer, options)
47+
return unless options[:batch_cache].present?
48+
49+
options[:batch_cache][cached_serializer.cache_key]
50+
end
51+
3952
def serializable_hash_for_single_resource(options)
4053
resource = resource_object_for(options)
4154
relationships = resource_relationships(options)
@@ -65,15 +78,11 @@ def include_meta(json)
6578
end
6679

6780
def resource_object_for(options)
68-
if options[:batch_cache].present?
69-
cache_key = CachedSerializer.new(serializer).cache_key
70-
71-
value = options[:batch_cache][cache_key]
72-
73-
return value if value.present?
74-
end
81+
cached_serializer = CachedSerializer.new(serializer)
82+
batch_cached_attributes = batch_cache_for(cached_serializer, options)
83+
return batch_cached_attributes if batch_cached_attributes.present?
7584

76-
cache_check(serializer) do
85+
cached_serializer.cache_check(self) do
7786
serializer.attributes(options[:fields])
7887
end
7988
end

lib/active_model/serializer/adapter/cached_serializer.rb

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@ def fragment_cached?
2828
end
2929

3030
def cache_key
31+
return @cache_key if defined?(@cache_key)
32+
3133
parts = []
3234
parts << object_cache_key
3335
parts << @klass._cache_digest unless @klass._cache_options && @klass._cache_options[:skip_digest]
34-
parts.join('/')
36+
@cache_key = parts.join('/')
3537
end
3638

3739
def object_cache_key
@@ -40,7 +42,10 @@ def object_cache_key
4042
(@klass._cache_key) ? "#{@klass._cache_key}/#{@cached_serializer.object.id}-#{object_time_safe}" : @cached_serializer.object.cache_key
4143
end
4244

43-
# collection_serializer with the include_tree
45+
# find all cache_key for the collection_serializer
46+
# @param collection_serializer
47+
# @param include_tree
48+
# @return [Array] all cache_key of collection_serializer
4449
def self.object_cache_keys(serializers, include_tree)
4550
cache_keys = []
4651

@@ -58,9 +63,10 @@ def self.object_cache_keys(serializers, include_tree)
5863
end
5964
end
6065

61-
cache_keys.compact
66+
cache_keys.compact.uniq
6267
end
6368

69+
# @return [String, nil] the cache_key of the serializer or nil
6470
def self.object_cache_key(serializer)
6571
return unless serializer.present? && serializer.object.present?
6672

test/serializers/cache_test.rb

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,12 +155,30 @@ def test_object_cache_keys
155155

156156
actual = Serializer::Adapter::CachedSerializer.object_cache_keys(serializer, include_tree)
157157

158-
assert_equal actual.size, 6
158+
assert_equal actual.size, 3
159159
assert actual.any? { |key| key == 'comment/1' }
160160
assert actual.any? { |key| key =~ %r{post/post-\d+} }
161161
assert actual.any? { |key| key =~ %r{writer/author-\d+} }
162162
end
163163

164+
def test_batch_cache
165+
serializer = CollectionSerializer.new([@comment, @comment])
166+
167+
Timecop.freeze(Time.now) do
168+
render_object_with_cache(@comment)
169+
170+
batch_cache = ActiveModel::Serializer::Adapter::Attributes.new(serializer).send(:batch_cache, {})[:batch_cache]
171+
172+
assert_equal batch_cache[@comment.cache_key], Comment.new(id: 1, body: 'ZOMG A COMMENT').attributes
173+
assert_equal batch_cache[@comment.post.cache_key], Post.new(id: 'post', title: 'New Post', body: 'Body').attributes
174+
175+
writer = @comment.post.blog.writer
176+
writer_cache_key = "writer/#{writer.id}-#{writer.updated_at.strftime("%Y%m%d%H%M%S%9N")}"
177+
178+
assert_equal batch_cache[writer_cache_key], Author.new(id: 'author', name: 'Joao M. D. Moura').attributes
179+
end
180+
end
181+
164182
def test_serializer_file_path_on_nix
165183
path = '/Users/git/emberjs/ember-crm-backend/app/serializers/lead_serializer.rb'
166184
caller_line = "#{path}:1:in `<top (required)>'"

0 commit comments

Comments
 (0)