Memcached动态Feed?

时间:2012-10-26 00:10:30

标签: ruby-on-rails ruby-on-rails-3 caching memcached

我有来自当前用户所遵循的用户的事件的动态馈送,部分都是memcached,但我也想为馈送本身做这件事。我担心的是,如果我记得这个,它将基于第一次写入缓存而不是每个唯一用户的动态,为每个用户显示相同的内容。

我如何记忆Feed和@following?如果当前用户跟随另一个用户,如何更新它?我假设我不能用<%cache“feed”do%>

包装它

注意:使用Memcached和Dalli

<% @following = current_user.following.collect {|f| f["id"]} %>
<div class='content'>
<% unless Rsvp.where(:voter_id => @following, :status => 'going').where("start_time > ? AND start_time < ?", Time.now, Time.now.strftime('%Y-%m-%d 23:59:59.000000')).order("count_all desc").count(:group => :event_id).collect { |f| f[0] }.count == 0 %>
          <div class='date_bar_container'><div class='date_bar'>Today</div></div>
          <div class='content_wrapper'>
    <%= render :partial => 'events/event', :collection => Event.where(:id =>  Rsvp.where(:event_id => Rsvp.where(:voter_id => @following, :status => 'going').where("start_time > ? AND start_time < ?", Time.now.strftime('%Y-%m-%d 00:00:00.000000'), Time.now.strftime('%Y-%m-%d 23:59:59.000000')).order("count_all desc").count(:group => :event_id).collect { |f| f[0] }).select("DISTINCT event_id").collect(&:event_id)).order('start_time asc')%>
          </div>
<% end %>

<% unless Rsvp.where(:voter_id => @following, :status => 'going').where("start_time > ? AND start_time < ?", (Time.now + 1.day).strftime('%Y-%m-%d 00:00:00.000000'), (Time.now + 1.day).strftime('%Y-%m-%d 23:59:59.000000')).order("count_all desc").count(:group => :event_id).collect { |f| f[0] }.count == 0%>
          <div class='date_bar_container'><div class='date_bar'>Tomorrow</div></div>
          <div class='content_wrapper'>
    <%= render :partial => 'events/event', :collection => Event.where(:id =>  Rsvp.where(:event_id => Rsvp.where(:voter_id => @following, :status => 'going').where("start_time > ? AND start_time < ?", (Time.now + 1.day).strftime('%Y-%m-%d 00:00:00.000000'), (Time.now + 1.day).strftime('%Y-%m-%d 23:59:59.000000')).order("count_all desc").count(:group => :event_id).collect { |f| f[0] }).select("DISTINCT event_id").collect(&:event_id)).order('start_time asc')%>
    </div>
    <% end %>

<% (2..15).each do |f| %>
    <% unless Rsvp.where(:voter_id => @following, :status => 'going').where("start_time > ? AND start_time < ?", (Time.now + f.day).strftime('%Y-%m-%d 00:00:00.000000'), (Time.now + f.day).strftime('%Y-%m-%d 23:59:59.000000')).order("count_all desc").count(:group => :event_id).collect { |f| f[0] }.count == 0 %>
              <div class='date_bar_container'><div class='date_bar'><%= dayofweek((Time.now + f.day).wday) %>, <%= month((Time.now + f.day).month) %> <%= (Time.now + f.day).day %>, 2012</div></div>
              <div class='content_wrapper'>
        <%= render :partial => 'events/event', :collection => Event.where(:id =>  Rsvp.where(:event_id => Rsvp.where(:voter_id => @following, :status => 'going').where("start_time > ? AND start_time < ?", (Time.now + f.day).strftime('%Y-%m-%d 00:00:00.000000'), (Time.now + f.day).strftime('%Y-%m-%d 23:59:59.000000')).order("count_all desc").count(:group => :event_id).collect { |f| f[0] }).select("DISTINCT event_id").collect(&:event_id)).order('start_time asc')%>
         </div>
        <% end %>
<% end %>
</div>

1 个答案:

答案 0 :(得分:0)

不相关,但是你的视图中的模型代码/ sql太多了。将它们打包在类方法或范围中。

关于缓存,如果您不希望每个用户看到相同的内容,那么您需要为每个用户设置不同的缓存键。执行此操作的一种方法是传递action_suffix选项,该选项会添加用于生成缓存键的数据(默认情况下,它只是控制器和操作)。如果您将当前用户ID作为其中的一部分包含在内,则将基于每个用户进行缓存。您还可以将带有任意缓存键的字符串传递给用户,而不是从控制器,操作和操作后缀构建它。

缓存到期被认为是计算机科学中的两个难题之一。至少有3个选项:

  • 当您缓存某些内容时,请将expires_in设置为适当的时间跨度。当基础数据更改不执行任何操作时:您接受用户看到的内容可能已过期,直到您设置的时间跨度。设置得很高,他们会长时间看到过时的数据,将它设置得太低,你就会丢掉可能保存的缓存数据。

例如:

 <% cache({:action_suffix => 'blah'}, :expires_in => 20.minutes  do %>
  ..
 <% end %>
  • 响应模型更改明确地使数据到期,例如通过清扫器。记住所有可能发生的地方并记得在添加新东西时增加清扫工具可能会很棘手

  • 使用分代缓存密钥:构建缓存密钥,以便在基础数据更改时缓存密钥也会发生变化。一个非常简单的例子是,如果您正在缓存有关用户的信息页面。您可以将缓存键设置为user_#{user.id}_#{user.updated_at.to_i}(或等效地,user.cache_key)。当用户更改时,无论如何,您使用的缓存键也会更改(因为updated_at已更改),因此您将不会使用旧的缓存数据