pebbles-river 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.
- checksums.yaml +4 -4
- data/lib/pebbles/river/errors.rb +17 -0
- data/lib/pebbles/river/river.rb +34 -25
- data/lib/pebbles/river/version.rb +1 -1
- data/lib/pebbles/river.rb +1 -0
- data/spec/lib/river_spec.rb +25 -5
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 32827f1f43724f8f2d5cf53943d89b519be5be11
|
4
|
+
data.tar.gz: 38db2f8b16ea69ca288e4f5c26c5debe1556356a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 077a5f0d4d2dc0f2f02cd38b839b49bd14a5bb2201023e2fbdc3fc4f6e4ee6f2370fceba64d97e10e17fb609f14bb8f4af1601acbe8c439b3b23ebef4900b237
|
7
|
+
data.tar.gz: b2b43a50bdeba51c83dcdebec4bf94dce4096d239aabd7189954a19d6446c775949ca92eb0b78ca61453c4aab249676da214d425f8bc3d508c5eb01bca269a33
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Pebbles
|
2
|
+
module River
|
3
|
+
|
4
|
+
class ConnectionError < StandardError
|
5
|
+
attr_reader :connection_exception
|
6
|
+
|
7
|
+
def initialize(message, connection_exception = nil)
|
8
|
+
super(message)
|
9
|
+
@connection_exception = connection_exception
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class ConnectFailure < ConnectionError; end
|
14
|
+
class SendFailure < ConnectionError; end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
data/lib/pebbles/river/river.rb
CHANGED
@@ -1,17 +1,6 @@
|
|
1
1
|
module Pebbles
|
2
2
|
module River
|
3
3
|
|
4
|
-
class SendFailure < StandardError
|
5
|
-
|
6
|
-
attr_reader :connection_exception
|
7
|
-
|
8
|
-
def initialize(message, connection_exception = nil)
|
9
|
-
super(message)
|
10
|
-
@connection_exception = connection_exception
|
11
|
-
end
|
12
|
-
|
13
|
-
end
|
14
|
-
|
15
4
|
class River
|
16
5
|
|
17
6
|
attr_reader :environment
|
@@ -20,6 +9,7 @@ module Pebbles
|
|
20
9
|
options = {environment: options} if options.is_a?(String) # Backwards compatibility
|
21
10
|
|
22
11
|
@environment = (options[:environment] || ENV['RACK_ENV'] || 'development').dup.freeze
|
12
|
+
@last_connect_attempt = nil
|
23
13
|
end
|
24
14
|
|
25
15
|
def connected?
|
@@ -28,18 +18,26 @@ module Pebbles
|
|
28
18
|
|
29
19
|
def connect
|
30
20
|
unless connected?
|
31
|
-
|
32
|
-
|
21
|
+
handle_connection_error do
|
22
|
+
bunny.start
|
23
|
+
bunny.qos
|
24
|
+
end
|
33
25
|
end
|
34
26
|
end
|
35
27
|
|
36
28
|
def disconnect
|
37
|
-
|
29
|
+
if connected?
|
30
|
+
begin
|
31
|
+
bunny.stop
|
32
|
+
rescue *CONNECTION_EXCEPTIONS
|
33
|
+
# Ignore
|
34
|
+
end
|
35
|
+
end
|
38
36
|
end
|
39
37
|
|
40
38
|
def publish(options = {})
|
41
39
|
connect
|
42
|
-
handle_connection_error do
|
40
|
+
handle_connection_error(SendFailure) do
|
43
41
|
exchange.publish(options.to_json,
|
44
42
|
persistent: options.fetch(:persistent, true),
|
45
43
|
key: Routing.routing_key_for(options.slice(:event, :uid)))
|
@@ -79,21 +77,32 @@ module Pebbles
|
|
79
77
|
@exchange ||= bunny.exchange(exchange_name, EXCHANGE_OPTIONS.dup)
|
80
78
|
end
|
81
79
|
|
82
|
-
def handle_connection_error(&block)
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
80
|
+
def handle_connection_error(exception_klass = ConnectFailure, &block)
|
81
|
+
last_exception = nil
|
82
|
+
Timeout.timeout(MAX_RETRY_TIMEOUT) do
|
83
|
+
retry_until, retry_count = nil, 0
|
84
|
+
begin
|
85
|
+
yield
|
86
|
+
rescue *CONNECTION_EXCEPTIONS => exception
|
87
|
+
last_exception = exception
|
88
|
+
retry_count += 1
|
89
|
+
backoff(retry_count)
|
90
90
|
retry
|
91
|
-
else
|
92
|
-
raise SendFailure.new(exception.message, exception)
|
93
91
|
end
|
94
92
|
end
|
93
|
+
rescue Timeout::Error => timeout
|
94
|
+
last_exception ||= timeout
|
95
|
+
raise exception_klass.new(last_exception.message, last_exception)
|
95
96
|
end
|
96
97
|
|
98
|
+
def backoff(iteration)
|
99
|
+
sleep([(1.0 / 2.0 * (2.0 ** [30, iteration].min - 1.0)).ceil, MAX_BACKOFF_SECONDS].min)
|
100
|
+
end
|
101
|
+
|
102
|
+
MAX_RETRY_TIMEOUT = 10
|
103
|
+
|
104
|
+
MAX_BACKOFF_SECONDS = MAX_RETRY_TIMEOUT
|
105
|
+
|
97
106
|
QUEUE_OPTIONS = {durable: true}.freeze
|
98
107
|
|
99
108
|
EXCHANGE_OPTIONS = {type: :topic, durable: :true}.freeze
|
data/lib/pebbles/river.rb
CHANGED
data/spec/lib/river_spec.rb
CHANGED
@@ -114,6 +114,10 @@ describe Pebbles::River::River do
|
|
114
114
|
|
115
115
|
subject.stub(:exchange) { exchange }
|
116
116
|
subject.stub(:sleep) { }
|
117
|
+
Timeout.stub(:timeout) { |&block|
|
118
|
+
block.call
|
119
|
+
}
|
120
|
+
expect(Timeout).to receive(:timeout).at_least(1).times
|
117
121
|
|
118
122
|
expect(subject).to receive(:sleep).at_least(2).times
|
119
123
|
|
@@ -126,17 +130,33 @@ describe Pebbles::River::River do
|
|
126
130
|
|
127
131
|
CONNECTION_EXCEPTIONS.each do |exception_class|
|
128
132
|
context "on permanent failure with #{exception_class}" do
|
129
|
-
it "
|
133
|
+
it "retries with exponential backoff until timeout and gives up with SendFailure" do
|
130
134
|
exchange = double('exchange')
|
131
135
|
exchange.stub(:publish) do
|
132
136
|
raise exception_class.new
|
133
137
|
end
|
134
|
-
|
135
138
|
subject.stub(:exchange) { exchange }
|
136
|
-
subject.stub(:sleep) { }
|
137
139
|
|
138
|
-
|
139
|
-
|
140
|
+
count, sleeps = 0, []
|
141
|
+
subject.stub(:sleep) { |t|
|
142
|
+
count += 1
|
143
|
+
if count >= 10
|
144
|
+
raise Timeout::Error
|
145
|
+
end
|
146
|
+
sleeps.push(t)
|
147
|
+
}
|
148
|
+
|
149
|
+
Timeout.stub(:timeout) { |&block|
|
150
|
+
block.call
|
151
|
+
}
|
152
|
+
expect(Timeout).to receive(:timeout).at_least(1).times
|
153
|
+
|
154
|
+
expect(-> { subject.publish({event: 'explode', uid: 'thing:rspec$1'})}).to raise_error do |e|
|
155
|
+
e.should be Pebbles::River::SendFailure
|
156
|
+
e.exception.should be exception_class
|
157
|
+
end
|
158
|
+
|
159
|
+
expect(sleeps[0, 9]).to eq [1, 2, 4, 8, 10, 10, 10, 10, 10]
|
140
160
|
end
|
141
161
|
end
|
142
162
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pebbles-river
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Staubo
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-04-
|
12
|
+
date: 2014-04-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: pebblebed
|
@@ -137,6 +137,7 @@ files:
|
|
137
137
|
- Rakefile
|
138
138
|
- lib/pebbles/river.rb
|
139
139
|
- lib/pebbles/river/compatibility.rb
|
140
|
+
- lib/pebbles/river/errors.rb
|
140
141
|
- lib/pebbles/river/message.rb
|
141
142
|
- lib/pebbles/river/river.rb
|
142
143
|
- lib/pebbles/river/routing.rb
|