Skip to content
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

Implement Russia Doll Cache #1045

Open
joaomdmoura opened this issue Aug 10, 2015 · 5 comments
Open

Implement Russia Doll Cache #1045

joaomdmoura opened this issue Aug 10, 2015 · 5 comments

Comments

@joaomdmoura
Copy link
Member

tl;dr

Implementing a Russia Doll Cache that will enable us to increase our performance. fetch-multi is an awesome plus


We have already implemented cache and fragment cache on 0.10.x, but we still need to make it better by implementing a Russia Doll Cache that will enable us to increase our performance when serializer different set of a resource.


related to issues:

  • ...

related to PRs:

  • ...
@mib32
Copy link

mib32 commented Aug 18, 2015

Hey @joaomdmoura ! Thanks for all your work.
Could you elaborate, is this related to my desire to have separate cache sources, like in next gist.
The FullMarker inherits from marker, and it also inherits it's cache.

class FullMarkerSerializer < MarkerSerializer
  attributes :name, :special_offer
  belongs_to :category
  cache key: 'business_full_markers', only: [:name, :special_offer, :category]
  cache key: 'business_markers', except: [:name, :special_offer, :category]

  def special_offer
    object.sale.special_offer.try(:description)
  end

end

I'm correct that now it doesn't work?

@joaomdmoura
Copy link
Member Author

No, @mib32 the Russian Doll cache is a technique of nesting fragment caches to maximize cache hits. By nesting fragment caches, it ensures that caches can be reused even when content changes.
When a change occurs to the top-most fragment cache, only that cache must be expired. Every nested cache of the parent can be reused, which provides a significant performance increase.

I'll need to check but what you posted might work now, not because of the inheritance, but because the cache is based on the model, and not on the serializer, anyway, I'm not so sure,I've to double check.

@passalini
Copy link

@joaomdmoura I'm trying to use this technic to improve the response time and the only way that I thought was caching the as_json from the adapter. This idea came up after I read Hawkins's posts and changed that a little bit.

Right know I have something like this:

class ActiveModel::Serializer::Adapter::FlattenJsonWithCustomCache < ActiveModel::Serializer::Adapter::FlattenJson
  def as_json(options = nil)
    tags = serializer.try(:cache_tags)

    # This `cache_key` was overwritten
    Rails.cache.fetch(serializer.cache_key, tag: tags) do
      super
    end
  end
end
# initializers/ams.rb
ActiveModel::Serializer.config.adapter = ActiveModel::Serializer::Adapter::FlattenJsonWithCustomCache

ps: I added cashier to expire that cache by tag because I have many relations by object and put a touch at all relations (to create an auto expire key) isn't a good idea for my case.

I hope that it helps with something and if someone has ideas to improve this workaround I will be very happy! =D

@passalini
Copy link

@joaomdmoura I had to change the cache to the serializable_hash method. I did it to use russian doll with collection objects, with it we can cache (russian doll) object by object... We can do some code to russian doll all objects in one cache, is just use the code above with my new approach

@bf4
Copy link
Member

bf4 commented Feb 11, 2016

ref: #1372

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants