rack-idempotent 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  class Idempotent
3
- VERSION = "0.0.1"
3
+ VERSION = "0.0.2"
4
4
  end
5
5
  end
@@ -3,7 +3,8 @@ require "rack-idempotent/version"
3
3
  module Rack
4
4
  class Idempotent
5
5
  RETRY_LIMIT = 5
6
- IDEMPOTENT_HTTP_CODES = [502, 503, 504, 408]
6
+ RETRY_HTTP_CODES = [502, 503, 504]
7
+ IDEMPOTENT_HTTP_CODES = [*RETRY_HTTP_CODES, 408]
7
8
  IDEMPOTENT_ERROR_CLASSES = [Errno::ETIMEDOUT, Errno::ECONNREFUSED, Errno::EHOSTUNREACH]
8
9
 
9
10
  class RetryLimitExceeded < Exception
@@ -24,6 +25,9 @@ module Rack
24
25
  end
25
26
  end
26
27
 
28
+ class Retryable < StandardError
29
+ end
30
+
27
31
  def initialize(app)
28
32
  @app= app
29
33
  end
@@ -38,15 +42,26 @@ module Rack
38
42
  raise HTTPException.new(status, headers, body) if IDEMPOTENT_HTTP_CODES.include?(status)
39
43
  env.merge!(dup_env)
40
44
  [status, headers, body]
41
- rescue *IDEMPOTENT_ERROR_CLASSES, HTTPException => ie
45
+ rescue *IDEMPOTENT_ERROR_CLASSES, HTTPException, Retryable => ie
42
46
  idempotent_exceptions << ie
43
47
  if env['client.retries'] > RETRY_LIMIT - 1
44
48
  raise(RetryLimitExceeded.new(idempotent_exceptions))
45
49
  else
46
- env['client.retries'] += 1
47
- retry
50
+ if retry?(status, env["REQUEST_METHOD"])
51
+ env['client.retries'] += 1
52
+ retry
53
+ else
54
+ raise
55
+ end
48
56
  end
49
57
  end
50
58
  end
59
+
60
+ private
61
+
62
+ def retry?(response_status, request_method)
63
+ RETRY_HTTP_CODES.include?(response_status) || request_method == "GET"
64
+ end
65
+
51
66
  end
52
67
  end
@@ -37,6 +37,14 @@ describe Rack::Idempotent do
37
37
  env['client.retries'].should == 2
38
38
  end
39
39
 
40
+ it "should retry Rack::Idempotent::Retryable" do
41
+ RaiseUp.errors = [Rack::Idempotent::Retryable, Rack::Idempotent::Retryable]
42
+ client.get("/alsodoesntmatter")
43
+
44
+ env = CaptureEnv.env
45
+ env['client.retries'].should == 2
46
+ end
47
+
40
48
  it "should raise Rack::Idempotent::RetryLimitExceeded when retry limit is reached" do
41
49
  RaiseUp.errors = (Rack::Idempotent::RETRY_LIMIT + 1).times.map{|i| Errno::ETIMEDOUT}
42
50
 
@@ -47,7 +55,7 @@ describe Rack::Idempotent do
47
55
  end
48
56
 
49
57
  [502, 503, 504, 408].each do |code|
50
- it "retries #{code}" do
58
+ it "retries GET #{code}" do
51
59
  RaiseUp.errors = [code]
52
60
  client.get("/something")
53
61
  env = CaptureEnv.env
@@ -55,6 +63,24 @@ describe Rack::Idempotent do
55
63
  end
56
64
  end
57
65
 
66
+ [502, 503, 504].each do |code|
67
+ it "retries POST #{code}" do
68
+ RaiseUp.errors = [code]
69
+ client.post("/something")
70
+ env = CaptureEnv.env
71
+ env['client.retries'].should == 1
72
+ end
73
+ end
74
+
75
+ it "doesn't retry POST when return code is 408" do
76
+ RaiseUp.errors = [408]
77
+ lambda do
78
+ client.post("/something")
79
+ end.should raise_error(Rack::Idempotent::HTTPException)
80
+ env = CaptureEnv.env
81
+ env['client.retries'].should == 0
82
+ end
83
+
58
84
  it "should store exceptions raised" do
59
85
  RaiseUp.errors = [502, Errno::ECONNREFUSED, 408, 504, Errno::EHOSTUNREACH, Errno::ETIMEDOUT]
60
86
  errors = RaiseUp.errors.dup
metadata CHANGED
@@ -1,23 +1,33 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: rack-idempotent
3
- version: !ruby/object:Gem::Version
4
- version: 0.0.1
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 2
10
+ version: 0.0.2
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Ines Sombra
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2012-01-17 00:00:00.000000000 Z
17
+
18
+ date: 2012-02-07 00:00:00 Z
13
19
  dependencies: []
20
+
14
21
  description: Retry logic for rack-client
15
- email:
22
+ email:
16
23
  - isombra@engineyard.com
17
24
  executables: []
25
+
18
26
  extensions: []
27
+
19
28
  extra_rdoc_files: []
20
- files:
29
+
30
+ files:
21
31
  - .gitignore
22
32
  - .travis.yml
23
33
  - Gemfile
@@ -29,30 +39,39 @@ files:
29
39
  - rack-idempotent.gemspec
30
40
  - spec/rack-idempotent_spec.rb
31
41
  - spec/spec_helper.rb
32
- homepage: ''
42
+ homepage: ""
33
43
  licenses: []
44
+
34
45
  post_install_message:
35
46
  rdoc_options: []
36
- require_paths:
47
+
48
+ require_paths:
37
49
  - lib
38
- required_ruby_version: !ruby/object:Gem::Requirement
50
+ required_ruby_version: !ruby/object:Gem::Requirement
39
51
  none: false
40
- requirements:
41
- - - ! '>='
42
- - !ruby/object:Gem::Version
43
- version: '0'
44
- required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ hash: 3
56
+ segments:
57
+ - 0
58
+ version: "0"
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
60
  none: false
46
- requirements:
47
- - - ! '>='
48
- - !ruby/object:Gem::Version
49
- version: '0'
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ hash: 3
65
+ segments:
66
+ - 0
67
+ version: "0"
50
68
  requirements: []
69
+
51
70
  rubyforge_project:
52
71
  rubygems_version: 1.8.10
53
72
  signing_key:
54
73
  specification_version: 3
55
74
  summary: Retry logic for rack-client
56
- test_files:
75
+ test_files:
57
76
  - spec/rack-idempotent_spec.rb
58
77
  - spec/spec_helper.rb