Amit Solanki

Avatar

A Ruby On Rails Programmer from India

Undefined symbol: xsltLibxmlVersion - Ruby XSLT and CentOS

If you are facing the following error on your CentOS server:

require 'xml/xslt'
LoadError: /usr/lib/ruby/gems/1.8/gems/ruby-xslt-0.9.6/lib/xml/xslt_lib.so: undefined symbol: xsltLibxmlVersion - /usr/lib/ruby/gems/1.8/gems/ruby-xslt-0.9.6/lib/xml/xslt_lib.so
	from /usr/lib/ruby/gems/1.8/gems/ruby-xslt-0.9.6/lib/xml/xslt_lib.so
	from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
	from /usr/lib/ruby/gems/1.8/gems/ruby-xslt-0.9.6/lib/xml/xslt.rb:19
	from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:36:in `gem_original_require'
	from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:36:in `require'
	from (irb):1

Try reinstalling the following packages and gems:

yum reinstall -y libxml2 libxml2-devel libxslt libxslt-devel
ldconfig
gem uninstall libxml-ruby ruby-xslt
gem install libxml-ruby ruby-xslt

Don’t forget to run ldconfig command as root user. This command creates the necessary links and cache to the most recent shared libraries found in the directories specified on the command line. More details on the command can be found here.

Running delayed delta daemon in background for thinking sphinx

Thinking Sphinx is a rubygem which provides excellent search capabilities within your rails application. Unlike other search mechanism like acts_as_solr, thinking sphinx has one major limitation, entries do not automatically get indexed when a new record is created or an existing record is updated. To overcome this limitation, thinking sphinx has support for delta indexes. These delta indexes either need to be merged with your main index or you need to run a process which automatically does this for you.

I have been trying to use one of the recommended advanced delta approaches, delayed deltas. If you are using this approach, you need to invoke the following command which automatically indexes new/updated entries and merges them into main index:

rake thinking_sphinx:delayed_delta
rake ts:dd # shortcut for above task

I found out that you cannot force the task to run in background and hence it is not suitable for production environment. This works well when you use it in development environment where you can debug code and see the task working.

You can use the following script to invoke a background process which essentially does the same work and can be used on the production server as well:

#!/usr/bin/env ruby
require 'rubygems'
require 'daemons'
dir = File.expand_path(File.join(File.dirname(__FILE__), '..'))

daemon_options = {
  :multiple => false,
  :dir_mode => :normal,
  :dir => File.join(dir, 'tmp', 'pids'),
  :backtrace => true
}

Daemons.run_proc('job_runner', daemon_options) do
  if ARGV.include?('--')
    ARGV.slice! 0..ARGV.index('--')
  else
    ARGV.clear
  end

  Dir.chdir dir
  RAILS_ENV = ARGV.first || ENV['RAILS_ENV'] || 'development'
  require File.join('config', 'environment')

  Delayed::Worker.new(
    :min_priority => ENV['MIN_PRIORITY'],
    :max_priority => ENV['MAX_PRIORITY']
  ).start
end

Just put this code into script directory of your rails application with filename delayed_delta and assign executable permissions. Now, you can use the following task to manage the background process on server:

ruby script/delayed_delta start RAILS_ENV=production  # Starts delta indexing daemon
ruby script/delayed_delta stop RAILS_ENV=production   # Stops delta indexing daemon
ruby script/delayed_delta status RAILS_ENV=production # Shows process id if the process is running
# => job_runner: running [pid 6200]

You can edit you capistrano deploy script to restart the daemon if required by adding th following code:

namespace :delayed_delta do
  desc "Start delayed_delta daemon."
  task :start, :roles => :app do
    run "cd #{current_path} && RAILS_ENV=production script/delayed_delta start"
  end

  desc "Stop delayed_delta daemon."
  task :stop, :roles => :app do
    run "cd #{current_path} && RAILS_ENV=production script/delayed_delta stop"
  end

  desc "Restart delayed_delta daemon."
  task :restart, :roles => :app do
    run "cd #{current_path} && RAILS_ENV=production script/delayed_delta restart"
  end

  desc "Show delayed_delta daemon status."
  task :status, :roles => :app do
    run "cd #{current_path} && RAILS_ENV=production script/delayed_delta status"
  end
end

after  "deploy:restart",     "delayed_delta:restart"

Hope this post saves your time.

,

Before you go

Going so soon? May these links be a guide to web enlightenment.