Class: Amazon::WebServices::MTurk::MechanicalTurkErrorHandler

Inherits:
Object
  • Object
show all
Includes:
Util::Logging
Defined in:
lib/amazon/webservices/mturk/mechanical_turk_error_handler.rb

Constant Summary collapse

REQUIRED_PARAMETERS =
[:Relay]
RETRY_PRE =

Commands with these prefixes can be retried if we are unsure of success

%w( search get register update disable assign set dispose )
MAX_RETRY =

Max number of times to retry a call

6
BACKOFF_BASE =

Base used in Exponential Backoff retry delay

2
BACKOFF_INITIAL =

Scale factor for Exponential Backoff retry delay

0.1
RESULT_PATTERN =

Matching pattern to find a ‘Results’ element in the Response

/Result/
ACCEPTABLE_RESULTS =

Additional elements to be considered a ‘Result’ despite not matching RESULT_PATTERN

%w( HIT Qualification QualificationType QualificationRequest Information )

Instance Method Summary collapse

Methods included from Util::Logging

#log, #set_log

Constructor Details

#initialize(args) ⇒ MechanicalTurkErrorHandler

Returns a new instance of MechanicalTurkErrorHandler.



33
34
35
36
37
# File 'lib/amazon/webservices/mturk/mechanical_turk_error_handler.rb', line 33

def initialize( args )
  missing_parameters = REQUIRED_PARAMETERS - args.keys
  raise "Missing paramters: #{missing_parameters.join(',')}" unless missing_parameters.empty?
  @relay = args[:Relay]
end

Instance Method Details

#canRetry(try) ⇒ Object



103
104
105
# File 'lib/amazon/webservices/mturk/mechanical_turk_error_handler.rb', line 103

def canRetry( try )
  try <= MAX_RETRY
end

#dispatch(method, *args) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/amazon/webservices/mturk/mechanical_turk_error_handler.rb', line 39

def dispatch(method, *args)
  try = 0
  begin
    try += 1
    log "Dispatching call to #{method} (try #{try})"
    response = @relay.send(method,*args)
    validateResponse( response )
    return response
  rescue Exception => error
    case handleError( error,method )
    when :RetryWithBackoff
      retry if doBackoff( try )
    when :RetryImmediate
      retry if canRetry( try )
    when :Ignore
      return :IgnoredError => error
    when :Unknown
      raise Util::UnknownResultException.new( error, method, args )
    when :Fail
      raise error
    else
      raise "Unknown error handling method: #{handleError( error,method )}"
    end
    raise error
  end
end

#doBackoff(try) ⇒ Object



107
108
109
110
111
112
# File 'lib/amazon/webservices/mturk/mechanical_turk_error_handler.rb', line 107

def doBackoff( try )
  return false unless canRetry(try)
  delay = BACKOFF_INITIAL * ( BACKOFF_BASE ** try )
  sleep delay
  return true
end

#handleError(error, method) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/amazon/webservices/mturk/mechanical_turk_error_handler.rb', line 73

def handleError( error, method )
  log "Handling error: #{error.inspect}"
  case error.class.to_s
  when 'Timeout::Error','SOAP::HTTPStreamError'
    if methodRetryable( method )
      return :RetryImmediate
    else
      return :Unknown
    end
  when 'SOAP::FaultError'
    case error.faultcode.data
    when "aws:Server.ServiceUnavailable"
      return :RetryWithBackoff
    else
      return :Unknown
    end
  when 'Amazon::WebServices::Util::ValidationException'
    return :Fail
  when 'RuntimeError'
    case error.message
    when 'Throttled'
      return :RetryWithBackoff
    else
      return :RetryImmediate
    end
  else
    return :Unknown
  end
end

#isResultTag(tag) ⇒ Object



114
115
116
# File 'lib/amazon/webservices/mturk/mechanical_turk_error_handler.rb', line 114

def isResultTag( tag )
  tag.to_s =~ RESULT_PATTERN or ACCEPTABLE_RESULTS.include?( tag.to_s )
end

#methodRetryable(method) ⇒ Object



66
67
68
69
70
71
# File 'lib/amazon/webservices/mturk/mechanical_turk_error_handler.rb', line 66

def methodRetryable( method )
  RETRY_PRE.each do |pre|
    return true if method.to_s =~ /^#{pre}/i
  end
  return false
end

#validateResponse(response) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/amazon/webservices/mturk/mechanical_turk_error_handler.rb', line 118

def validateResponse(response)
  log "Validating response: #{response.inspect}"
  raise 'Throttled' if response[:Errors] and response[:Errors][:Error] and response[:Errors][:Error][:Code] == "ServiceUnavailable"
  raise Util::ValidationException.new(response) unless response[:OperationRequest][:Errors].nil?
  resultTags = response.keys.find_all {|r| isResultTag( r ) }
  raise Util::ValidationException.new(response, "Didn't get back an acceptable result tag (got back #{response.keys.join(',')})") if resultTags.empty?
  resultTags.each do |resultTag|
    log "using result tag <#{resultTag}>"
    result = response[resultTag]
    raise Util::ValidationException.new(response) unless result[:Request][:Errors].nil?
  end
  response
end