Class: Rightscale::Rackspace::HttpErrorHandler

Inherits:
Object
  • Object
show all
Defined in:
lib/rackspace_base.rb

Overview

:nodoc:

Constant Summary collapse

REAUTHENTICATE_ON =

Receiving these codes we have to reauthenticate at Rackspace

['401']
SKIP_LOGGING_ON =

SKIP_LOGGING_ON = [‘404’]

[]
@@reiteration_start_delay =
0.2
@@reiteration_time =
5

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(handle, params = {}) ⇒ HttpErrorHandler

params:

:reiteration_time
:errors_list


463
464
465
466
467
468
469
470
# File 'lib/rackspace_base.rb', line 463

def initialize(handle, params={}) #:nodoc:
  @handle        = handle           # Link to RightEc2 | RightSqs | RightS3 instance
  @started_at    = Time.now
  @stop_at       = @started_at  + (params[:reiteration_time] || @@reiteration_time)
  @errors_list   = params[:errors_list] || []
  @reiteration_delay = @@reiteration_start_delay
  @retries       = 0
end

Class Method Details

.extract_error_description(response, verbose = false) ⇒ Object

Format a response error message.



443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
# File 'lib/rackspace_base.rb', line 443

def self.extract_error_description(response, verbose=false) #:nodoc:
  message = nil
  Interface::bench.parser.add! do
    message = begin
                if response.body[/^<!DOCTYPE HTML PUBLIC/] then response.message
                else
                  JSON::parse(response.body).to_a.map do |k,v|
                    "#{k}: #{v['message']}" + (verbose ? "\n#{v['details']}" : "")
                  end.join("\n")
                end
              rescue
                response.message
              end
  end
  "#{response.code}: #{message}"
end

.reiteration_start_delayObject



428
429
430
# File 'lib/rackspace_base.rb', line 428

def self.reiteration_start_delay
  @@reiteration_start_delay
end

.reiteration_start_delay=(reiteration_start_delay) ⇒ Object



431
432
433
# File 'lib/rackspace_base.rb', line 431

def self.reiteration_start_delay=(reiteration_start_delay)
  @@reiteration_start_delay = reiteration_start_delay
end

.reiteration_timeObject



435
436
437
# File 'lib/rackspace_base.rb', line 435

def self.reiteration_time
  @@reiteration_time
end

.reiteration_time=(reiteration_time) ⇒ Object



438
439
440
# File 'lib/rackspace_base.rb', line 438

def self.reiteration_time=(reiteration_time)
  @@reiteration_time = reiteration_time
end

Instance Method Details

#check(request_hash) ⇒ Object

Process errored response



473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
# File 'lib/rackspace_base.rb', line 473

def check(request_hash)  #:nodoc:
  result      = nil
  error_found = false
  response    = @handle.last_response
  error_message = @handle.last_error
  # Log the error
  logger = @handle.logger
  unless SKIP_LOGGING_ON.include?(response.code)
    logger.warn("##### #{@handle.class.name} returned an error: #{error_message} #####")
    logger.warn("##### #{@handle.class.name} request: #{request_hash[:server]}:#{request_hash[:port]}#{request_hash[:request].path} ####")
  end
  # now - check the error
  @errors_list.each do |error_to_find|
    if error_message[/#{error_to_find}/i]
      error_found = error_to_find
      logger.warn("##### Retry is needed, error pattern match: #{error_to_find} #####")
      break
    end
  end
  # yep, we know this error and have to do a retry when it comes
  if error_found || REAUTHENTICATE_ON.include?(@handle.last_response.code)
    # check the time has gone from the first error come
    # Close the connection to the server and recreate a new one.
    # It may have a chance that one server is a semi-down and reconnection
    # will help us to connect to the other server
    if (Time.now < @stop_at)
      @retries += 1
      @handle.logger.warn("##### Retry ##{@retries} is being performed. Sleeping for #{@reiteration_delay} sec. Whole time: #{Time.now-@started_at} sec ####")
      sleep @reiteration_delay
      @reiteration_delay *= 2
      # Always make sure that the fp is set to point to the beginning(?)
      # of the File/IO. TODO: it assumes that offset is 0, which is bad.
      if request_hash[:request].body_stream && request_hash[:request].body_stream.respond_to?(:pos)
        begin
          request_hash[:request].body_stream.pos = 0
        rescue Exception => e
          logger.warn("Retry may fail due to unable to reset the file pointer -- #{self.class.name} : #{e.inspect}")
        end
      end
      # Oops it seems we have been asked about reauthentication..
      if REAUTHENTICATE_ON.include?(@handle.last_response.code)
        @handle.authenticate
        @handle.request_info(request_hash)
      end
      # Make another try
      result = @handle.request_info(request_hash)
    else
      logger.warn("##### Ooops, time is over... ####")
    end
  end
  result
end