-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Fix up caching, especially fragment_cache #1781
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@@ -167,7 +167,7 @@ def serializable_hash(adapter_options = nil, options = {}, adapter_instance = se | |||
adapter_options ||= {} | |||
options[:include_directive] ||= ActiveModel::Serializer.include_directive_from_options(adapter_options) | |||
cached_attributes = adapter_options[:cached_attributes] ||= {} | |||
resource = cached_attributes(options[:fields], cached_attributes, adapter_instance) | |||
resource = fetch_attributes(options[:fields], cached_attributes, adapter_instance) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
otherwise we have a method that takes an argument (a hash) of the same name
self.class._cache_options ||= {} | ||
self.class._cache_options[:key] = self.class._cache_key if self.class._cache_key | ||
|
||
cached_serializer = _get_or_create_fragment_cached_serializer(serializer_class_name) | ||
cached_serializer = _get_or_create_fragment_cached_serializer | ||
cached_hash = ActiveModelSerializers::SerializableResource.new( | ||
object, | ||
serializer: cached_serializer, | ||
adapter: adapter_instance.class | ||
).serializable_hash |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
first pass at trying to remove the extra class failed, so I left it here
something like
cached_hash = cached_attributes.fetch(key) do
self.class.cache_store.fetch(key) do
attributes(fields, true)
end
end
(added cached_attributes
to the method params and removed all references to _fragmented
since there would be no more special classes)
It's funny when code coverage drops because there's less code :)
|
@@ -208,46 +199,44 @@ def object_cache_key(serializer, adapter_instance) | |||
end | |||
end | |||
|
|||
def cached_attributes(fields, cached_attributes, adapter_instance) | |||
### INSTANCE METHODS | |||
def fetch_attributes(fields, cached_attributes, adapter_instance) | |||
if self.class.cache_enabled? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could have klass = self.class
here since we use it many times.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah. Ultimately, I'd like to move a lot of this into a class that lives outside of the serializer. I started to write that and had a serializer_class
attribute
cache_check(adapter_instance) do | ||
attributes(fields) | ||
self.class.cache_store.fetch(key, self.class._cache_options) do | ||
attributes(fields, true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
passing true since we always want to reload the attributes in a cache block
- on association, fix up assocation logic - on attribute
Follows from #1766 and #1684
Benchmark results look good:. Fragment cache went from in #1766
1729 objs/iteration to 1382, and from 716 ips to 767.
It's still not as good as caching or non-caching, but at least we're
seeing some actual performance improvements now.
Related:
step 1 removing the non caching fragment cache class
step 2 removing the caching fragment serializer class