Skip to content

Commit

Permalink
battle#index recovers from failed results
Browse files Browse the repository at this point in the history
  • Loading branch information
jrochkind committed Aug 21, 2012
1 parent 2a2db3e commit 996ed15
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 8 deletions.
48 changes: 44 additions & 4 deletions app/controllers/battle_controller.rb
Expand Up @@ -14,18 +14,26 @@ def self.contenders=(arr)
before_filter :validate_choice, :only => :choice

def index
if params[:q]
choices = contenders.shuffle

if params[:q]
@one = choices.pop
@two = choices.pop

searcher = BentoSearch::MultiSearcher.new(@one, @two)

@results = searcher.start(params[:q]).results
@results = searcher.start(params[:q]).results

# check for failed searches and handle
["one", "two"].each do |choice|
engine = instance_variable_get("@#{choice}")
if @results[engine].failed?
handle_failed_results(choice)
end
end
end
end



def choice
choice = if params["preferA"].present?
params[:option_a]
Expand Down Expand Up @@ -57,6 +65,12 @@ def choice

protected

# in seperate method mainly so we can mock it in tests to choose
# exactly what engines we want.
def choices
@choices ||= contenders.shuffle
end

def validate_choice
unless (params[:option_a].present? && params[:option_b].present? &&
params[:query].present? &&
Expand All @@ -68,4 +82,30 @@ def validate_choice
end
end

# arg 'choice' is 'one' or 'two', and is a search engine results
# that failed. We'll try to replace it with results from next in
# list, and register it's failure. Check again and recursively
# handle error again if needed.
def handle_failed_results(choice)
orig_engine = instance_variable_get("@#{choice}")
orig_results = @results[orig_engine]

# record the error
Error.create(
:engine => orig_engine,
:error_info => orig_results.error.to_hash,
:backtrace => orig_results.error[:exception].try(:backtrace)
)


@results.delete orig_engine

new_engine = choices.pop
instance_variable_set("@#{choice}", new_engine)

new_results = BentoSearch.get_engine(new_engine).search(params[:q])

@results[new_engine] = new_results
end

end
2 changes: 2 additions & 0 deletions app/models/error.rb
@@ -1,3 +1,5 @@
class Error < ActiveRecord::Base
serialize :error_info
serialize :backtrace
attr_accessible :backtrace, :engine, :error_info
end
47 changes: 43 additions & 4 deletions test/functional/battle_controller_test.rb
Expand Up @@ -2,17 +2,17 @@

class BattleControllerTest < ActionController::TestCase
def setup
BentoSearch.register_engine("one") do |conf|
BentoSearch.register_engine("AA") do |conf|
conf.engine = "BentoSearch::MockEngine"
end
BentoSearch.register_engine("two") do |conf|
BentoSearch.register_engine("BB") do |conf|
conf.engine = "BentoSearch::MockEngine"
end
BentoSearch.register_engine("three") do |conf|
BentoSearch.register_engine("CC") do |conf|
conf.engine = "BentoSearch::MockEngine"
end

BattleController.contenders = ["one", "two", "three"]
BattleController.contenders = ["AA", "BB", "CC"]
end

def teardown
Expand Down Expand Up @@ -49,6 +49,45 @@ def teardown
end
end

test "should recover from errors when searching" do
BentoSearch.register_engine("error") do |conf|
conf.engine = "BentoSearch::MockEngine"
conf.error = {:message => "Fake error"}
end
BattleController.contenders = ["AA", "BB", "CC", "error"]

# Fake it into 'randomly' picking error in it's first two please
@controller.extend( Module.new do
# chooses from the end, so put error at the end
def choices
@choices ||= ["AA", "BB", "error", "CC"]
end
end)

assert_difference("Error.count", 1) do
get :index, :q => "Cancer"
end

assert_response :success

# proper error was saved
err = Error.last
assert_equal "error", err.engine


# didn't use error, replaced it with next in list, BB
assert_equal "CC", assigns["one"]
assert_equal "BB", assigns["two"]

# and in results
assert_include assigns["results"].keys, "CC"
assert_include assigns["results"].keys, "BB"

# and neither are errors
assert ! assigns["results"].values.find {|r| r.failed?}

end

test "choice" do
option_a = ["a", "b", "c"].sample
option_b = ["1", "2", "3"].sample
Expand Down

0 comments on commit 996ed15

Please sign in to comment.