popit 0.0.6 → 0.0.7

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 288679ecd99d837bbce6221def9efc09ed239df6
4
- data.tar.gz: 4ebff4b12ee6e79ce02635c66b5a27578c5bc315
3
+ metadata.gz: 9e107fa8a67b9fb91253acc05db2c906befc9463
4
+ data.tar.gz: 5acea070cae8ef2839b9463406d0a8e00de81938
5
5
  SHA512:
6
- metadata.gz: 742c8c9428d52ad353afef5e377c365022e5f003b3967ea2862df55b3e23fcc985b2911da387f1ba81663fe4e75103c00c6adc3cf23e9f59e4de7b90aa8bf1bd
7
- data.tar.gz: 62e57d47b2e26309385a539dd2fee7b8184b3fa1a3947a5cb6e4d9296cc966e423b1103783daacb661ae32cd91066c8f72db46caff4c7c59be391bccc5ef850f
6
+ metadata.gz: 41a16756393b990c236499ca3ca00ca63ed2cfc1c564543212c1206b17e24d1432af99cc382e6383c2ab34128beceeb825b3dfafc71c4c0f6ed541f2ca77bd66
7
+ data.tar.gz: 6a5a620436db1c783ca726cb94d68968c80de9fdd9d523317b91398eeb9908936cc51cc5058338e2c9b08bdf579bb224a4dcef030ad3bb288fe0746ddacb23bc
data/lib/popit/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class PopIt
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.7"
3
3
  end
data/lib/popit.rb CHANGED
@@ -39,6 +39,8 @@ class PopIt
39
39
  attr_reader :username
40
40
  # The user's password.
41
41
  attr_reader :password
42
+ # The maximum number of retries in case of HTTP 503 Service Unavailable errors.
43
+ attr_reader :max_retries
42
44
 
43
45
  # Initializes a PopIt API client.
44
46
  #
@@ -49,17 +51,21 @@ class PopIt
49
51
  # @option opts [String] :version the PopIt API version, eg "v1"
50
52
  # @option opts [String] :user a user name
51
53
  # @option opts [String] :password the user's password
54
+ # @option opts [String] :max_retries the maximum number of retries in case of
55
+ # HTTP 503 Service Unavailable errors
52
56
  def initialize(opts = {})
53
57
  unless opts.has_key?(:instance_name)
54
58
  raise ArgumentError, 'Missing key :instance_name'
55
59
  end
56
60
 
57
61
  @instance_name = opts[:instance_name]
58
- @host_name = opts[:host_name] || 'popit.mysociety.org'
59
- @port = opts[:port] || 80
60
- @version = opts[:version] || 'v0.1'
62
+ @host_name = opts[:host_name] || 'popit.mysociety.org'
63
+ @port = opts[:port] || 80
64
+ @version = opts[:version] || 'v0.1'
61
65
  @username = opts[:user]
62
66
  @password = opts[:password]
67
+ @max_retries = opts[:max_retries] || 0
68
+
63
69
  end
64
70
 
65
71
  # Sends a GET request.
@@ -101,6 +107,8 @@ class PopIt
101
107
  private
102
108
 
103
109
  def request(http_method, path, opts = {})
110
+ attempts ||= 0
111
+
104
112
  path = "http://#{instance_name}.#{host_name}:#{port}/api/#{version}/#{path}"
105
113
 
106
114
  response = case http_method
@@ -138,6 +146,14 @@ private
138
146
  end
139
147
 
140
148
  response.parsed_response && response.parsed_response['result']
149
+ rescue PopIt::ServiceUnavailable
150
+ attempts += 1
151
+ if attempts <= max_retries
152
+ sleep attempts ** 2
153
+ retry
154
+ else
155
+ raise
156
+ end
141
157
  end
142
158
 
143
159
  def method_missing(*args)
data/spec/popit_spec.rb CHANGED
@@ -7,7 +7,7 @@ require 'yaml'
7
7
  # @see https://github.com/mysociety/popit/blob/master/lib/apps/api/api_v1.js
8
8
  describe PopIt do
9
9
  let :unauthenticated do
10
- PopIt.new :instance_name => 'tttest'
10
+ PopIt.new(:instance_name => 'tttest')
11
11
  end
12
12
 
13
13
  let :authenticated do
@@ -18,13 +18,17 @@ describe PopIt do
18
18
  })
19
19
  end
20
20
 
