Skip to content

Commit

Permalink
trefactor batch_cache code
Browse files Browse the repository at this point in the history
  • Loading branch information
LcpMarvel committed Dec 20, 2015
1 parent 320a1ee commit 975c975
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 20 deletions.
41 changes: 25 additions & 16 deletions lib/active_model/serializer/adapter/attributes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,31 @@ def fragment_cache(cached_hash, non_cached_hash)
private

def serializable_hash_for_collection(options)
if options[:batch_cache].blank? && ActiveModelSerializers.config.cache_store.present?
keys = CachedSerializer.object_cache_keys(serializer, @include_tree)
if keys.present?
values = ActiveModelSerializers.config.cache_store.read_multi(*keys)

options.merge!(batch_cache: values)
end
end
options.merge!(batch_cache(options))

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

# Read cache from cache_store, and set those into options[:batch_cache]
# @return [Hash] a batch of cache
def batch_cache(options)
return {} if options[:batch_cache].present? || ActiveModelSerializers.config.cache_store.blank?

keys = CachedSerializer.object_cache_keys(serializer, @include_tree)

return {} if keys.blank?

{ batch_cache: ActiveModelSerializers.config.cache_store.read_multi(*keys) }
end

# Get attributes from options[:batch_cache].
# @return [Hash] cached attributes
def batch_cache_for(cached_serializer, options)
return unless options[:batch_cache].present?

options[:batch_cache][cached_serializer.cache_key]
end

def serializable_hash_for_single_resource(options)
resource = resource_object_for(options)
relationships = resource_relationships(options)
Expand Down Expand Up @@ -65,15 +78,11 @@ def include_meta(json)
end

def resource_object_for(options)
if options[:batch_cache].present?
cache_key = CachedSerializer.new(serializer).cache_key

value = options[:batch_cache][cache_key]

return value if value.present?
end
cached_serializer = CachedSerializer.new(serializer)
batch_cached_attributes = batch_cache_for(cached_serializer, options)
return batch_cached_attributes if batch_cached_attributes.present?

cache_check(serializer) do
cached_serializer.cache_check(self) do
serializer.attributes(options[:fields])
end
end
Expand Down
12 changes: 9 additions & 3 deletions lib/active_model/serializer/adapter/cached_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@ def fragment_cached?
end

def cache_key
return @cache_key if defined?(@cache_key)

parts = []
parts << object_cache_key
parts << @klass._cache_digest unless @klass._cache_options && @klass._cache_options[:skip_digest]
parts.join('/')
@cache_key = parts.join('/')
end

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

# collection_serializer with the include_tree
# find all cache_key for the collection_serializer
# @param collection_serializer
# @param include_tree
# @return [Array] all cache_key of collection_serializer
def self.object_cache_keys(serializers, include_tree)
cache_keys = []

Expand All @@ -58,9 +63,10 @@ def self.object_cache_keys(serializers, include_tree)
end
end

cache_keys.compact
cache_keys.compact.uniq
end

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

Expand Down
20 changes: 19 additions & 1 deletion test/serializers/cache_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,30 @@ def test_object_cache_keys

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

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

def test_batch_cache
serializer = CollectionSerializer.new([@comment, @comment])

Timecop.freeze(Time.now) do
render_object_with_cache(@comment)

batch_cache = ActiveModel::Serializer::Adapter::Attributes.new(serializer).send(:batch_cache, {})[:batch_cache]

assert_equal batch_cache[@comment.cache_key], Comment.new(id: 1, body: 'ZOMG A COMMENT').attributes
assert_equal batch_cache[@comment.post.cache_key], Post.new(id: 'post', title: 'New Post', body: 'Body').attributes

writer = @comment.post.blog.writer
writer_cache_key = "writer/#{writer.id}-#{writer.updated_at.strftime("%Y%m%d%H%M%S%9N")}"

assert_equal batch_cache[writer_cache_key], Author.new(id: 'author', name: 'Joao M. D. Moura').attributes
end
end

def test_serializer_file_path_on_nix
path = '/Users/git/emberjs/ember-crm-backend/app/serializers/lead_serializer.rb'
caller_line = "#{path}:1:in `<top (required)>'"
Expand Down

0 comments on commit 975c975

Please sign in to comment.