0

現在のユーザーがフォローしているユーザーからのイベントの動的フィードがあり、パーシャルはすべてmemcachedですが、フィード自体に対しても実行したいと思います。私の懸念は、これをmemcacheすると、一意のユーザーごとに動的ではなく、キャッシュへの最初の書き込みに基づいてすべてのユーザーに同じものが表示されることです。

フィードと@followingをmemcacheするにはどうすればよいですか?現在のユーザーが別のユーザーをフォローしている場合、どうすれば更新できますか?<%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>
4

1 に答える 1

0

無関係ですが、それはあなたの見解ではあまりにも多くのモデルコード/SQLです。それらをクラスメソッドまたはスコープにパッケージ化します。

キャッシングに関しては、すべてのユーザーに同じものを見せたくない場合は、ユーザーごとにキャッシュキーを変える必要があります。これを行う1つの方法は、オプションを渡すことaction_suffixです。これにより、キャッシュキーの生成に使用されるデータが追加されます(デフォルトでは、コントローラーとアクションのみです)。この一部として現在のユーザーIDを含めると、キャッシュはユーザーごとに実行されます。コントローラ、アクション、アクションのサフィックスから作成するのではなく、任意のキャッシュキーを持つ文字列をユーザーに渡すこともできます。

キャッシュの有効期限は、コンピュータサイエンスで難しい2つのことの1つと言われています。少なくとも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変更されるため(変更されるため)、古いキャッシュデータは使用されません。

于 2012-10-26T00:41:34.137 に答える