21
+ let :exponential_backoff do
22
+ PopIt.new(:instance_name => 'tttest', :max_retries => 2)
23
+ end
24
+
21
25
  it 'should fail to send a request to a bad instance' do
22
- api = PopIt.new :instance_name => '47cc67093475061e3d95369d'
26
+ api = PopIt.new(:instance_name => '47cc67093475061e3d95369d')
23
27
  expect { api.persons.get }.to raise_error(PopIt::PageNotFound)
24
28
  end
25
29
 
26
30
  it 'should fail to send a request to a bad version' do
27
- api = PopIt.new :instance_name => 'tttest', :version => 'v0'
31
+ api = PopIt.new(:instance_name => 'tttest', :version => 'v0')
28
32
  expect { api.persons.get }.to raise_error(PopIt::PageNotFound, 'page not found')
29
33
  end
30
34
 
@@ -48,7 +52,7 @@ describe PopIt do
48
52
  end
49
53
 
50
54
  it 'should get one item by name' do
51
- response = unauthenticated.persons.get :name => 'Foo'
55
+ response = unauthenticated.persons.get(:name => 'Foo')
52
56
  response.should be_an(Array)
53
57
  end
54
58
 
@@ -68,11 +72,11 @@ describe PopIt do
68
72
  end
69
73
 
70
74
  it 'should fail to create an item' do
71
- expect {unauthenticated.persons.post :name => 'John Doe', :slug => 'john-doe'}.to raise_error(PopIt::NotAuthenticated, 'not authenticated')
75
+ expect {unauthenticated.persons.post(:name => 'John Doe', :slug => 'john-doe')}.to raise_error(PopIt::NotAuthenticated, 'not authenticated')
72
76
  end
73
77
 
74
78
  it 'should fail to update an item' do
75
- expect {unauthenticated.persons(id).put :id => id, :name => 'John Doe', :slug => 'john-doe'}.to raise_error(PopIt::NotAuthenticated, 'not authenticated')
79
+ expect {unauthenticated.persons(id).put(:id => id, :name => 'John Doe', :slug => 'john-doe')}.to raise_error(PopIt::NotAuthenticated, 'not authenticated')
76
80
  end
77
81
 
78
82
  it 'should fail to delete an item' do
@@ -82,12 +86,12 @@ describe PopIt do
82
86
 
83
87
  context 'when authenticated' do
84
88
  it 'should create, update and delete an item' do
85
- response = authenticated.persons.post :name => 'John Smith', :slug => 'john-smith', :contact_details => [{:type => 'email', :value => 'test@example.com'}]
89
+ response = authenticated.persons.post(:name => 'John Smith', :slug => 'john-smith', :contact_details => [{:type => 'email', :value => 'test@example.com'}])
86
90
  id = response['id']
87
91
  contact_detail_id = response['contact_details'][0]['id']
88
92
  response['name'].should == 'John Smith'
89
93
 
90
- response = authenticated.persons(id).put :id => id, :name => 'John Doe', :slug => 'john-doe'
94
+ response = authenticated.persons(id).put(:id => id, :name => 'John Doe', :slug => 'john-doe')
91
95
  response.should == {
92
96
  'id' => id,
93
97
  'name' => 'John Doe',
@@ -111,5 +115,27 @@ describe PopIt do
111
115
  expect {authenticated.persons(id).get}.to raise_error(PopIt::PageNotFound, "id '#{id}' not found")
112
116
  end
113
117
  end
118
+
119
+ context 'when service unavailable' do
120
+ before :each do
121
+ PopIt.stub(:get) do
122
+ response = Net::HTTPServiceUnavailable.new('1.1', 503, 'Service Unavailable')
123
+ response.stub(:body => '', :code => '503')
124
+ HTTParty::Response.new(HTTParty::Request.new(Net::HTTP::Get, '/'), response, lambda {})
125
+ end
126
+ end
127
+
128
+ it 'should fail immediately' do
129
+ time = Time.now
130
+ expect {unauthenticated.persons.get}.to raise_error(PopIt::ServiceUnavailable)
131
+ Time.now.should be_within(1).of(time)
132
+ end
133
+
134
+ it 'should backoff exponentially' do
135
+ time = Time.now
136
+ expect {exponential_backoff.persons.get}.to raise_error(PopIt::ServiceUnavailable)
137
+ Time.now.should_not be_within(5).of(time)
138
+ end
139
+ end
114
140
  end
115
141
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: popit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Open North
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-08 00:00:00.000000000 Z
11
+ date: 2014-05-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty