Class: Rest::Client
- Inherits:
-
Object
- Object
- Rest::Client
- Defined in:
- lib/rest/client.rb
Instance Attribute Summary collapse
-
#gem ⇒ Object
Returns the value of attribute gem.
-
#logger ⇒ Object
Returns the value of attribute logger.
-
#options ⇒ Object
Returns the value of attribute options.
-
#wrapper ⇒ Object
readonly
Returns the value of attribute wrapper.
Instance Method Summary collapse
- #choose_best_gem ⇒ Object
- #close ⇒ Object
- #delete(url, req_hash = {}) ⇒ Object
- #get(url, req_hash = {}) ⇒ Object
-
#initialize(options = {}) ⇒ Client
constructor
options: - :gem => specify gem explicitly.
- #patch(url, req_hash = {}) ⇒ Object
-
#perform_op(method, req_hash, options = {}, &blk) ⇒ Object
This will attempt to perform the operation with an exponential backoff on 503 errors.
-
#post(url, req_hash = {}) ⇒ Object
req_hash options: - :body => post body.
- #post_file(url, req_hash = {}) ⇒ Object
- #put(url, req_hash = {}) ⇒ Object
- #set_defaults(options) ⇒ Object
Constructor Details
#initialize(options = {}) ⇒ Client
options:
-
:gem => specify gem explicitly
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 |
# File 'lib/rest/client.rb', line 57 def initialize(={}) = @logger = Rest.logger @gem = [:gem] if @gem.nil? choose_best_gem() end if @gem == :excon require File.('wrappers/excon_wrapper', File.dirname(__FILE__)) @wrapper = Rest::Wrappers::ExconWrapper.new(self) @logger.debug "Using excon gem." elsif @gem == :typhoeus require File.('wrappers/typhoeus_wrapper', File.dirname(__FILE__)) @wrapper = Rest::Wrappers::TyphoeusWrapper.new(self) @logger.debug "Using typhoeus gem." elsif @gem == :net_http_persistent require File.('wrappers/net_http_persistent_wrapper', File.dirname(__FILE__)) @wrapper = Rest::Wrappers::NetHttpPersistentWrapper.new(self) @logger.debug "Using net-http-persistent gem." elsif @gem == :rest_client require File.('wrappers/rest_client_wrapper', File.dirname(__FILE__)) @wrapper = Rest::Wrappers::RestClientWrapper.new hint = ([:gem] ? "" : "NOTICE: Please upgrade to Ruby 2.X for optimal performance.") puts hint @logger.debug "Using rest-client gem. #{hint}" RestClient.proxy = [:http_proxy] if [:http_proxy] else # use internal client @wrapper = Rest::Wrappers::InternalClientWrapper.new @logger.debug "Using rest internal client. #{hint}" end # Always set this because of the shared post_file in base_wrapper InternalClient.proxy = [:http_proxy] if [:http_proxy] end |
Instance Attribute Details
#gem ⇒ Object
Returns the value of attribute gem.
52 53 54 |
# File 'lib/rest/client.rb', line 52 def gem @gem end |
#logger ⇒ Object
Returns the value of attribute logger.
52 53 54 |
# File 'lib/rest/client.rb', line 52 def logger @logger end |
#options ⇒ Object
Returns the value of attribute options.
52 53 54 |
# File 'lib/rest/client.rb', line 52 def end |
#wrapper ⇒ Object (readonly)
Returns the value of attribute wrapper.
53 54 55 |
# File 'lib/rest/client.rb', line 53 def wrapper @wrapper end |
Instance Method Details
#choose_best_gem ⇒ Object
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 |
# File 'lib/rest/client.rb', line 95 def choose_best_gem gems_to_try = [] #puts "Ruby MAJOR: #{Rest.ruby_major}" if Rest.ruby_major >= 2 gems_to_try << :net_http_persistent gems_to_try << :typhoeus gems_to_try << :rest_client gems_to_try << :internal else # net-http-persistent has issues with ssl and keep-alive connections on ruby < 1.9.3p327 gems_to_try << :typhoeus gems_to_try << :rest_client gems_to_try << :internal end gems_to_try.each_with_index do |g, i| bg = Rest.backing_gems[g] begin require bg.gem_name unless g == :internal @gem = bg.name return @gem rescue LoadError => ex if (i+1) >= gems_to_try.length raise ex end @logger.debug "LoadError on #{bg.name}, trying #{Rest.backing_gems[gems_to_try[i+1]].name}..." end end end |
#close ⇒ Object
241 242 243 |
# File 'lib/rest/client.rb', line 241 def close @wrapper.close end |
#delete(url, req_hash = {}) ⇒ Object
225 226 227 228 229 230 231 |
# File 'lib/rest/client.rb', line 225 def delete(url, req_hash={}) res = nil res = perform_op(:delete, req_hash) do res = @wrapper.delete(url, req_hash) end return res end |
#get(url, req_hash = {}) ⇒ Object
124 125 126 127 128 129 130 |
# File 'lib/rest/client.rb', line 124 def get(url, req_hash={}) res = nil res = perform_op(:get, req_hash) do res = @wrapper.get(url, req_hash) end return res end |
#patch(url, req_hash = {}) ⇒ Object
217 218 219 220 221 222 223 |
# File 'lib/rest/client.rb', line 217 def patch(url, req_hash={}) res = nil res = perform_op(:patch, req_hash) do res = @wrapper.patch(url, req_hash) end return res end |
#perform_op(method, req_hash, options = {}, &blk) ⇒ Object
This will attempt to perform the operation with an exponential backoff on 503 errors. Amazon services throw 503 todo: just make perform_op a method and have it call the wrapper. The block is a waste now.
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 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/rest/client.rb', line 135 def perform_op(method, req_hash, ={}, &blk) set_defaults() max_retries = [:max_retries] || 5 max_follows = [:max_follows] || 10 if [:follow_count] && [:follow_count] >= max_follows raise Rest::RestError, "Too many follows. #{options[:follow_count]}" end current_retry = 0 current_follow = 0 success = false tries = 0 res = nil # todo: typhoeus does retries in the library so it shouldn't do retries here. And we should use the max_retries here as a parameter to typhoeus while current_retry < max_retries && current_follow < max_follows do tries += 1 begin res = yield blk res.tries = tries if res.code >= 300 && res.code < 400 # try new location #p res.headers loc = res.headers["location"] @logger.debug "#{res.code} Received. Trying new location: #{loc}" if loc.nil? raise InvalidResponseError.new("No location header received with #{res.code} status code!") end # options.merge({:max_follows=>options[:max_follows-1]} [:follow_count] ||= 0 [:follow_count] += 1 res = perform_op(method, req_hash, ) do res = @wrapper.send(method, loc, req_hash) end #puts 'X: ' + res.inspect return res end # If it's here, then it's all good break rescue Rest::HttpError => ex if ex.code == 503 raise ex if current_retry == max_retries - 1 pow = (4 ** (current_retry)) * 100 # milliseconds #puts 'pow=' + pow.to_s s = rand * pow #puts 's=' + s.to_s sleep_secs = 1.0 * s / 1000.0 #puts 'sleep for ' + sleep_secs.to_s current_retry += 1 @logger.debug "#{ex.code} Received. Retrying #{current_retry} out of #{max_retries} max in #{sleep_secs} seconds." sleep sleep_secs else raise ex end end end res end |
#post(url, req_hash = {}) ⇒ Object
req_hash options:
-
:body => post body
201 202 203 204 205 206 207 |
# File 'lib/rest/client.rb', line 201 def post(url, req_hash={}) res = nil res = perform_op(:post, req_hash) do res = @wrapper.post(url, req_hash) end return res end |
#post_file(url, req_hash = {}) ⇒ Object
233 234 235 236 237 238 239 |
# File 'lib/rest/client.rb', line 233 def post_file(url, req_hash={}) res = nil res = perform_op(:post_file, req_hash) do res = @wrapper.post_file(url, req_hash) end return res end |
#put(url, req_hash = {}) ⇒ Object
209 210 211 212 213 214 215 |
# File 'lib/rest/client.rb', line 209 def put(url, req_hash={}) res = nil res = perform_op(:put, req_hash) do res = @wrapper.put(url, req_hash) end return res end |
#set_defaults(options) ⇒ Object
193 194 195 196 |
# File 'lib/rest/client.rb', line 193 def set_defaults() [:max_retries] ||= ([:max_retries] || 5) [:max_follows] ||= ([:max_follows] || 10) end |