excon 0.7.8 → 0.7.9

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of excon might be problematic. Click here for more details.

@@ -13,8 +13,8 @@ Gem::Specification.new do |s|
13
13
  ## If your rubyforge_project name is different, then edit it and comment out
14
14
  ## the sub! line in the Rakefile
15
15
  s.name = 'excon'
16
- s.version = '0.7.8'
17
- s.date = '2011-11-24'
16
+ s.version = '0.7.9'
17
+ s.date = '2011-11-30'
18
18
  s.rubyforge_project = 'excon'
19
19
 
20
20
  ## Make sure your summary is short. The description may be as long
@@ -25,7 +25,7 @@ Gem::Specification.new do |s|
25
25
  ## List the primary authors. If there are a bunch of authors, it's probably
26
26
  ## better to set the email to an email list or something. If you don't have
27
27
  ## a custom homepage, consider using your GitHub URL or the like.
28
- s.authors = ["geemus (Wesley Beary)"]
28
+ s.authors = ["dpiddy (Dan Peterson)", "geemus (Wesley Beary)", "nextmat (Matt Sanders)"]
29
29
  s.email = 'geemus@gmail.com'
30
30
  s.homepage = 'https://github.com/geemus/excon'
31
31
 
@@ -17,6 +17,7 @@ module Excon
17
17
  # @option params [Hash] :query Default query; appended to the 'scheme://host:port/path/' in the form of '?key=value'. Will only be used if params[:query] is not supplied to Connection#request
18
18
  # @option params [String] :scheme The protocol; 'https' causes OpenSSL to be used
19
19
  # @option params [String] :proxy Proxy server; e.g. 'http://myproxy.com:8888'
20
+ # @option params [Fixnum] :retry_limit Set how many times we'll retry a failed request. (Default 4)
20
21
  def initialize(url, params = {})
21
22
  uri = URI.parse(url)
