automate thinking_sphinx index rebuilding using capistrano 23 Jun 2011
Tags: thinking_sphinx gem capistrano deployment

On my current project, we use capistrano to automate deployment to our two servers: staging and production. Deployment was going smooth until we decided to use thinking_sphinx. Sphinx and thinking_sphinx works well together and it was easy to setup. The problem we had was automating indexing after deployment.

Thinking Sphinx's site has a page dedicated to this but it's not working for us. Moreover, it always uses the production environment. So I delved into the capistrano tasks in

ruby
thinking_sphinx/deploy/capistrano

and I found out that the rake method defined use the rails_env variable. In our capistrano recipe, we use rack_env. So to solve the environment issue, just set a rails_env variable.

Next problem is the indexing automation. To solve this, require the files specified in the thinking_sphinx page

ruby
# If you're using Thinking Sphinx as a gem:
require 'thinking_sphinx/deploy/capistrano'

#If you're using Thinking Sphinx as a plugin:
require 'vendor/plugins/thinking-sphinx/recipes/thinking_sphinx'

Now that we have access to the thinking_sphinx capistrano tasks, we add the following lines to the end of our capistrano recipe

ruby
task :before_update_code, :roles => [:app] do
  thinking_sphinx.stop
end

after 'deploy:setup', 'thinking_sphinx:shared_sphinx_folder'

Then inside the deploy namespace, add these lines

ruby
namespace :deploy do
  task :start, :roles => :app do
    #other tasks here
    thinking_sphinx.rebuild
  end

  task :restart, :roles => :app do
    #other tasks here
    thinking_sphinx.rebuild
  end
end

Expiring Cache Fragments from the console 29 Jun 2011
Tags: console, cache

I've been using some simple fragment caching on some of the pages of my current app.  But one update made all these fragments expire.  So either I create a rake task to delete these cache fragments or I use the console. Either way, the only thing you need to remember is

ruby
ActionController::Base.new.expire_fragment(key)

Of course, almost all of the times, key is dynamic. But since key accepts either a String, Hash or Regexp, this shouldn't be a problem. Check the fragment caching module