rack-idempotent 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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