httpray 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 94354672b454e3ffb1f53a0d0704157c4a3208c2
4
- data.tar.gz: 755940a03eedb6095bf8b8c7c2a5174b85d3125e
3
+ metadata.gz: 85f7ee216d286ddb7923f073086321aaad64ed36
4
+ data.tar.gz: c8a0b734b3565a1bf8a9391ce0bee417c1e015c5
5
5
  SHA512:
6
- metadata.gz: 18e91441b0908e96d8f45c2d76fce167c855dd5b4526976b811e7918c2932a52d98eba43e497d2816fb06cfeede05cfdab531e18c9858b2a5459840753967127
7
- data.tar.gz: c94caa608c92993d0856aada6f22fafbf9498950d2816b3219a32de4502cf6c4080eaa364210c0133877d20d0e8bd0113fb7c0422bf2624a80fcfc355375f1bf
6
+ metadata.gz: d1f1f90d6d72dceeba9ed80b7ba01247e0043ee5933737d0f9cc17aa9f24f15393ebdd882be7c13d2afee162256eb319b0f4f562e16486b9c659ff524c276082
7
+ data.tar.gz: b84071e158ce7b043b56b77573159cd954a43983f9dfc94b56385b7acd9780303e8bca198e4c13ff281dca047dd7a6af7f1d69f834755b089dc9d4675d2b2ef7
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- HTTPray (1.0.0)
4
+ httpray (1.1.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -11,8 +11,7 @@ PLATFORMS
11
11
  ruby
12
12
 
13
13
  DEPENDENCIES
14
- HTTPray!
15
- bundler (>= 1.2)
14
+ httpray!
16
15
 
17
16
  BUNDLED WITH
18
17
  1.13.6
data/README.md CHANGED
@@ -43,7 +43,13 @@ socket.close
43
43
  # use a persistent connection to keep the party rolling
44
44
  # will automatically reconnect if connection is lost
45
45
  uri = URI.parse("https://your.diety/pray")
46
- ark = HTTPray::Connection.new(uri.host, uri.port, 1, OpenSSL::SSL::SSLContext.new)
46
+ ark = HTTPray::Connection.new(
47
+ uri.host,
48
+ uri.port,
49
+ 1, #timeout
50
+ OpenSSL::SSL::SSLContext.new, #ssl context
51
+ 1, #retries on error
52
+ 10) #seconds to wait after all retries failed before trying again on a subsequent request
47
53
  ark.request("POST", uri,
48
54
  {"Content-Type" => "application/prayer"},
49
55
  "Why did it have to be snakes?")
@@ -58,7 +64,7 @@ ark.request("POST", uri,
58
64
 
59
65
  HTTPray has minimal convenience and sanitization features because I didn't need them. All that it does is fill in the Host, User-Agent, Accept, and Content-Length headers for you. The body must be a string, so convert it yourself first. The URI can be a `URI` or a `String` that will go through `URI.parse`. You're welcome.
60
66
 
61
- If you're using `Connection` with TLS you need to provide an `OpenSSL::SSL::SSLContext` when creating the connection. `HTTPray.request!` is more forgiving and if you don't give it one it will create it for you if needed.
67
+ If you're using `Connection` with TLS you need to provide an `OpenSSL::SSL::SSLContext` when creating the connection. `HTTPray.request!` is more forgiving and if you don't give it one it will create it for you if needed. `Connection` also has some fancy retry and circuit breaker logic so you can assume your request always writes even if it doesn't without major performance impacts.
62
68
 
63
69
  Timeout support does not extend to the response since you just get back a `Socket`. You're own your own for how you want to handle that.
64
70
 
@@ -6,6 +6,7 @@ require_relative 'httpray/version'
6
6
 
7
7
  module HTTPray
8
8
  class Timeout < StandardError; end
9
+ class CircuitBreakerError < StandardError; end
9
10
 
10
11
  DEFAULT_HEADERS = {
11
12
  "User-Agent" => "HTTPray #{VERSION}",
@@ -14,12 +15,14 @@ module HTTPray
14
15
  }.freeze
15
16
 
16
17
  class Connection
17
- def initialize(host, port, timeout = 1, ssl_context = nil, retry_count = 1)
18
+ def initialize(host, port, timeout = 1, ssl_context = nil, retry_count = 1, retry_circuit_breaker_interval = 10)
18
19
  @host = host
19
20
  @port = port
20
21
  @timeout = timeout
21
22
  @ssl_context = ssl_context
22
23
  @retry_count = retry_count
24
+ @retry_circuit_breaker_interval = retry_circuit_breaker_interval
25
+ @next_retry_time = Time.now - @retry_circuit_breaker_interval
23
26
  @socket = connect
24
27
  end
25
28
 
@@ -29,12 +32,13 @@ module HTTPray
29
32
  @socket
30
33
  end
31
34
 
35
+ def reconnect
36
+ @socket = connect unless @socket && !socket.closed?
37
+ end
38
+
32
39
  def request!(method, uri, headers = {}, body = nil)
33
40
  tries ||= 0
34
- begin
35
- IO.select([@socket], [@socket], [@socket], @timeout) if @socket
36
- rescue; end
37
- @socket = connect unless @socket && !@socket.closed?
41
+ reconnect
38
42
  socket = @socket
39
43
  uri = URI.parse(uri) unless URI === uri
40
44
 
@@ -48,11 +52,19 @@ module HTTPray
48
52
  socket.write_nonblock "\r\n"
49
53
  socket.write_nonblock body if body
50
54
  socket
51
- rescue
52
- @socket.close
53
- if tries < @retry_count
54
- tries += 1
55
- retry
55
+ rescue => error
56
+ @socket.close unless @socket.closed?
57
+ now = Time.now
58
+ if now > @next_retry_time
59
+ if tries < @retry_count
60
+ tries += 1
61
+ retry
62
+ else
63
+ @next_retry_time = now + @retry_circuit_breaker_interval
64
+ raise error
65
+ end
66
+ else
67
+ raise HTTPray::CircuitBreakerError
56
68
  end
57
69
  end
58
70
 
@@ -1,3 +1,3 @@
1
1
  module HTTPray
2
- VERSION = "1.1.1".freeze
2
+ VERSION = "1.1.2".freeze
3
3
  end
@@ -106,4 +106,19 @@ class HTTPrayTest < MiniTest::Test
106
106
  ark.request("GET", uri, {"Connection" => ""})
107
107
  end
108
108
  end
109
+ def test_retries_stopped_by_circuit_breaker
110
+ uri = URI.parse("http://httpbin.org/deny")
111
+ ark = HTTPray::Connection.new(uri.host, uri.port, 1, nil, 0, 2)
112
+ # force retries to expire
113
+ ark.socket.stub(:write_nonblock, lambda { |*args| raise "Broken pipe" }) do
114
+ assert_raises RuntimeError do; ark.request("GET", uri, {"Connection" => ""}); end
115
+ end
116
+ ark.stub(:reconnect, ark.socket) do #prevent reconnect of closed socket from previous error
117
+ ark.socket.stub(:write_nonblock, lambda { |*args| raise "Broken pipe" }) do
118
+ assert_raises HTTPray::CircuitBreakerError do; ark.request("GET", uri, {"Connection" => ""}); end
119
+ end
120
+ end
121
+ sleep(2)
122
+ ark.request("GET", uri, {"Connection" => ""})
123
+ end
109
124
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: httpray
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - G Gordon Worley III