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

Add multi-key caching support for collection blocks #111

Open
dasch opened this issue Nov 5, 2014 · 0 comments
Open

Add multi-key caching support for collection blocks #111

dasch opened this issue Nov 5, 2014 · 0 comments
Milestone

Comments

@dasch
Copy link
Contributor

dasch commented Nov 5, 2014

Since Curly has much more control of rendering when it takes place in a collection block, it should be possible to add smarter caching.

Given the template:

{{*comments}}
  {{body}}
{{/comments}}

... and presenter

class CommentPresenter < Curly::Presenter
  presents :comment

  def body
    @comment.body
  end

  def cache_key
    @comment
  end
end

... we should be able to generate Ruby that looks like this:

class Curly::RenderingContext
  attr_reader :presenter, :value

  def initialize(presenter, value)
    @presenter, @value = presenter, value
  end

  def cache_key
    @presenter.cache_key
  end
end

contexts = presenter.comments.map {|value|
  presenter = find_presenter_for(value) # pseudo code
  Curly::RenderingContext.new(presenter, value)
}

# `fetch_multi` does a multi-get to the cache backend, so the cached fragments
# will be fetched in parallel. It gets the cache key for each item by calling `cache_key`
# on the object. Any object that was not found in the cache will be yielded, and the
# block's return value will be saved in the cache.
Rails.cache.fetch_multi(*contexts) do |context|
  presenter = context.presenter
  # code goes here.
end

That way, if the template is rendered with Comment records A and B, the nested template will be rendered for each and the results stored in the cache. The next time, there's a new Comment record C, so we'll have to render A, B, and C, but A and B are already stored in the cache. We'll do a single GET to the backend, get the pre-rendered HTML for both A and B and a miss for C, so we'll render the nested template with C.

@dasch dasch added this to the v2.2 milestone Nov 5, 2014
@dasch dasch modified the milestones: v2.2, v2.4 Jan 9, 2015
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

1 participant