Getting acts_as_solr Rake tasks working on JRuby

Posted by Colin Mon, 15 Jun 2009 21:09:00 GMT

When you try and run rake solr:start or rake solr:stop it uses Kernel.fork to spawn of a child process. However in JRuby this is disabled by default due to concurrency issues. And this prevents your solr rake tasks from running under a JRuby environment...

The Problem

>When you try and run rake solr:start or rake solr:stop it uses Kernel.fork to spawn of a child process. However in JRuby this is disabled by default due to concurrency issues. There is an option to enabling fork (jruby -J-Djruby.fork.enabled=true) within JRuby but it is experimental and as the warning says, "WARNING: fork is highly unlikely to be safe or stable on the JVM. Have fun!" as it can cause all sorts of weird and wonderful side-effects.

The Solution

The solution therefore is to simply alter the solr:start and solr:stop tasks to use Kernel.exec instead. To do this find the solr rake tasks usually in {RAILS_ROOT}/vendor/acts_as_solr/lib/tasks/solr.rake. In the start task all that is required is to comment out the start of the fork block. so you only have the exec method call,

task :start do
      require "#{File.dirname(__FILE__)}/../../config/solr_environment.rb"
      begin
        n = Net::HTTP.new('127.0.0.1', SOLR_PORT)
        n.request_head('/').value 

      rescue Net::HTTPServerException #responding
        puts "Port #{SOLR_PORT} in use" and return

      rescue Errno::ECONNREFUSED #not responding
        Dir.chdir(SOLR_PATH) do
            exec "java #{SOLR_JVM_OPTIONS} 
-Dsolr.data.dir=#{SOLR_DATA_PATH} -Djetty.logs=#{SOLR_LOGS_PATH} 
-Djetty.port=#{SOLR_PORT} -jar start.jar"
          sleep(5)
          File.open("#{SOLR_PIDS_PATH}/#{ENV['RAILS_ENV']}_pid", "w"){ |f| f << pid}
          puts "#{ENV['RAILS_ENV']} Solr started successfully on #{SOLR_PORT}, pid: #{pid}."
        end
      end
    end

and in the end task just comment out the begining of the fork block so you are left with

  task :stop do
    require "#{File.dirname(__FILE__)}/../../config/solr_environment.rb"
      file_path = "#{SOLR_PIDS_PATH}/#{ENV['RAILS_ENV']}_pid"
      if File.exists?(file_path)
        File.open(file_path, "r") do |f| 
          pid = f.readline
          Process.kill('TERM', pid.to_i)
        end
        File.unlink(file_path)
        Rake::Task["solr:destroy_index"].invoke if ENV['RAILS_ENV'] == 'test'
        puts "Solr shutdown successfully."
      else
        puts "PID file not found at #{file_path}. Either Solr is not running or no PID file was written."
      end
  end

you should now be able to run your solr rake tasks under jruby with out any problems.. Have fun Colin


About

We are a small British company that produces business-oriented software and solutions. These articles are a product of our daily work - information that we think might be useful to share. We hope you find them useful.

Our Software

These are some of our products. Several are open source, some are web-based and others are proprietary:

Categories

Archives

Syndicate

ml> ._trackPageview(); } catch(err) {} ml> l> pageTracker._trackPageview(); } catch(err) {} ml> ._trackPageview(); } catch(err) {} ml> l>