Class: RightScale::CloudApi::ConnectionProxy::RightHttpConnectionProxy
- Defined in:
- lib/base/routines/connection_proxies/right_http_connection_proxy.rb
Defined Under Namespace
Classes: Error
Constant Summary collapse
- INACTIVE_LIFETIME_LIMIT =
seconds
900- @@storage =
{}
Class Method Summary collapse
-
.clean_storage ⇒ Object
Remove dead threads/fibers from the storage.
- .storage ⇒ Object
Instance Method Summary collapse
-
#clean_outdated_connections ⇒ Object
Delete out-of-dated connections for current Thread/Fiber.
-
#close_connection(endpoint, reason = '') ⇒ Object
:nodoc:.
-
#current_connection ⇒ Object
Expire the connection if it has expired.
-
#current_endpoint ⇒ Object
:nodoc:.
- #log(message) ⇒ Object
-
#request(data) ⇒ Object
Performs an HTTP request.
-
#storage ⇒ Object
—————————- HTTP Connections handling —————————-.
Class Method Details
.clean_storage ⇒ Object
Remove dead threads/fibers from the storage
36 37 38 |
# File 'lib/base/routines/connection_proxies/right_http_connection_proxy.rb', line 36 def self.clean_storage Utils::remove_dead_fibers_and_threads_from_storage(storage) end |
.storage ⇒ Object
31 32 33 |
# File 'lib/base/routines/connection_proxies/right_http_connection_proxy.rb', line 31 def self.storage @@storage end |
Instance Method Details
#clean_outdated_connections ⇒ Object
Delete out-of-dated connections for current Thread/Fiber
192 193 194 195 196 197 198 199 |
# File 'lib/base/routines/connection_proxies/right_http_connection_proxy.rb', line 192 def clean_outdated_connections life_time_scratch = Time::now - INACTIVE_LIFETIME_LIMIT storage.each do |endpoint, connection| if connection[:last_used_at] < life_time_scratch close_connection(endpoint, 'out-of-date') end end end |
#close_connection(endpoint, reason = '') ⇒ Object
:nodoc:
178 179 180 181 182 183 184 185 186 187 |
# File 'lib/base/routines/connection_proxies/right_http_connection_proxy.rb', line 178 def close_connection(endpoint, reason='') # :nodoc: return nil unless storage[endpoint] log "Destroying RightHttpConnection to #{endpoint}, reason: #{reason}" storage[endpoint][:connection].finish(reason) rescue => e log "Exception in close_connection: #{e.class.name}: #{e.message}" ensure storage.delete(endpoint) if endpoint end |
#current_connection ⇒ Object
Expire the connection if it has expired.
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/base/routines/connection_proxies/right_http_connection_proxy.rb', line 202 def current_connection # :nodoc: # Remove dead threads/fibers from the storage self.class::clean_storage # Delete out-of-dated connections clean_outdated_connections # Get current_connection endpoint = current_endpoint unless storage[endpoint] storage[endpoint] = {} storage[endpoint][:connection] = Rightscale::HttpConnection.new( :exception => CloudError, :logger => @data[:options][:cloud_api_logger].logger ) log "Creating RightHttpConection to #{endpoint.inspect}" else log "Reusing RightHttpConection to #{endpoint.inspect}" end storage[endpoint][:last_used_at] = Time::now storage[endpoint][:connection] end |
#current_endpoint ⇒ Object
:nodoc:
174 175 176 |
# File 'lib/base/routines/connection_proxies/right_http_connection_proxy.rb', line 174 def current_endpoint # :nodoc: "#{@uri.scheme}://#{@uri.host}:#{@uri.port}" end |
#log(message) ⇒ Object
162 163 164 |
# File 'lib/base/routines/connection_proxies/right_http_connection_proxy.rb', line 162 def log() @data[:options][:cloud_api_logger].log(, :connection_proxy) end |
#request(data) ⇒ Object
Performs an HTTP request.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 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 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 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/base/routines/connection_proxies/right_http_connection_proxy.rb', line 48 def request(data) require "right_http_connection" @data = data @data[:response] = {} # Create a connection @uri = @data[:connection][:uri].dup # Create/Get RightHttpConnection instance remote_endpoint = current_endpoint right_http_connection = current_connection # Register a callback to close current connection @data[:callbacks][:close_current_connection] = Proc::new{|reason| close_connection(remote_endpoint, reason); log "Current connection closed: #{reason}" } # Create a real HTTP request fake = @data[:request][:instance] http_request = "Net::HTTP::#{fake.verb._camelize}"._constantize::new(fake.path) if fake.is_io? http_request.body_stream = fake.body else http_request.body = fake.body end fake.headers.each{|header, value| http_request[header] = value } fake.raw = http_request # Set all the options are suported by RightHttpConnection (if they are) http_connection_data = { :server => @uri.host, :port => @uri.port, :protocol => @uri.scheme, :request => http_request, :exception => ConnectionError } # Set all required options http_connection_data[:logger] = @data[:options][:cloud_api_logger].logger http_connection_data[:user_agent] = @data[:options][:connection_user_agent] if @data[:options].has_key?(:connection_user_agent) http_connection_data[:ca_file] = @data[:options][:connection_ca_file] if @data[:options].has_key?(:connection_ca_file) http_connection_data[:http_connection_retry_count] = @data[:options][:connection_retry_count] if @data[:options].has_key?(:connection_retry_count) http_connection_data[:http_connection_read_timeout] = @data[:options][:connection_read_timeout] if @data[:options].has_key?(:connection_read_timeout) http_connection_data[:http_connection_open_timeout] = @data[:options][:connection_open_timeout] if @data[:options].has_key?(:connection_open_timeout) http_connection_data[:http_connection_retry_delay] = @data[:options][:connection_retry_delay] if @data[:options].has_key?(:connection_retry_delay) http_connection_data[:raise_on_timeout] = @data[:options][:abort_on_timeout] if @data[:options][:abort_on_timeout] http_connection_data[:cert] = @data[:credentials][:cert] if @data[:credentials].has_key?(:cert) http_connection_data[:key] = @data[:credentials][:key] if @data[:credentials].has_key?(:key) #log "HttpConnection request: #{http_connection_data.inspect}" # Make a request: block = @data[:vars][:system][:block] if block # If block is given - pass there all the chunks of a response and stop # (dont do any parsing, analysing etc) # # TRB 9/17/07 Careful - because we are passing in blocks, we get a situation where # an exception may get thrown in the block body (which is high-level # code either here or in the application) but gets caught in the # low-level code of HttpConnection. The solution is not to let any # exception escape the block that we pass to HttpConnection::request. # Exceptions can originate from code directly in the block, or from user # code called in the other block which is passed to response.read_body. # # TODO: the suggested fix for RightHttpConnection if to catch # Interrupt and SystemCallError instead of Exception in line 402 response = nil begin block_exception = nil # Response.body will be a Net::ReadAdapter instance here - it cant be read as a string. # WEB: On its own, Net::HTTP causes response.body to be a Net::ReadAdapter when you make a request with a block # that calls read_body on the response. response = right_http_connection.request(http_connection_data) do |res| begin # Update temp response @data[:response][:instance] = HTTPResponse::new( res.code, nil, res.to_hash, res ) res.read_body(&block) if res.is_a?(Net::HTTPSuccess) rescue Exception => e block_exception = e break end end raise block_exception if block_exception rescue Exception => e right_http_connection.finish(e.) raise e end else # Things are simple if there is no any block response = right_http_connection.request(http_connection_data) end @data[:response][:instance] = HTTPResponse::new( response.code, response.body, response.to_hash, response ) # # HACK: KD # # # # When one uploads a file with pos > 0 and 'content-length' != File.size - pos # # then the next request through this connection fails with 400 or 505... # # It seems that it expects the file to be read until EOF. # # # # KIlling the current connection seems to help but it is not good... # # # if @data[:request][:instance].body_stream #&& !@data[:request][:instance].body_stream.eof # pp @data[:request][:instance].body_stream.pos # log "closing current connection because of an issue when an IO object is not read until EOF" # @connection.finish # end end |
#storage ⇒ Object
HTTP Connections handling
170 171 172 |
# File 'lib/base/routines/connection_proxies/right_http_connection_proxy.rb', line 170 def storage # :nodoc: @@storage[Utils::current_thread_and_fiber] ||= {} end |