faraday-conductivity 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ log/
data/README.md CHANGED
@@ -140,6 +140,36 @@ The User-Agent will looks like this on my machine:
140
140
  MarketingSite/1.1 (iain.local; iain; 30360) ruby/1.9.3 (327; x86_64-darwin12.2.0)
141
141
  ```
142
142
 
143
+ ### Repeater
144
+
145
+ The Repeater will retry your requests until they succeed. This is handy for
146
+ reaching servers that are not too reliable.
147
+
148
+ ``` ruby
149
+ connection = Faraday.new(url: "http://slow.website.com") do |faraday|
150
+ faraday.use :repeater, retries: 6, mode: :rapid
151
+ end
152
+ ```
153
+
154
+ The `retries` parameter specifies how many times to retry before succeeding.
155
+
156
+ The `mode` parameter specifies how long to wait before retrying. `:rapid` will
157
+ retry instantly, `:one`, will wait one second between retries, `:linear` and
158
+ `:exponential` will retry longer and longer after every retry.
159
+
160
+ It's also possible to specify your own pattern by providing a lambda, that
161
+ returns the number of seconds to wait. For example:
162
+
163
+ ``` ruby
164
+ connection = Faraday.new(url: "http://slow.website.com") do |faraday|
165
+ faraday.use :repeater, retries: 6, pattern: ->(n) { rand < 0.5 ? 10 : 2 }
166
+ end
167
+ ```
168
+
169
+ You can use the repeater together with the `raise_error` middleware to also
170
+ retry after getting 404s and other succeeded requests, but failed statuses.
171
+
172
+
143
173
  ## Contributing
144
174
 
145
175
  1. Fork it
@@ -22,4 +22,5 @@ Gem::Specification.new do |gem|
22
22
  gem.add_development_dependency "rake"
23
23
  gem.add_development_dependency "rspec"
24
24
  gem.add_development_dependency "pry"
25
+ gem.add_development_dependency "service_double"
25
26
  end
@@ -7,6 +7,7 @@ require "faraday/conductivity/mimetype"
7
7
  require "faraday/conductivity/request_id"
8
8
  require "faraday/conductivity/request_id_filter"
9
9
  require "faraday/conductivity/user_agent"
10
+ require "faraday/conductivity/repeater"
10
11
 
11
12
  module Faraday
12
13
  module Conductivity
@@ -15,5 +16,6 @@ module Faraday
15
16
  register_middleware :request, :user_agent => Faraday::Conductivity::UserAgent
16
17
  register_middleware :request, :request_id => Faraday::Conductivity::RequestId
17
18
  register_middleware :request, :mimetype => Faraday::Conductivity::Mimetype
19
+ register_middleware :middleware, :repeater => Faraday::Conductivity::Repeater
18
20
  end
19
21
 
@@ -0,0 +1,61 @@
1
+ module Faraday
2
+ module Conductivity
3
+ class Repeater < Faraday::Middleware
4
+
5
+ PATTERNS = {
6
+ :rapid => lambda { |n| 0 },
7
+ :one => lambda { |n| 1 },
8
+ :linear => lambda { |n| n },
9
+ :exponential => lambda { |n| n ** 2 },
10
+ }
11
+
12
+ def initialize(app, options = {})
13
+ @app = app
14
+ @retries = options[:retries] || 10
15
+
16
+ if mode = options[:mode]
17
+ @pattern = build_pattern(PATTERNS.fetch(mode))
18
+ elsif pattern = options[:pattern]
19
+ @pattern = build_pattern(pattern)
20
+ else
21
+ @pattern = build_pattern(PATTERNS.fetch(:exponential))
22
+ end
23
+ end
24
+
25
+ def call(env)
26
+ tries = 0
27
+ begin
28
+ @app.call(env)
29
+ rescue Faraday::Error::ClientError
30
+ if tries < @retries
31
+ tries += 1
32
+ @pattern.wait(tries)
33
+ retry
34
+ else
35
+ raise
36
+ end
37
+ end
38
+ end
39
+
40
+ def build_pattern(pattern)
41
+ Pattern.new(pattern)
42
+ end
43
+
44
+ class Pattern
45
+
46
+ def initialize(pattern)
47
+ @pattern = pattern
48
+ end
49
+
50
+ def wait(num)
51
+ seconds = @pattern.call(num)
52
+ if seconds != 0
53
+ sleep num
54
+ end
55
+ end
56
+
57
+ end
58
+
59
+ end
60
+ end
61
+ end
@@ -1,5 +1,5 @@
1
1
  module Faraday
2
2
  module Conductivity
3
- VERSION = "0.0.4"
3
+ VERSION = "0.1.0"
4
4
  end
5
5
  end
@@ -0,0 +1,21 @@
1
+ count = 0
2
+
3
+ get "/" do
4
+ 200
5
+ end
6
+
7
+ delete "/" do
8
+ count = 0
9
+ 200
10
+ end
11
+
12
+ get "/unreliable/:max" do |max|
13
+ max = Integer(max)
14
+ count += 1
15
+ if count <= max
16
+ sleep 5
17
+ "slow"
18
+ else
19
+ "fast"
20
+ end
21
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe Faraday::Conductivity::Repeater do
4
+
5
+ let(:connection) {
6
+ Faraday.new(url: $service_double_url) { |faraday|
7
+ faraday.use :repeater, mode: :rapid, retries: 6
8
+ faraday.adapter Faraday.default_adapter
9
+ }
10
+ }
11
+
12
+ it "retries after timeouts" do
13
+ get_with_max(4).body.should eq "fast"
14
+ end
15
+
16
+ it "gives up after a number of retries" do
17
+ expect { get_with_max(9) }.to raise_error(Faraday::Error::TimeoutError)
18
+ end
19
+
20
+ it "waits according to a pattern" do
21
+ pattern = double :pattern
22
+ Faraday::Conductivity::Repeater::Pattern.should_receive(:new).and_return(pattern)
23
+ pattern.should_receive(:wait).with(1).ordered
24
+ pattern.should_receive(:wait).with(2).ordered
25
+ pattern.should_receive(:wait).with(3).ordered
26
+ get_with_max(3)
27
+ end
28
+
29
+ def get_with_max(num)
30
+ connection.get("/unreliable/#{num}") { |req|
31
+ req.options[:timeout] = 1
32
+ req.options[:open_timeout] = 1
33
+ }
34
+ end
35
+
36
+ end
data/spec/spec_helper.rb CHANGED
@@ -34,3 +34,12 @@ RSpec.configure do |config|
34
34
  config.order = 'random'
35
35
  config.include SpecHelper
36
36
  end
37
+
38
+ require 'service_double'
39
+
40
+ $service_double_url = "http://localhost:3434"
41
+
42
+ $service_double = ServiceDouble.hook_into(:rspec) do |config|
43
+ config.server = File.expand_path('../fake_server.rb', __FILE__)
44
+ config.url = $service_double_url
45
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: faraday-conductivity
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-14 00:00:00.000000000 Z
12
+ date: 2013-03-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: faraday
@@ -75,6 +75,22 @@ dependencies:
75
75
  - - ! '>='
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: service_double
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
78
94
  description: Extra Faraday middleware, geared towards a service oriented architecture.
79
95
  email:
80
96
  - iain@iain.nl
@@ -92,12 +108,15 @@ files:
92
108
  - lib/faraday/conductivity.rb
93
109
  - lib/faraday/conductivity/extended_logging.rb
94
110
  - lib/faraday/conductivity/mimetype.rb
111
+ - lib/faraday/conductivity/repeater.rb
95
112
  - lib/faraday/conductivity/request_id.rb
96
113
  - lib/faraday/conductivity/request_id_filter.rb
97
114
  - lib/faraday/conductivity/user_agent.rb
98
115
  - lib/faraday/conductivity/version.rb
116
+ - spec/fake_server.rb
99
117
  - spec/middleware/extended_logging_spec.rb
100
118
  - spec/middleware/mimetype_spec.rb
119
+ - spec/middleware/repeater_spec.rb
101
120
  - spec/middleware/request_id_spec.rb
102
121
  - spec/middleware/user_agent_spec.rb
103
122
  - spec/spec_helper.rb
@@ -127,8 +146,10 @@ signing_key:
127
146
  specification_version: 3
128
147
  summary: Extra Faraday middleware, geared towards a service oriented architecture.
129
148
  test_files:
149
+ - spec/fake_server.rb
130
150
  - spec/middleware/extended_logging_spec.rb
131
151
  - spec/middleware/mimetype_spec.rb
152
+ - spec/middleware/repeater_spec.rb
132
153
  - spec/middleware/request_id_spec.rb
133
154
  - spec/middleware/user_agent_spec.rb
134
155
  - spec/spec_helper.rb