Class: RightDevelop::Testing::Client::Rest::Request::Playback

Inherits:
Base
  • Object
show all
Defined in:
lib/right_develop/testing/clients/rest/requests/playback.rb

Overview

Provides a middle-ware layer that intercepts transmition of the request and escapes out of the execute call with a stubbed response using throw/catch.

Defined Under Namespace

Classes: FakeNetHttpResponse, PlaybackError

Constant Summary collapse

HALT_TRANSMIT =
:halt_transmit
RETRY_DELAY =
0.5
MAX_RETRIES =

50 seconds; a socket usually times out in 60-120 seconds

100

Constants inherited from Base

Base::METADATA_CLASS, Base::MUTEX

Instance Attribute Summary collapse

Attributes inherited from Base

#fixtures_dir, #logger, #request_metadata, #request_timestamp, #response_metadata, #response_timestamp, #route_data, #route_path, #state_file_path

Instance Method Summary collapse

Methods inherited from Base

#forget_outstanding_request, #log_response

Constructor Details

#initialize(args) ⇒ Playback



67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/right_develop/testing/clients/rest/requests/playback.rb', line 67

def initialize(args)
  if args[:throttle]
    args = args.dup
    @throttle = Integer(args.delete(:throttle))
    if @throttle < 0 || @throttle > 100
      raise ::ArgumentError, 'throttle must be a percentage between 0 and 100'
    end
  else
    @throttle = 0
  end
  super(args)
end

Instance Attribute Details

#throttleObject (readonly)

Returns the value of attribute throttle.



65
66
67
# File 'lib/right_develop/testing/clients/rest/requests/playback.rb', line 65

def throttle
  @throttle
end

Instance Method Details

#handle_timeoutObject

Raises:

  • (::NotImplementedError)

See Also:

  • Base.handle_timeout


150
151
152
# File 'lib/right_develop/testing/clients/rest/requests/playback.rb', line 150

def handle_timeout
  raise ::NotImplementedError, 'Timeout is unexpected for stubbed API call.'
end

#log_requestObject

Overrides log_request to interrupt transmit before any connection is made.

Raises:

  • (Symbol)

    always throws HALT_TRANSMIT



83
84
85
86
# File 'lib/right_develop/testing/clients/rest/requests/playback.rb', line 83

def log_request
  super
  throw(HALT_TRANSMIT, HALT_TRANSMIT)
end

#transmit(uri, req, payload, &block) ⇒ Object

Overrides transmit to catch halt thrown by log_request.



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/right_develop/testing/clients/rest/requests/playback.rb', line 98

def transmit(uri, req, payload, &block)
  caught = catch(HALT_TRANSMIT) { super }
  if caught == HALT_TRANSMIT
    response = nil
    try_counter = 0
    while response.nil?
      with_state_lock do |state|
        response = catch(::HALT) do
          fetch_response(state)
        end
      end
      case response
      when ::RetryableFailure
        try_counter += 1
        if try_counter >= MAX_RETRIES
          message =
            "Released thread id=#{::Thread.current.object_id} after " <<
            "#{try_counter} attempts to satisfy a retryable condition:\n" <<
            response.message
          raise PlaybackError, message
        end
        if 1 == try_counter
          message = "Blocking thread id=#{::Thread.current.object_id} " <<
                    'until a retryable condition is satisfied...'
          logger.debug(message)
        end
        response = nil
        sleep RETRY_DELAY
      else
        if try_counter > 0
          message = "Released thread id=#{::Thread.current.object_id} " <<
                    'after a retryable condition was satisfied.'
          logger.debug(message)
        end
      end
    end

    # delay, if throttled, to simulate server response time.
    if @throttle > 0 && response.elapsed_seconds > 0
      delay = (Float(response.elapsed_seconds) * @throttle) / 100.0
      logger.debug("throttle delay = #{delay}")
      sleep delay
    end
    log_response(response)
    process_result(response, &block)
  else
    raise PlaybackError,
          'Unexpected RestClient::Request#transmit returned without calling RestClient::Request#log_request'
  end
end