Skip to content

Loading…

Retry failed updates at least once after a 500ms delay. #198

Closed
wants to merge 1 commit into from

2 participants

@nz
Sunspot member
nz commented

So, sometimes Solr sends a 503 because it needs a breather. Let's just retry those.

TODO:

  • Target 503 errors differently than the rest — what exception is RSolr sending? No sense retrying a 40x.
  • Tests
  • Wrap this into the default session, because what's the point if nobody uses it?
@brupm

+1

@brupm

Would be even more awesome if both read and write had a rescue and retry.

@nz
Sunspot member
nz commented

Would be even more awesome if both read and write had a rescue and retry.

IMHO, read failures are more of a controller concern: an explicit rescue to retry 503s, and a rescue_from to show an appropriate user-facing response for everything else.

But… I guess I could be persuaded that a well-formed 503 with a sensible Retry-After header could be automagically retried for both reads and writes. I'm just concerned that a throttled retry may be too slow for some applications, and so should be up to the developer to handle.

@nz
Sunspot member
nz commented

I've got a way better thing going in #208.

@nz nz closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 15, 2012
  1. @nz
Showing with 45 additions and 0 deletions.
  1. +45 −0 sunspot/lib/sunspot/session_proxy/retry_fail_session_proxy.rb
View
45 sunspot/lib/sunspot/session_proxy/retry_fail_session_proxy.rb
@@ -0,0 +1,45 @@
+require File.join(File.dirname(__FILE__), 'abstract_session_proxy')
+
+module Sunspot
+ module SessionProxy
+ class RetryFailSessionProxy < AbstractSessionProxy
+
+ attr_reader :search_session
+
+ delegate :new_search, :search, :config,
+ :new_more_like_this, :more_like_this,
+ :delete_dirty, :delete_dirty?,
+ :to => :search_session
+
+ def initialize(search_session = Sunspot.session)
+ @search_session = search_session
+ end
+
+ def rescued_exception(method, e)
+ $stderr.puts("Exception in #{method}: #{e.message}")
+ end
+
+ SUPPORTED_METHODS = [
+ :batch, :commit, :commit_if_dirty, :commit_if_delete_dirty, :dirty?,
+ :index!, :index, :optimize, :remove!, :remove, :remove_all!, :remove_all,
+ :remove_by_id!, :remove_by_id
+ ]
+
+ SUPPORTED_METHODS.each do |method|
+ module_eval(<<-RUBY)
+ def #{method}(*args, &block)
+ retry_count = 1
+ begin
+ search_session.#{method}(*args, &block)
+ rescue => e
+ sleep 0.5
+ self.rescued_exception(:#{method}, e)
+ retry if (retry_count -= 1) >= 0
+ end
+ end
+ RUBY
+ end
+
+ end
+ end
+end
Something went wrong with that request. Please try again.