22
23
  @connection = {
@@ -39,6 +40,8 @@ module Excon
39
40
  @proxy = setup_proxy(params[:proxy])
40
41
  end
41
42
 
43
+ self.retry_limit = params[:retry_limit] || DEFAULT_RETRY_LIMIT
44
+
42
45
  if @connection[:scheme] == 'https'
43
46
  # use https_proxy if that has been specified
44
47
  if ENV.has_key?('https_proxy')
@@ -198,7 +201,7 @@ module Excon
198
201
 
199
202
  rescue => request_error
200
203
  if params[:idempotent] && [Excon::Errors::SocketError, Excon::Errors::HTTPStatusError].any? {|ex| request_error.kind_of? ex }
201
- retries_remaining ||= 4
204
+ retries_remaining ||= retry_limit
202
205
  retries_remaining -= 1
203
206
  if retries_remaining > 0
204
207
  if params[:body].respond_to?(:pos=)
@@ -226,6 +229,12 @@ module Excon
226
229
  DEF
227
230
  end
228
231
 
232
+ attr_writer :retry_limit
233
+
234
+ def retry_limit
235
+ @retry_limit ||= DEFAULT_RETRY_LIMIT
236
+ end
237
+
229
238
  private
230
239
 
231
240
  def socket
@@ -1,6 +1,6 @@
1
1
  module Excon
2
2
  unless const_defined?(:VERSION)
3
- VERSION = '0.7.8'
3
+ VERSION = '0.7.9'
4
4
  end
5
5
 
6
6
  unless const_defined?(:CHUNK_SIZE)
@@ -11,6 +11,10 @@ module Excon
11
11
  HTTP_VERBS = %w{connect delete get head options post put trace}
12
12
  end
13
13
 
14
+ unless const_defined?(:DEFAULT_RETRY_LIMIT)
15
+ DEFAULT_RETRY_LIMIT = 4
16
+ end
17
+
14
18
  unless ::IO.const_defined?(:WaitReadable)
15
19
  class ::IO
16
20
  module WaitReadable; end
@@ -22,5 +26,4 @@ module Excon
22
26
  module WaitWritable; end
23
27
  end
24
28
  end
25
-
26
29
  end
@@ -13,34 +13,54 @@ module Excon
13
13
  @read_buffer, @write_buffer = '', ''
14
14
  @eof = false
15
15
 
16
+ connect
17
+ end
18
+
19
+ def connect
20
+ @socket = nil
21
+ exception = nil
22
+
16
23
  addrinfo = if @proxy
17
24
  ::Socket.getaddrinfo(@proxy[:host], @proxy[:port].to_i, nil, ::Socket::Constants::SOCK_STREAM)
18
25
  else
19
26
  ::Socket.getaddrinfo(@params[:host], @params[:port].to_i, nil, ::Socket::Constants::SOCK_STREAM)
20
- end.first
21
-
22
- _, port, _, ip, a_family, s_type = addrinfo
27
+ end
23
28
 
24
- @sockaddr = ::Socket.sockaddr_in(port, ip)
29
+ addrinfo.each do |_, port, _, ip, a_family, s_type|
30
+ # nonblocking connect
31
+ begin
32
+ sockaddr = ::Socket.sockaddr_in(port, ip)
25
33
 
26
- @socket = ::Socket.new(a_family, s_type, 0)
34
+ socket = ::Socket.new(a_family, s_type, 0)
27
35
 
28
- connect
36
+ socket.connect_nonblock(sockaddr)
29
37
 
30
- @socket
31
- end
38
+ @socket = socket
39
+ break
40
+ rescue Errno::EINPROGRESS
41
+ IO.select(nil, [socket], nil, @params[:connect_timeout])
42
+ begin
43
+ socket.connect_nonblock(sockaddr)
32
44
 
33
- def connect
34
- # nonblocking connect
35
- begin
36
- @socket.connect_nonblock(@sockaddr)
37
- rescue Errno::EINPROGRESS
38
- IO.select(nil, [@socket], nil, @params[:connect_timeout])
39
- begin
40
- @socket.connect_nonblock(@sockaddr)
41
- rescue Errno::EISCONN
45
+ @socket = socket
46
+ break
47
+ rescue Errno::EISCONN
48
+ @socket = socket
49
+ break
50
+ rescue SystemCallError => exception
51
+ socket.close
52
+ next
53
+ end
54
+ rescue SystemCallError => exception
55
+ socket.close
56
+ next
42
57
  end
43
58
  end
59
+
60
+ unless @socket
61
+ # this will be our last encountered exception
62
+ raise exception
63
+ end
44
64
  end
45
65
 
46
66
  def read(max_length=nil)
@@ -6,7 +6,7 @@ module Excon
6
6
 
7
7
  undef_method :connect
8
8
  def connect
9
- @socket.connect(@sockaddr)
9
+ @socket = TCPSocket.new(@params[:host], @params[:port])
10
10
  end
11
11
 
12
12
  undef_method :read
@@ -10,7 +10,7 @@ Shindo.tests('Excon request idempotencey') do
10
10
  run_count = 0
11
11
  Excon.stub({:method => :get}) { |params|
12
12
  run_count += 1
13
- if run_count < 4 # First 3 calls fail.
13
+ if run_count <= 3 # First 3 calls fail.
14
14
  raise Excon::Errors::SocketError.new(Exception.new "Mock Error")
15
15
  else
16
16
  {:body => params[:body], :headers => params[:headers], :status => 200}
@@ -53,5 +53,93 @@ Shindo.tests('Excon request idempotencey') do
53
53
  response.status
54
54
  end
55
55
 
56
+ tests("Lowered retry limit with socket erroring first time").returns(200) do
57
+ run_count = 0
58
+ Excon.stub({:method => :get}) { |params|
59
+ run_count += 1
60
+ if run_count <= 1 # First call fails.
61
+ raise Excon::Errors::SocketError.new(Exception.new "Mock Error")
62
+ else
63
+ {:body => params[:body], :headers => params[:headers], :status => 200}
64
+ end
65
+ }
66
+
67
+ connection = Excon.new('http://127.0.0.1:9292')
68
+ connection.retry_limit = 2
69
+ response = connection.request(:method => :get, :idempotent => true, :path => '/some-path')
70
+ response.status
71
+ end
72
+
73
+ tests("Lowered retry limit with socket erroring first 3 times").raises(Excon::Errors::SocketError) do
74
+ run_count = 0
75
+ Excon.stub({:method => :get}) { |params|
76
+ run_count += 1
77
+ if run_count <= 3 # First 3 calls fail.
78
+ raise Excon::Errors::SocketError.new(Exception.new "Mock Error")
79
+ else
80
+ {:body => params[:body], :headers => params[:headers], :status => 200}
81
+ end
82
+ }
83
+
84
+ connection = Excon.new('http://127.0.0.1:9292')
85
+ connection.retry_limit = 2
86
+ response = connection.request(:method => :get, :idempotent => true, :path => '/some-path')
87
+ response.status
88
+ end
89
+
90
+ tests("Raised retry limit with socket erroring first 5 times").returns(200) do
91
+ run_count = 0
92
+ Excon.stub({:method => :get}) { |params|
93
+ run_count += 1
94
+ if run_count <= 5 # First 5 calls fail.
95
+ raise Excon::Errors::SocketError.new(Exception.new "Mock Error")
96
+ else
97
+ {:body => params[:body], :headers => params[:headers], :status => 200}
98
+ end
99
+ }
100
+
101
+ connection = Excon.new('http://127.0.0.1:9292')
102
+ connection.retry_limit = 8
103
+ response = connection.request(:method => :get, :idempotent => true, :path => '/some-path')
104
+ response.status
105
+ end
106
+
107
+ tests("Raised retry limit with socket erroring first 9 times").raises(Excon::Errors::SocketError) do
108
+ run_count = 0
109
+ Excon.stub({:method => :get}) { |params|
110
+ run_count += 1
111
+ if run_count <= 9 # First 9 calls fail.
112
+ raise Excon::Errors::SocketError.new(Exception.new "Mock Error")
113
+ else
114
+ {:body => params[:body], :headers => params[:headers], :status => 200}
115
+ end
116
+ }
117
+
118
+ connection = Excon.new('http://127.0.0.1:9292')
119
+ connection.retry_limit = 8
120
+ response = connection.request(:method => :get, :idempotent => true, :path => '/some-path')
121
+ response.status
122
+ end
123
+
124
+ tests("Retry limit in constructor with socket erroring first 5 times").returns(200) do
125
+ run_count = 0
126
+
127
+ connection = Excon.new('http://127.0.0.1:9292', :retry_limit => 6)
128
+ tests("setter sets").returns(6) do
129
+ connection.retry_limit
130
+ end
131
+
132
+ Excon.stub({:method => :get}) { |params|
133
+ run_count += 1
134
+ if run_count <= 5 # First 5 calls fail.
135
+ raise Excon::Errors::SocketError.new(Exception.new "Mock Error")
136
+ else
137
+ {:body => params[:body], :headers => params[:headers], :status => 200}
138
+ end
139
+ }
140
+ response = connection.request(:method => :get, :idempotent => true, :path => '/some-path')
141
+ response.status
142
+ end
143
+
56
144
  Excon.mock = false
57
145
  end
@@ -5,18 +5,18 @@ Shindo.tests('Excon request methods') do
5
5
  tests 'one-offs' do
6
6
 
7
7
  tests('Excon.get').returns('GET') do
8
- Excon.get('http://127.0.0.1:9292').body
8
+ Excon.get('http://localhost:9292').body
9
9
  end
10
10
 
11
11
  tests('Excon.post').returns('POST') do
12
- Excon.post('http://127.0.0.1:9292').body
12
+ Excon.post('http://localhost:9292').body
13
13
  end
14
14
 
15
15
  end
16
16
 
17
17
  tests 'with a connection object' do
18
18
 
19
- connection = Excon.new('http://127.0.0.1:9292')
19
+ connection = Excon.new('http://localhost:9292')
20
20
 
21
21
  tests('connection.get').returns('GET') do
22
22
  connection.get.body
@@ -67,10 +67,12 @@ def rackup_path(*parts)
67
67
  end
68
68
 
69
69
  def with_rackup(name)
70
+ GC.disable
70
71
  pid, w, r, e = Open4.popen4("rackup #{rackup_path(name)}")
71
72
  until e.gets =~ /HTTPServer#start:/; end
72
73
  yield
73
74
  ensure
75
+ GC.enable
74
76
  Process.kill(9, pid)
75
77
  end
76
78
 
metadata CHANGED
@@ -1,72 +1,83 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: excon
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
4
+ hash: 17
5
+ prerelease:
5
6
  segments:
6
7
  - 0
7
8
  - 7
8
- - 8
9
- version: 0.7.8
9
+ - 9
10
+ version: 0.7.9
10
11
  platform: ruby
11
12
  authors:
13
+ - dpiddy (Dan Peterson)
12
14
  - geemus (Wesley Beary)
15
+ - nextmat (Matt Sanders)
13
16
  autorequire:
14
17
  bindir: bin
15
18
  cert_chain: []
16
19
 
17
- date: 2011-11-24 00:00:00 -06:00
20
+ date: 2011-11-30 00:00:00 -04:00
18
21
  default_executable:
19
22
  dependencies:
20
23
  - !ruby/object:Gem::Dependency
21
- name: open4
22
- prerelease: false
23
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
24
26
  requirements:
25
27
  - - ">="
26
28
  - !ruby/object:Gem::Version
29
+ hash: 3
27
30
  segments:
28
31
  - 0
29
32
  version: "0"
30
- type: :development
31
33
  version_requirements: *id001
32
- - !ruby/object:Gem::Dependency
33
- name: rake
34
+ name: open4
34
35
  prerelease: false
36
+ type: :development
37
+ - !ruby/object:Gem::Dependency
35
38
  requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
36
40
  requirements:
37
41
  - - ">="
38
42
  - !ruby/object:Gem::Version
43
+ hash: 3
39
44
  segments:
40
45
  - 0
41
46
  version: "0"
42
- type: :development
43
47
  version_requirements: *id002
44
- - !ruby/object:Gem::Dependency
45
- name: shindo
48
+ name: rake
46
49
  prerelease: false
50
+ type: :development
51
+ - !ruby/object:Gem::Dependency
47
52
  requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
48
54
  requirements:
49
55
  - - "="
50
56
  - !ruby/object:Gem::Version
57
+ hash: 23
51
58
  segments:
52
59
  - 0
53
60
  - 2
54
61
  - 0
55
62
  version: 0.2.0
56
- type: :development
57
63
  version_requirements: *id003
58
- - !ruby/object:Gem::Dependency
59
- name: sinatra
64
+ name: shindo
60
65
  prerelease: false
66
+ type: :development
67
+ - !ruby/object:Gem::Dependency
61
68
  requirement: &id004 !ruby/object:Gem::Requirement
69
+ none: false
62
70
  requirements:
63
71
  - - ">="
64
72
  - !ruby/object:Gem::Version
73
+ hash: 3
65
74
  segments:
66
75
  - 0
67
76
  version: "0"
68
- type: :development
69
77
  version_requirements: *id004
78
+ name: sinatra
79
+ prerelease: false
80
+ type: :development
70
81
  description: EXtended http(s) CONnections
71
82
  email: geemus@gmail.com
72
83
  executables: []
@@ -133,23 +144,27 @@ rdoc_options:
133
144
  require_paths:
134
145
  - lib
135
146
  required_ruby_version: !ruby/object:Gem::Requirement
147
+ none: false
136
148
  requirements:
137
149
  - - ">="
138
150
  - !ruby/object:Gem::Version
151
+ hash: 3
139
152
  segments:
140
153
  - 0
141
154
  version: "0"
142
155
  required_rubygems_version: !ruby/object:Gem::Requirement
156
+ none: false
143
157
  requirements:
144
158
  - - ">="
145
159
  - !ruby/object:Gem::Version
160
+ hash: 3
146
161
  segments:
147
162
  - 0
148
163
  version: "0"
149
164
  requirements: []
150
165
 
151
166
  rubyforge_project: excon
152
- rubygems_version: 1.3.6
167
+ rubygems_version: 1.6.2
153
168
  signing_key:
154
169
  specification_version: 2
155
170
  summary: speed, persistence, http(s)