Phusion Passenger and memcache

One of my recently deployed Rails app uses memcache with Phusion Passenger. I read on the Phusion documentation about the possibility of corrupted commands issued to memcache through the spawned processes within Passenger.

I added the declarations below within the config/environment.rb file to overcome this issue:


      begin
         PhusionPassenger.on_event(:starting_worker_process) do |forked|
             if forked
               # We're in smart spawning mode, so...
               # Close duplicated memcached connections - they will open themselves
                 CACHE.reset
             end
         end
     # In case you're not running under Passenger (i.e. devmode with mongrel)
     rescue NameError => error
   end
 

The CACHE constant is set within the cache_fu plugin. All the declaration does is similar to that outlined in the Appendix of the Phusion documentation with the addition of the ‘begin..rescue’ block to counteract exceptions which may arise.

I understand from comments on the Passenger google group that cache_fu causes problems with memcached. If anyone has any further information on the above please feel free to comment.

Tagged with:
 

Using cache_fu with will_paginate

Firstly, apologies for not updating regularly enough (last post was in September – yikes!). We have been busy working on two freelance projects since then: firstly with South East Forum for 55 Degrees; and finally with HiredHelp, which is a service provider listing page for Hermes Technologies based in Ireland.

I want to start off the new series of posts with interesting tidits I learnt while developing on these two projects.

On the HiredHelp website, we try to cache as much of the DB calls as possible using memecached with the cache_fu plugin. One of the obstacles we came across was if we had to cache the index action of say a list of babysitters with pagination added in, the subsequent paginated pages do not show. This is due to the fact that the cache is storing the page as ‘babysitters/index’ and not ‘babysitters?page=xxx’.

You will need to provide a ‘cached_path’ to the caches_action in the controller.

For example:

This is the ‘caches_action’ method within the controller:

  
      caches_action :index, :cache_path => :index_cache_path.to_proc
      
def index @babysitters = Babysitter.cached(:list).paginate(:page => params[:page],:per_page => 10) end
private def index_cache_path p = '' p = params[:page] if params[:page] and params[:page] != 1 'babysitters/' + p end

The ‘cached’ method was provided by cache_fu and calls the method ‘list’ within the Babysitter model. The index_cache_path method simply appends the page params from the wii_paginate plugin to the end of the index url. So pages like ‘babysitters?page=2′ will be cached as ‘babysitters/2′ etc.

Now to expire the paginated pages, I wrote a custom method within my sweepers file:

  
  #within BabysitterSweeper
  
def expire_cache total = (Babysitter.list.size.to_i) if total <= 10 expire_fragment("babysitters/index") else pages = (total % 10) + (total /10) -1 1.upto(pages) do |page| expire_fragment("babysitters/#{page}") end expire_fragment("babysitters/index")
end end

The method computes the number of listings allowed per page as stipulated in the wii_paginate call in the index action. In our case it is 10. If the number of entries is less than 10, that means we only expire the index action. If not, we calculate the number of paginated pages there are. If we have say 22 entries that will be split into 3 paginated pages with 2 pages containing 10 entries and a third page with 2 entries. The ‘expire_cache’ method will expire the fragements labelled ‘babysitters/2′ etc from the index call such as ‘babysitters?page=2′.

Tagged with: