Google Groups Home
Help | Sign in
Conditional action-caching stops after a period of time
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  6 messages - Collapse all
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
spariam  
View profile
 More options May 8, 4:01 pm
From: spariam <doug.sparl...@gmail.com>
Date: Thu, 8 May 2008 13:01:27 -0700 (PDT)
Local: Thurs, May 8 2008 4:01 pm
Subject: Conditional action-caching stops after a period of time
I came across this earlier post, which describes a problem very
similar to the one I'm having now.

http://groups.google.com/group/acts_as_cached/browse_thread/thread/24...

Conditional caching seems to be working intermittently and it's only
on our production servers (six servers, I believe 3 mongrels each)
where the problem is showing up (it works fine in development and on
our staging server).

For example, on our main index page, a non-authenticated user should
get the action cached page, but it was obviously not using action
cache (we didn't even see an outbound call to the memcache server with
TCP dump).

I added one logging statement in the :cacheable? method and restarted
servers. At that point I was seeing what I expected and it looked like
action cached was now  working on the main index page (CACHEABLE is
the logger output).

Processing HomeController#index (for 64.79.204.16 at 2008-05-08
12:57:18) [GET]
  Session ID: d33f8f527f6c62cfdf425ad750e4beff
  Parameters: {"action"=>"index", "controller"=>"home"}
CACHEABLE: true
Filter chain halted as
[#<ActionController::Caching::Actions::ActionCacheFilter:0xb7309fc8
@actions={:index=>{:if=>:cacheable_not_logged_in?, :ttl=>1800
seconds}}, @options={:cache_path=>#<Proc:0xb7321dd0@/usr/local/sites/
www.somesite.com/releases/20080428165347/app/controllers/home_control...>}>]
rendered_or_redirected.
Filter chain halted as
[#<ActionController::Filters::ClassMethods::ProcWithCallFilter:
0xb7309c08 @filter=#<Proc:0xb7838760@/usr/lib/ruby/gems/1.8/gems/
actionpack-2.0.1/lib/action_controller/filters.rb:657>>]
did_not_yield.
Completed in 0.00212 (471 reqs/sec) | Rendering: 0.00006 (2%) | DB:
0.00000 (0%) 0 queries | 200 OK

After a half hour or so, I see less and less caching...either the
logging statement isn't there (like the condition is ignored), or it
is 'true' but still doesn't action cache (considerably more of the
former):

Processing HomeController#index (for 216.183.47.142 at 2008-05-08
13:51:07) [GET]
  Session ID: 8711c577dc9b74cfa3811fb2778a6aef
  Parameters: {"action"=>"index", "controller"=>"home"}
Rendering template within layouts/application
Rendering home/index
Completed in 0.13643 (7 reqs/sec) | Rendering: 0.13087 (95%) | DB:
0.00000 (0%) 18 queries | 200 OK

or

Processing HomeController#index (for 127.0.0.1 at 2008-05-08 13:52:23)
[GET]
  Session ID: 289cc740f8957738dccd22ce619357fe
  Parameters: {"action"=>"index", "controller"=>"home"}
CACHEABLE: true
Rendering template within layouts/application
Rendering home/welcome
Completed in 0.19601 (5 reqs/sec) | Rendering: 0.18986 (96%) | DB:
0.00000 (0%) 22 queries | 200 OK

Any insight or suggestions would be most helpful.

home controller:

caches_action :index => { :ttl => 30.minutes, :if
=> :cacheable? } , :cache_path => Proc.new {|c| c.flash_message }

(the flash_message was needed as when a user logged out, they go to
the home index page with a flash message)

app/controllers/application.rb

  def cacheable_not_logged_in?
    logged_in? ? false : true
  end

We're using Rails 2.0.01, cache_fu, and memcache-cilent.

Thanks...


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
spariam  
View profile
 More options May 8, 4:14 pm
From: spariam <doug.sparl...@gmail.com>
Date: Thu, 8 May 2008 13:14:40 -0700 (PDT)
Local: Thurs, May 8 2008 4:14 pm
Subject: Re: Conditional action-caching stops after a period of time
Sorry, couple typos:

