使用分页(kaminari)时如何使用dalli实现片段缓存?

编程入门 行业动态 更新时间:2024-10-09 16:25:49
本文介绍了使用分页(kaminari)时如何使用dalli实现片段缓存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我知道 dalli(缓存)是非常强大的插件,可以增强静态页面的性能.但是经常更新的带有分页的动态页面呢?设置 dalli 的正确方法是什么?

我遇到的一个问题,例如:dalli 在使用分页时将不同的 params[:page] 识别为同一页面:(

当两者都使用 dalli 时,你们会如何设计系统

  • 经常更新的页面
  • 不会经常更新的页面

例如.我有 4 个模型,例如 User、Community、Topic 和 Comment(定义了社区和主题的多态.他们可以在#show pages中创建或显示)

就像

  • 社区 > (has_many) > 主题 > (has_many) > 评论
  • 社区 > (has_many) > 评论
  • 它们都属于用户(创建者)

我目前的代码就是这样(这有点长.抱歉)我在使用缓存时遇到分页问题...

-------------------------------------设置-----------------------------------------

config/environments/development.rb

config.think_all_requests_local = trueconfig.action_controller.perform_caching = trueconfig.cache_store = :dalli_store

routes.rb

资源:社区做资源:主题做资源:评论做结尾结尾

--------------------------------------社区-----------------------------------------

controllers/communities_controller.rb#index&show

caches_page :showcaches_action :edit, :new定义索引....if params[:sort] == 'new'@communities = Community.scoped.page(params[:page]).order("created_at DESC")elsif params[:sort] = '流行'@communities = Community.scoped.page(params[:page]).order("follow_count DESC")elsif params[:sort] = '声誉'@communities = Community.scoped.page(params[:page]).order("reputation_count DESC")别的@communities = Community.scoped.page(params[:page]).order("created_at DESC")结尾....结尾高清秀@community = Community.find(params[:community_id])@comments @communityments.page(params[:page]@topics = @community.topics.limit(10)结尾

views/communities/index.html.erb注意:但是,即使我移动到下一个 params[:page]:( 似乎缓存将不同的页面识别为相同的内容...

#here, url 可能类似于 example/communities?utf8=✓&location=14&genre=3&search=strawberry但这将创建巨大的缓存宠物:(所以我想让它只在 params[:sort] 不为空时才起作用.因为,当 params[:sort] 不为空时,没有其他参数.它可能是这样的,example/communities?sort=new,example/communities?sort=popular,example/communities?sort=reputation...<% if params[:sort] %><% @key = "community_index_" + params[:sort] + params[:page] %><% cache(:controller => "communities", :action => "index", :action_suffix => @key) do %><%= page_entries_info(@communities, :entry_name => 'community').html_safe %>4%><% @communities.each 做 |community|%>社区%><%结束%><%结束%><%结束%>...

views/communities/show.html.erb

...<% @key = params[:community_name] + "_community_show_information" %><% cache(:controller => "communities", :action => "show", :action_suffix => @key) do %><h2>信息</h2><div class="社区信息"><%=呈现'社区/信息'%>

<%结束%><% @key = params[:community_name] + "_community_show_wall_" + params[:page] + %><% cache(:controller => "communities", :action => "show", :action_suffix => @key) do %>4%><h2>主题</h2><div class="WallInformation"><% @comments.eager.recent.each 做 |comment|%>评论 %><%结束%>

<%结束%><% @key = params[:community_name] + "_community_show_topics" %><% cache(:controller => "communities", :action => "show", :action_suffix => @key) do %><h2>主题</h2><div class="TopicInformation"><% @topics.eager.recent.each 做 |topic|%>主题%><%结束%>

<%结束%>...

models/community_sweeper.rb

class CommunitySweeper 'index', :only_path => true) + '?????(所有与社区相关的缓存#index)')expire_fragment(url_for(:action => 'show', :only_path => true) + '?????(与特定社区相关的缓存#show)')结尾结尾结尾

-------------------------------------主题-----------------------------------------

controllers/topics_controller.rb#index&show

caches_page :showcaches_action :edit, :new定义索引....@community = Community.find(params[:community_id])@topics = @community.topics.page(params[:page]....结尾高清秀@topic = Topic.find(params[:id])@comments = @topicments.page(params[:page]结尾

views/topics/index.html.erb

...<% @key = params[:community_id] + "_topic_index_" + params[:page] %><% cache(:controller => "topics", :action => "index", :action_suffix => @key) do %><%= page_entries_info(@communities, :entry_name => 'community').html_safe %>4%><% @communities.each 做 |community|%>社区%><%结束%><%结束%><%结束%>...

views/topics/show.html.erb

...<% @key = params[:community_name] + "_topic_show_" + params[:id] + "_comments" + params[:page] %><% cache(:controller => "topics", :action => "show", :action_suffix => @key) do %>4%><%= page_entries_info(@comments, :entry_name => 'comment').html_safe %><h2>评论</h2><div class="CommentInformation"><% @comments.each 做 |comment|%><%= 渲染 'topics/comment', :comment =>评论 %><%结束%>

<%结束%>...

models/topic_sweeper.rb

class TopicSweeper 'index', :only_path => true) + '?????(所有与主题相关的缓存#index)')expire_fragment(url_for(:action => 'show', :only_path => true) + '?????(与特定主题相关的缓存#show)')结尾结尾

-------------------------------------评论-----------------------------------------

models/comment_sweeper.rb

class CommentSweeper <ActionController::Caching::Sweeper观察评论def after_save(记录)expire_fragment(url_for(:action => 'index', :only_path => true) + '?????(所有与主题相关的缓存#index)')expire_fragment(url_for(:action => 'show', :only_path => true) + '?????(与特定主题相关的缓存#show)')结尾结尾

解决方案

我继续我对

的回答

我应该如何为包含大量内容更新的动态页面设置 dalli?

请注意,我不是专家,但我确实尝试了您的方法并放弃了它,因为随着我的应用程序的增长它变得越来越复杂,我选择了上一个问题中提到的基于缓存键片段的方法.有几点需要牢记.

  • 缓存清除程序方法要求您在更改应用程序时确保清除程序是最新的,这意味着额外的维护和测试工作.

  • 在动态应用程序中,您可能无法轻松缓存整个页面,尤其是当视图显示来自多个模型的信息时.

  • 除非 page 参数成为缓存键的一部分,否则您将无法处理分页问题.

  • 当您的缓存已满时,memcached 会在放入新缓存片段时删除最少使用/最旧的缓存项.

  • 因此,当您的模型发生变化时,您只需推送新的缓存片段并让 memcached 清除旧的过时缓存项目就没有问题.

  • 因此,视图中的片段缓存可能是最简单的解决方案,因为它将处理分页,而您不必处理手动缓存失效

    所以看看你的一个观点,我可能会做的是

    <%= page_entries_info(@communities, :entry_name => 'community').html_safe %>4%><% @communities.each 做 |community|%><% cache(community, :suffix => "community_index") 做社区%><%结束%><%结束%><%结束%>

    我所做的是缓存每个社区记录的渲染,分页变得无关紧要

    I know dalli (caching) is pretty powerful plugin to enhance performance for static pages. But what about dynamic pages with pagination, which are updated quite often? What is the correct way to set up dalli?

    One problem I've encountered for example: dalli recognizes different params[:page] as the same page when using pagination:(

    How would you guys design the system when using dalli for both

    • the page that gets updated so often
    • the page that won't be updated so often

    For example. I have 4 models such as User, Community, Topic, and Comment(defined Polymorphic to both Community, and Topic. They can be created or shown in #show pages)

    It's like

    • Community > (has_many) > Topics > (has_many) > Comments
    • Community > (has_many) > Comments
    • All of them belongs to user(creator)

    My current codes are just like this(This is quite bit long. Sorry about that) I'm facing the pagination problem when using caching...

    -------------------------------------Settings----------------------------------------

    config/environments/development.rb

    config.consider_all_requests_local = true config.action_controller.perform_caching = true config.cache_store = :dalli_store

    routes.rb

    resources :communities do resources :topics do resources :comments do end end

    -------------------------------------Community----------------------------------------

    controllers/communities_controller.rb#index&show

    caches_page :show caches_action :edit, :new def index .... if params[:sort] == 'new' @communities = Community.scoped.page(params[:page]).order("created_at DESC") elsif params[:sort] = 'popular' @communities = Community.scoped.page(params[:page]).order("follow_count DESC") elsif params[:sort] = 'reputation' @communities = Community.scoped.page(params[:page]).order("reputation_count DESC") else @communities = Community.scoped.page(params[:page]).order("created_at DESC") end .... end def show @community = Community.find(params[:community_id]) @comments @communityments.page(params[:page] @topics = @community.topics.limit(10) end

    views/communities/index.html.erb note: However, the content will be the same even if I move to next params[:page]:( It seems caching recognize different page as the same contents...

    #here, the url will could be something like this example/communities?utf8=✓&location=14&genre=3&search=strawberry But this is going to create gigantic petterns of the caches:( So I want to make it work only when params[:sort] was not empty. Because, no other parameters come with when params[:sort] is not empty. It could be like, example/communities?sort=new, example/communities?sort=popular, example/communities?sort=reputation ... <% if params[:sort] %> <% @key = "community_index_" + params[:sort] + params[:page] %> <% cache(:controller => "communities", :action => "index", :action_suffix => @key) do %> <%= page_entries_info(@communities, :entry_name => 'community').html_safe %> <%= paginate @communities, :window => 4 %> <% @communities.each do |community| %> <%= render 'communities/community', :community => community %> <% end %> <% end %> <% end %> ...

    views/communities/show.html.erb

    ... <% @key = params[:community_name] + "_community_show_information" %> <% cache(:controller => "communities", :action => "show", :action_suffix => @key) do %> <h2>Information</h2> <div class="CommunityInformation"> <%= render 'communities/information'%> </div> <% end %> <% @key = params[:community_name] + "_community_show_wall_" + params[:page] + %> <% cache(:controller => "communities", :action => "show", :action_suffix => @key) do %> <%= paginate @comments, :window => 4 %> <h2>Topic</h2> <div class="WallInformation"> <% @comments.eager.recent.each do |comment| %> <%= render 'communities/comment', :comment => comment %> <% end %> </div> <% end %> <% @key = params[:community_name] + "_community_show_topics" %> <% cache(:controller => "communities", :action => "show", :action_suffix => @key) do %> <h2>Topic</h2> <div class="TopicInformation"> <% @topics.eager.recent.each do |topic| %> <%= render 'communities/topic', :topic => topic %> <% end %> </div> <% end %> ...

    models/community_sweeper.rb

    class CommunitySweeper < ActionController::Caching::Sweeper observe Community def after_save(record) expire_fragment(url_for(:action => 'index', :only_path => true) + '?????(all the caches related to the community#index)') expire_fragment(url_for(:action => 'show', :only_path => true) + '?????(the cache related to the particular community#show)') end end end

    -------------------------------------Topic----------------------------------------

    controllers/topics_controller.rb#index&show

    caches_page :show caches_action :edit, :new def index .... @community = Community.find(params[:community_id]) @topics = @community.topics.page(params[:page] .... end def show @topic = Topic.find(params[:id]) @comments = @topicments.page(params[:page] end

    views/topics/index.html.erb

    ... <% @key = params[:community_id] + "_topic_index_" + params[:page] %> <% cache(:controller => "topics", :action => "index", :action_suffix => @key) do %> <%= page_entries_info(@communities, :entry_name => 'community').html_safe %> <%= paginate @communities, :window => 4 %> <% @communities.each do |community| %> <%= render 'communities/community', :community => community %> <% end %> <% end %> <% end %> ...

    views/topics/show.html.erb

    ... <% @key = params[:community_name] + "_topic_show_" + params[:id] + "_comments" + params[:page] %> <% cache(:controller => "topics", :action => "show", :action_suffix => @key) do %> <%= paginate @comments, :window => 4 %> <%= page_entries_info(@comments, :entry_name => 'comment').html_safe %> <h2>Comment</h2> <div class="CommentInformation"> <% @comments.each do |comment| %> <%= render 'topics/comment', :comment => comment %> <% end %> </div> <% end %> ...

    models/topic_sweeper.rb

    class TopicSweeper < ActionController::Caching::Sweeper observe Topic def after_save(record) expire_fragment(url_for(:action => 'index', :only_path => true) + '?????(all the caches related to the topic#index)') expire_fragment(url_for(:action => 'show', :only_path => true) + '?????(the cache related to the particular topic#show)') end end

    -------------------------------------Comment----------------------------------------

    models/comment_sweeper.rb

    class CommentSweeper < ActionController::Caching::Sweeper observe Comment def after_save(record) expire_fragment(url_for(:action => 'index', :only_path => true) + '?????(all the caches related to the topic#index)') expire_fragment(url_for(:action => 'show', :only_path => true) + '?????(the cache related to the particular topic#show)') end end

    解决方案

    I am following on on from my answer to

    How should I set up dalli for a dynamic page with lots of content updates?

    Please note that I am not an expert but I did try your approach and abandoned it as it just kept getting more and more complex as my application grew and I went for the cache key fragment based approach mentioned in the last question. There are a few things to bear in mind.

  • The cache sweeper approach requires you to make sure that the sweeper is up to date as you make changes to your application which means extra maintenance and testing work.

  • In a dynamic application you probably wont be able to easily cache whole pages especially if the views show information from many models.

  • You wont be able to deal with the paging issue unless the page parameter becomes part of your cache keys.

  • When your cache gets full, memcached will simply remove the least used / oldest cache items when putting in a new cache fragment.

  • So there is no issue with you just pushing in a new cache fragments when your models change and letting memcached clear out the old out of date cache items.

  • Therefore fragment caching in your views will probably be the easiest solution as it will deal with paging and you wont have to deal with manual cache invalidation

    So looking at one of your views, what I might do is

    <% if params[:sort] %> <%= page_entries_info(@communities, :entry_name => 'community').html_safe %> <%= paginate @communities, :window => 4 %> <% @communities.each do |community| %> <% cache(community, :suffix => "community_index") do <%= render 'communities/community', :community => community %> <% end %> <% end %> <% end %>

    What I have done is cache the rendering of each community record and paging becomes irrelavent

    更多推荐

    使用分页(kaminari)时如何使用dalli实现片段缓存?

    本文发布于:2023-11-30 21:48:20,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1651574.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:分页   缓存   如何使用   片段   kaminari

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!