grocer 0.0.3 → 0.0.4

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.
data/README.md CHANGED
@@ -32,15 +32,20 @@ pusher = Grocer.pusher(
32
32
  certificate: "/path/to/cert.pem", # required
33
33
  passphrase: "", # optional
34
34
  gateway: "gateway.push.apple.com", # optional; See note below.
35
- port: 2195 # optional
35
+ port: 2195, # optional
36
+ retries: 3 # optional
36
37
  )
37
38
  ```
38
39
 
39
- **NOTE**: The `gateway` option defaults to `gateway.push.apple.com`
40
- **only** when running in a production environement, as determined by
41
- either the `RAILS_ENV` or `RACK_ENV` environment variables. In all other
42
- cases, it defaults to the sandbox gateway,
43
- `gateway.sandbox.push.apple.com`.
40
+ #### Notes
41
+
42
+ * `gateway`: Defaults to `gateway.push.apple.com` **only** when running in a
43
+ production environment, as determined by either the `RAILS_ENV` or
44
+ `RACK_ENV` environment variables. In all other cases, it defaults to the
45
+ sandbox gateway, `gateway.sandbox.push.apple.com`.
46
+ * `retries`: The number of times **grocer** will retry writing to or reading
47
+ from the Apple Push Notification Service before raising any errors to client
48
+ code.
44
49
 
45
50
  ### Sending Notifications
46
51
 
@@ -80,6 +85,7 @@ feedback = Grocer.feedback(
80
85
  passphrase: "", # optional
81
86
  gateway: "feedback.push.apple.com", # optional; See note below.
82
87
  port: 2196 # optional
88
+ retries: 3 # optional
83
89
  )
84
90
 
85
91
  feedback.each do |attempt|
@@ -87,11 +93,15 @@ feedback.each do |attempt|
87
93
  end
88
94
  ```
89
95
 
90
- **NOTE**: The `gateway` option defaults to `feedback.push.apple.com`
91
- **only** when running in a production environement, as determined by
92
- either the `RAILS_ENV` or `RACK_ENV` environment variables. In all other
93
- cases, it defaults to the sandbox gateway,
94
- `feedback.sandbox.push.apple.com`.
96
+ #### Notes
97
+
98
+ * `gateway`: Defaults to `feedback.push.apple.com` **only** when running in a
99
+ production environment, as determined by either the `RAILS_ENV` or
100
+ `RACK_ENV` environment variables. In all other cases, it defaults to the
101
+ sandbox gateway, `feedback.sandbox.push.apple.com`.
102
+ * `retries`: The number of times **grocer** will retry writing to or reading
103
+ from the Apple Push Notification Service before raising any errors to client
104
+ code.
95
105
 
96
106
  ### Device Token
97
107
 
@@ -6,23 +6,24 @@ require 'grocer/ssl_connection'
6
6
 
7
7
  module Grocer
8
8
  class Connection
9
- attr_reader :certificate, :passphrase, :gateway, :port
9
+ attr_reader :certificate, :passphrase, :gateway, :port, :retries
10
10
 
11
11
  def initialize(options = {})
12
12
  @certificate = options.fetch(:certificate) { fail NoCertificateError }
13
13
  @gateway = options.fetch(:gateway) { fail NoGatewayError }
14
14
  @port = options.fetch(:port) { fail NoPortError }
15
15
  @passphrase = options.fetch(:passphrase) { nil }
16
+ @retries = options.fetch(:retries) { 3 }
16
17
  end
17
18
 
18
19
  def read(size = nil, buf = nil)
19
- with_open_connection do
20
+ with_connection do
20
21
  ssl.read(size, buf)
21
22
  end
22
23
  end
23
24
 
24
25
  def write(content)
25
- with_open_connection do
26
+ with_connection do
26
27
  ssl.write(content)
27
28
  end
28
29
  end
@@ -40,9 +41,25 @@ module Grocer
40
41
  port: port)
41
42
  end
42
43
 
43
- def with_open_connection(&block)
44
- ssl.connect unless ssl.connected?
45
- block.call
44
+ def destroy_connection
45
+ return unless @ssl_connection
46
+
47
+ @ssl_connection.disconnect rescue nil
48
+ @ssl_connection = nil
49
+ end
50
+
51
+ def with_connection
52
+ attempts = 1
53
+ begin
54
+ ssl.connect unless ssl.connected?
55
+ yield
56
+ rescue StandardError, Errno::EPIPE
57
+ raise unless attempts < @retries
58
+
59
+ destroy_connection
60
+ attempts += 1
61
+ retry
62
+ end
46
63
  end
47
64
  end
48
65
  end
@@ -1,3 +1,3 @@
1
1
  module Grocer