app/controllers/application.rb

   def cacheable?
     logged_in? ? false : true
   end

Rails 2.0.1

On May 8, 3:01 pm, spariam <doug.sparl...@gmail.com> wrote:


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Sujal Shah  
View profile
 More options Jun 10, 10:29 pm
From: Sujal Shah <codesu...@gmail.com>
Date: Tue, 10 Jun 2008 22:29:08 -0400
Local: Tues, Jun 10 2008 10:29 pm
Subject: Re: [acts_as_cached] Re: Conditional action-caching stops after a period of time
spariam,

        I think you're running into the issue I just described in my previous  
email to the list.  I figured out what the line I asked about is for,  
and I'm working out a patch now.  Hopefully, this will solve your  
problem, too.

Sujal

On May 8, 2008, at 4:14 PM, spariam wrote:


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
dsparling  
View profile
 More options Jun 12, 11:08 am
From: dsparling <doug.sparl...@gmail.com>
Date: Thu, 12 Jun 2008 08:08:42 -0700 (PDT)
Local: Thurs, Jun 12 2008 11:08 am
Subject: Re: Conditional action-caching stops after a period of time
Sujal,

It is indeed something with that line you posted. I contacted the
author of the original post (Jan Prill) and he sent me his patch,
which I've been meaning to post here. I had to modify it slightly for
Rails 2 and I'm glad to say that cache_fu has been working great ever
since.

/vendor/plugins/cache_fu/lib/acts_as_cached/fragment_cache.rb
===============================================

module ActsAsCached
  module FragmentCache
    def self.setup!
      class << CACHE
        include Extensions
      end

      setup_fragment_cache_cache
      setup_rails_for_memcache_fragments
      setup_rails_for_action_cache_options
    end

    # add :ttl option to cache helper and set cache store memcache
object
    def self.setup_rails_for_memcache_fragments
      if ::ActionView.const_defined?(:Template)
        # Rails 2.1+
        ::ActionController::Base.cache_store = CACHE
      else
        # Rails < svn r8619
        ::ActionView::Helpers::CacheHelper.class_eval do
          def cache(name = {}, options = nil, &block)
            @controller.cache_erb_fragment(block, name, options)
          end
        end
        ::ActionController::Base.fragment_cache_store = CACHE
      end
    end

    def self.setup_fragment_cache_cache
      Object.const_set(:FragmentCacheCache, Class.new
{ acts_as_cached :store => CACHE })
    end

    # add :ttl option to caches_action on the per action level by
passing in a hash instead of an array
    #
    # Examples:
    #  caches_action :index                                       #
will use the default ttl from your memcache.yml, or 25 minutes
    #  caches_action :index => { :ttl => 5.minutes }              #
cache index action with 5 minute ttl
    #  caches_action :page, :feed, :index => { :ttl => 2.hours }  #
cache index action with 2 hours ttl, all others use default
    #
    def self.setup_rails_for_action_cache_options
      ::ActionController::Caching::Actions::ActionCacheFilter.class_eval
do
        # convert all actions into a hash keyed by action named, with
a value of a ttl hash (to match other cache APIs)
        def initialize(*actions, &block)
          if [].respond_to?(:extract_options!)
            #edge
            @options = actions.extract_options!
            @actions = actions.inject(@options.except(:cache_path)) do
|hsh, action|
              action.is_a?(Hash) ? hsh.merge(action) :
hsh.merge(action => { :ttl => nil })
            end
            @options.slice!(:cache_path)
          else
            #1.2.5
            @actions = actions.inject({}) do |hsh, action|
              action.is_a?(Hash) ? hsh.merge(action) :
hsh.merge(action => { :ttl => nil })
            end
          end
        end

        # override to skip caching/rendering on evaluated if option
        def before(controller)
          return unless @actions.include?
(controller.action_name.intern)

          # maintaining edge and 1.2.x compatibility with this branch
          # Jan Prill - added && false
          #if @options && false
          # Doug Sparling - removed false - false causing else to
always run - this may be
          # because Jan was using Rails 1.2?
          if @options
            action_cache_path =
