Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Hard retries for Sphinx exceptions, via Andrew Hunter.

  • Loading branch information...
commit 96807c7c032bb2e20e573c03a8726bda6619f3ab 1 parent c85940e
@pat authored
View
5 lib/thinking_sphinx/configuration.rb
@@ -28,6 +28,7 @@ module ThinkingSphinx
# html remove elements:: ''
# searchd_binary_name:: searchd
# indexer_binary_name:: indexer
+ # hard_retry_count:: 0
#
# If you want to change these settings, create a YAML file at
# config/sphinx.yml with settings for each environment, in a similar
@@ -64,7 +65,8 @@ class Configuration
attr_accessor :searchd_file_path, :allow_star, :app_root,
:model_directories, :delayed_job_priority, :indexed_models, :use_64_bit,
- :touched_reindex_file, :stop_timeout, :version, :shuffle
+ :touched_reindex_file, :stop_timeout, :version, :shuffle,
+ :hard_retry_count
attr_accessor :source_options, :index_options
@@ -112,6 +114,7 @@ def reset(custom_app_root=nil)
self.delayed_job_priority = 0
self.indexed_models = []
self.shuffle = false
+ self.hard_retry_count = 0
self.source_options = {}
self.index_options = {
View
55 lib/thinking_sphinx/search.rb
@@ -405,28 +405,41 @@ def config
def populate
return if @populated
@populated = true
+ retries = hard_retries
- retry_on_stale_index do
- begin
- log "Querying: '#{query}'"
- runtime = Benchmark.realtime {
- @results = client.query query, indexes, comment
- }
- log "Found #{@results[:total_found]} results", :debug,
- "Sphinx (#{sprintf("%f", runtime)}s)"
-
- log "Sphinx Daemon returned warning: #{warning}", :error if warning?
-
- if error?
- log "Sphinx Daemon returned error: #{error}", :error
- raise SphinxError.new(error, @results) unless options[:ignore_errors]
+ begin
+ retry_on_stale_index do
+ begin
+ log "Querying: '#{query}'"
+ runtime = Benchmark.realtime {
+ @results = client.query query, indexes, comment
+ }
+ log "Found #{@results[:total_found]} results", :debug,
+ "Sphinx (#{sprintf("%f", runtime)}s)"
+
+ log "Sphinx Daemon returned warning: #{warning}", :error if warning?
+
+ if error?
+ log "Sphinx Daemon returned error: #{error}", :error
+ raise SphinxError.new(error, @results) unless options[:ignore_errors]
+ end
+ rescue Errno::ECONNREFUSED => err
+ raise ThinkingSphinx::ConnectionError,
+ 'Connection to Sphinx Daemon (searchd) failed.'
end
- rescue Errno::ECONNREFUSED => err
- raise ThinkingSphinx::ConnectionError,
- 'Connection to Sphinx Daemon (searchd) failed.'
- end
- compose_results
+ compose_results
+ end
+ rescue => e
+ log 'Caught Sphinx exception: %s (%s %s left)' % [
+ e.message, retries, (retries == 1 ? 'try' : 'tries')
+ ]
+ retries -= 1
+ if retries >= 0
+ retry
+ else
+ raise e
+ end
end
end
@@ -847,6 +860,10 @@ def stale_retries
end
end
+ def hard_retries
+ options[:hard_retry_count] || config.hard_retry_count
+ end
+
def include_for_class(klass)
includes = options[:include] || klass.sphinx_index_options[:include]
View
32 spec/thinking_sphinx/search_spec.rb
@@ -411,6 +411,38 @@
'baz @foo bar @(foo,bar) baz', :star => true
).first
end
+
+ it "should try retry query up to the hard_retry_count option times if it catches an exception" do
+ @client.should_receive(:query).exactly(4).and_raise("Test Exception")
+
+ expect { ThinkingSphinx::Search.new(:hard_retry_count => 3).first }.
+ to raise_error("Test Exception")
+ end
+
+ it "should not retry query if hard_retry_count option is not set" do
+ @client.should_receive(:query).exactly(1).and_raise("Test Exception")
+
+ expect { ThinkingSphinx::Search.new.first }.
+ to raise_error("Test Exception")
+ end
+
+ it "should allow the hard_retry_count to be globally set as a configuration option" do
+ @config.hard_retry_count = 2
+
+ @client.should_receive(:query).exactly(3).and_raise("Test Exception")
+
+ expect { ThinkingSphinx::Search.new.first }.
+ to raise_error("Test Exception")
+ end
+
+ it "should give priority to the hard_retry_count search option over the globally configured option" do
+ @config.hard_retry_count = 4
+
+ @client.should_receive(:query).exactly(2).and_raise("Test Exception")
+
+ expect { ThinkingSphinx::Search.new(:hard_retry_count => 1).first }.
+ to raise_error("Test Exception")
+ end
end
describe 'comment' do
Please sign in to comment.
Something went wrong with that request. Please try again.