Class: ActsAsFerret::Remote::Server
- Inherits:
-
Object
- Object
- ActsAsFerret::Remote::Server
- Includes:
- UnixDaemon
- Defined in:
- lib/ferret_server.rb
Overview
This class acts as a drb server listening for indexing and search requests from models declared to ‘acts_as_ferret :remote => true’
Usage:
-
modify RAILS_ROOT/config/ferret_server.yml to suit your needs.
-
environments for which no section in the config file exists will use the index locally (good for unit tests/development mode)
-
run script/ferret_server to start the server:
script/ferret_server -e production start
-
to stop the server run
script/ferret_server -e production stop
Instance Method Summary collapse
-
#db_disconnect!(class_name) ⇒ Object
disconnects the db connection for the class specified by class_name used only in unit tests to check the automatic reconnection feature.
-
#ensure_index_exists(class_name) ⇒ Object
make sure we have a versioned index in place, building one if necessary.
-
#initialize ⇒ Server
constructor
A new instance of Server.
-
#method_missing(name, *args) ⇒ Object
handles all incoming method calls, and sends them on to the LocalIndex instance of the correct model class.
-
#rebuild_index(clazz, *models) ⇒ Object
hides LocalIndex#rebuild_index to implement index versioning.
-
#start ⇒ Object
start the server.
Methods included from UnixDaemon
#platform_daemon, #read_pid_file, #safefork, #stop, #write_pid_file
Constructor Details
#initialize ⇒ Server
Returns a new instance of Server.
64 65 66 67 68 69 |
# File 'lib/ferret_server.rb', line 64 def initialize @cfg = ActsAsFerret::Remote::Config.new ActiveRecord::Base.allow_concurrency = true ActiveRecord::Base.logger = @logger = Logger.new(@cfg.log_file) ActiveRecord::Base.logger.level = Logger.const_get(@cfg.log_level.upcase) rescue Logger::DEBUG end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args) ⇒ Object
handles all incoming method calls, and sends them on to the LocalIndex instance of the correct model class.
Calls are not queued atm, so this will block until the call returned.
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/ferret_server.rb', line 93 def method_missing(name, *args) @logger.debug "\#method_missing(#{name.inspect}, #{args.inspect})" retried = false with_class args.shift do |clazz| reconnect_when_needed(clazz) do # using respond_to? here so we not have to catch NoMethodError # which would silently catch those from deep inside the indexing # code, too... if clazz.aaf_index.respond_to?(name) clazz.aaf_index.send name, *args elsif clazz.respond_to?(name) @logger.debug "no luck, trying to call class method instead" clazz.send name, *args else raise NoMethodError.new("method #{name} not supported by DRb server") end end end rescue => e @logger.error "ferret server error #{$!}\n#{$!.backtrace.join "\n"}" raise e end |
Instance Method Details
#db_disconnect!(class_name) ⇒ Object
disconnects the db connection for the class specified by class_name used only in unit tests to check the automatic reconnection feature
129 130 131 132 133 |
# File 'lib/ferret_server.rb', line 129 def db_disconnect!(class_name) with_class class_name do |clazz| clazz.connection.disconnect! end end |
#ensure_index_exists(class_name) ⇒ Object
make sure we have a versioned index in place, building one if necessary
117 118 119 120 121 122 123 124 125 |
# File 'lib/ferret_server.rb', line 117 def ensure_index_exists(class_name) @logger.debug "DRb server: ensure_index_exists for class #{class_name}" with_class class_name do |clazz| dir = clazz.aaf_configuration[:index_dir] unless File.directory?(dir) && File.file?(File.join(dir, 'segments')) && dir =~ %r{/\d+(_\d+)?$} rebuild_index(clazz) end end end |
#rebuild_index(clazz, *models) ⇒ Object
hides LocalIndex#rebuild_index to implement index versioning
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/ferret_server.rb', line 136 def rebuild_index(clazz, *models) with_class clazz do |clazz| models = models.flatten.uniq.map(&:constantize) models << clazz unless models.include?(clazz) index = new_index_for(clazz, models) reconnect_when_needed(clazz) do @logger.debug "DRb server: rebuild index for class(es) #{models.inspect} in #{index.[:path]}" index.index_models models end new_version = File.join clazz.aaf_configuration[:index_base_dir], Time.now.utc.strftime('%Y%m%d%H%M%S') # create a unique directory name (needed for unit tests where # multiple rebuilds per second may occur) if File.exists?(new_version) i = 0 i+=1 while File.exists?("#{new_version}_#{i}") new_version << "_#{i}" end File.rename index.[:path], new_version clazz.index_dir = new_version end end |
#start ⇒ Object
start the server
73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/ferret_server.rb', line 73 def start raise "ferret_server not configured for #{RAILS_ENV}" unless (@cfg.uri rescue nil) $stdout.puts("starting ferret server...") platform_daemon do self.class.running = true DRb.start_service(@cfg.uri, self) DRb.thread.join end rescue Exception => e @logger.error(e.to_s) raise end |