ActionController::Caching::Actions::ActionCachePath.new(controller,
path_options_for(controller, @options))
          else
            action_cache_path =
ActionController::Caching::Actions::ActionCachePath.new(controller)
          end

          # should probably be like
ActiveRecord::Validations.evaluate_condition.  color me lazy.
          if conditional = @actions[controller.action_name.intern]
[:if]
            conditional = conditional.respond_to?(:call) ?
conditional.call(controller) : controller.send(conditional)
          end
          # Jan Prill - causing caching to stop after a period of
time?
          #...@actions.delete(controller.action_name.intern) if
conditional == false

          # Jan Prill - added if clause
          cache = controller.read_fragment(action_cache_path.path) if
conditional != false
          if cache && (conditional || conditional.nil?)
            controller.rendered_action_cache = true
            if method(:set_content_type!).arity == 2
              set_content_type!(controller,
action_cache_path.extension)
            else
              set_content_type!(action_cache_path)
            end
            controller.send(:render, :text => cache)
            false
          else
            # 1.2.x compatibility
            # Jan Prill added &&
            controller.action_cache_path = action_cache_path if
(controller.respond_to?(:action_cache_path) && conditional != false)
          end
        end

        # override to pass along the ttl hash
        def after(controller)
          # Jan Prill - added || controller.action_cache_path.nil?
          return if !...@actions.include?(controller.action_name.intern)
|| controller.rendered_action_cache ||
controller.action_cache_path.nil?
          # 1.2.x compatibility
          path = controller.respond_to?(:action_cache_path) ?
controller.action_cache_path.path :
ActionController::Caching::Actions::ActionCachePath.path_for(controller)
          controller.write_fragment(path, controller.response.body,
action_ttl(controller))
        end

        private
        def action_ttl(controller)
          @actions[controller.action_name.intern]
        end
      end
    end

    module Extensions
      def read(*args)
        return if ActsAsCached.config[:skip_gets]
        FragmentCacheCache.cache_store(:get, args.first)
      end

      def write(name, content, options = {})
        ttl = (options.is_a?(Hash) ? options[:ttl] : nil) ||
ActsAsCached.config[:ttl] || 25.minutes
        FragmentCacheCache.cache_store(:set, name, content, ttl)
      end
    end

    module DisabledExtensions
      def read(*args) nil end
      def write(*args) "" end
    end
  end
end

On Jun 10, 9:29 pm, Sujal Shah <codesu...@gmail.com> wrote:

...

read more »


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Sujal Shah  
View profile
 More options Jun 12, 1:43 pm
From: Sujal Shah <codesu...@gmail.com>
Date: Thu, 12 Jun 2008 13:43:18 -0400
Local: Thurs, Jun 12 2008 1:43 pm
Subject: Re: [acts_as_cached] Re: Conditional action-caching stops after a period of time
Yeah, this is one way to do it.  Might be better than my solution.  
Basically, he was trying to keep the app from writing out the current  
rendered view to the cache if the conditional was false.  Deleting it  
from @actions did it, but it also deleted it for any future calls (the  
filter is instantiated once and kept around rather than being created  
each request).

I made it explicit, just chucking the result of the conditional (true  
or false) to Thread.current[:do_cache] or something like that (don't  
have it in front of me).  I then just checked that in the after  
clause.  You could also set an ivar.  My patch was quick because I was  
actually debugging something else at the time -- I need to revisit the  
implications of using thread.current[].

Sujal

On Jun 12, 2008, at 11:08 AM, dsparling wrote:


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Doug Sparling  
View profile
 More options Jun 12, 3:15 pm
From: "Doug Sparling" <doug.sparl...@gmail.com>
Date: Thu, 12 Jun 2008 14:15:42 -0500
Local: Thurs, Jun 12 2008 3:15 pm
Subject: Re: [acts_as_cached] Re: Conditional action-caching stops after a period of time

I was in the middle of a site launch and this came up - Jan fortunately
helped me and it worked and I haven't had time to revisit it - I had meant
to post that back to the list a month ago.

==
doug


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2008 Google