2
- VERSION = '0.0.3'
2
+ VERSION = '0.0.4'
3
3
  end
@@ -5,7 +5,8 @@ describe Grocer::Connection do
5
5
  subject { described_class.new(connection_options) }
6
6
  let(:connection_options) { { certificate: '/path/to/cert.pem',
7
7
  gateway: 'push.example.com',
8
- port: 443 } }
8
+ port: 443,
9
+ retries: 3 } }
9
10
  let(:ssl) { stub_everything('SSLConnection') }
10
11
  before do
11
12
  Grocer::SSLConnection.stubs(:new).returns(ssl)
@@ -47,6 +48,10 @@ describe Grocer::Connection do
47
48
  subject.port.should == 443
48
49
  end
49
50
 
51
+ it 'can be initialized with a number of retries' do
52
+ subject.retries.should == 3
53
+ end
54
+
50
55
  context 'an open SSLConnection' do
51
56
  before do
52
57
  ssl.stubs(:connected?).returns(true)
@@ -80,4 +85,18 @@ describe Grocer::Connection do
80
85
  ssl.should have_received(:read).with(42, 'IO')
81
86
  end
82
87
  end
88
+
89
+ describe 'retries' do
90
+ [SocketError, OpenSSL::SSL::SSLError, Errno::EPIPE].each do |error|
91
+ it "retries #read in the case of an #{error}" do
92
+ ssl.stubs(:read).raises(error).then.returns(42)
93
+ subject.read
94
+ end
95
+
96
+ it "retries #write in the case of an #{error}" do
97
+ ssl.stubs(:write).raises(error).then.returns(42)
98
+ subject.write("abc123")
99
+ end
100
+ end
101
+ end
83
102
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grocer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -15,7 +15,7 @@ date: 2012-04-02 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rspec
18
- requirement: &70358032520280 !ruby/object:Gem::Requirement
18
+ requirement: &70235826824560 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ~>
@@ -23,10 +23,10 @@ dependencies:
23
23
  version: 2.9.0
24
24
  type: :development
25
25
  prerelease: false
26
- version_requirements: *70358032520280
26
+ version_requirements: *70235826824560
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: pry
29
- requirement: &70358032519500 !ruby/object:Gem::Requirement
29
+ requirement: &70235826838540 !ruby/object:Gem::Requirement
30
30
  none: false
31
31
  requirements:
32
32
  - - ~>
@@ -34,10 +34,10 @@ dependencies:
34
34
  version: 0.9.8
35
35
  type: :development
36
36
  prerelease: false
37
- version_requirements: *70358032519500
37
+ version_requirements: *70235826838540
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: mocha
40
- requirement: &70358032518920 !ruby/object:Gem::Requirement
40
+ requirement: &70235826837180 !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
43
  - - ! '>='
@@ -45,10 +45,10 @@ dependencies:
45
45
  version: '0'
46
46
  type: :development
47
47
  prerelease: false
48
- version_requirements: *70358032518920
48
+ version_requirements: *70235826837180
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: bourne
51
- requirement: &70358032518260 !ruby/object:Gem::Requirement
51
+ requirement: &70235826836020 !ruby/object:Gem::Requirement
52
52
  none: false
53
53
  requirements:
54
54
  - - ! '>='
@@ -56,10 +56,10 @@ dependencies:
56
56
  version: '0'
57
57
  type: :development
58
58
  prerelease: false
59
- version_requirements: *70358032518260
59
+ version_requirements: *70235826836020
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: rake
62
- requirement: &70358032533920 !ruby/object:Gem::Requirement
62
+ requirement: &70235826835400 !ruby/object:Gem::Requirement
63
63
  none: false
64
64
  requirements:
65
65
  - - ! '>='
@@ -67,7 +67,7 @@ dependencies:
67
67
  version: '0'
68
68
  type: :development
69
69
  prerelease: false
70
- version_requirements: *70358032533920
70
+ version_requirements: *70235826835400
71
71
  description: ! " Grocer interfaces with the Apple Push\n
72
72
  \ Notification Service to send push\n notifications
73
73
  to iOS devices and collect\n notification feedback via
@@ -132,7 +132,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
132
132
  version: '0'
133
133
  segments:
134
134
  - 0
135
- hash: 2039363373187503925
135
+ hash: 4223240216448352640
136
136
  required_rubygems_version: !ruby/object:Gem::Requirement
137
137
  none: false
138
138
  requirements:
@@ -141,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
141
  version: '0'
142
142
  segments:
143
143
  - 0
144
- hash: 2039363373187503925
144
+ hash: 4223240216448352640
145
145
  requirements: []
146
146
  rubyforge_project:
147
147
  rubygems_version: 1.8.15