pebbles-river 0.1.5 → 0.1.6
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/lib/pebbles/river.rb +12 -0
- data/lib/pebbles/river/river.rb +21 -14
- data/lib/pebbles/river/supervisor.rb +4 -3
- data/lib/pebbles/river/version.rb +1 -1
- data/lib/pebbles/river/worker.rb +1 -0
- data/pebbles-river.gemspec +2 -2
- data/spec/lib/river_spec.rb +8 -2
- metadata +30 -9
- checksums.yaml +0 -15
data/lib/pebbles/river.rb
CHANGED
@@ -16,3 +16,15 @@ require_relative "river/river"
|
|
16
16
|
require_relative "river/compatibility"
|
17
17
|
require_relative "river/rate_limiter"
|
18
18
|
require_relative "river/daemon_helper"
|
19
|
+
|
20
|
+
module Pebbles::River
|
21
|
+
|
22
|
+
def self.rabbitmq_options
|
23
|
+
@rabbitmq_options ||= {}.freeze
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.rabbitmq_options=(options)
|
27
|
+
@rabbitmq_options = options.freeze
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
data/lib/pebbles/river/river.rb
CHANGED
@@ -20,9 +20,10 @@ module Pebbles
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def connect
|
23
|
-
unless @session
|
23
|
+
unless @session and @channel and @exchange
|
24
|
+
disconnect
|
24
25
|
handle_session_error do
|
25
|
-
session = Bunny::Session.new
|
26
|
+
session = Bunny::Session.new(::Pebbles::River.rabbitmq_options)
|
26
27
|
session.start
|
27
28
|
|
28
29
|
channel = session.create_channel
|
@@ -35,9 +36,12 @@ module Pebbles
|
|
35
36
|
end
|
36
37
|
|
37
38
|
def disconnect
|
38
|
-
@exchange = nil
|
39
39
|
if @channel
|
40
|
-
|
40
|
+
begin
|
41
|
+
@channel.close
|
42
|
+
rescue *CONNECTION_EXCEPTIONS
|
43
|
+
# Ignore
|
44
|
+
end
|
41
45
|
@channel = nil
|
42
46
|
end
|
43
47
|
if @session
|
@@ -48,12 +52,15 @@ module Pebbles
|
|
48
52
|
end
|
49
53
|
@session = nil
|
50
54
|
end
|
55
|
+
@exchange = nil
|
51
56
|
end
|
52
57
|
|
53
58
|
def publish(options = {})
|
54
|
-
connect
|
55
59
|
handle_session_error(SendFailure) do
|
56
|
-
|
60
|
+
connect
|
61
|
+
|
62
|
+
# Note: Using self.exchange so it can be stubbed in tests
|
63
|
+
self.exchange.publish(options.to_json,
|
57
64
|
persistent: options.fetch(:persistent, true),
|
58
65
|
key: Routing.routing_key_for(options.slice(:event, :uid)))
|
59
66
|
end
|
@@ -62,8 +69,13 @@ module Pebbles
|
|
62
69
|
def queue(options = {})
|
63
70
|
raise ArgumentError.new 'Queue must be named' unless options[:name]
|
64
71
|
|
72
|
+
queue_opts = {durable: true}
|
73
|
+
if (ttl = options[:ttl])
|
74
|
+
queue_opts[:arguments] = {'x-message-ttl' => ttl}
|
75
|
+
end
|
76
|
+
|
65
77
|
connect
|
66
|
-
queue = @channel.queue(options[:name],
|
78
|
+
queue = @channel.queue(options[:name], queue_opts)
|
67
79
|
Subscription.new(options).queries.each do |key|
|
68
80
|
queue.bind(exchange.name, key: key)
|
69
81
|
end
|
@@ -89,6 +101,7 @@ module Pebbles
|
|
89
101
|
begin
|
90
102
|
yield
|
91
103
|
rescue *CONNECTION_EXCEPTIONS => exception
|
104
|
+
disconnect
|
92
105
|
last_exception = exception
|
93
106
|
retry_count += 1
|
94
107
|
backoff(retry_count)
|
@@ -108,16 +121,10 @@ module Pebbles
|
|
108
121
|
|
109
122
|
MAX_BACKOFF_SECONDS = MAX_RETRY_TIMEOUT
|
110
123
|
|
111
|
-
QUEUE_OPTIONS = {durable: true}.freeze
|
112
|
-
|
113
124
|
EXCHANGE_OPTIONS = {type: :topic, durable: :true}.freeze
|
114
125
|
|
115
126
|
CONNECTION_EXCEPTIONS = [
|
116
|
-
Bunny::
|
117
|
-
Bunny::ForcedChannelCloseError,
|
118
|
-
Bunny::ForcedConnectionCloseError,
|
119
|
-
Bunny::ServerDownError,
|
120
|
-
Bunny::ProtocolError,
|
127
|
+
Bunny::Exception,
|
121
128
|
# These should be caught by Bunny, but apparently aren't.
|
122
129
|
Errno::ECONNRESET
|
123
130
|
].freeze
|
@@ -30,8 +30,8 @@ module Pebbles
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
def add_listener(listener, queue_spec)
|
34
|
-
worker = Pebbles::River::Worker.new(listener,
|
33
|
+
def add_listener(listener, queue_spec, worker_options = {})
|
34
|
+
worker = Pebbles::River::Worker.new(listener, {
|
35
35
|
queue: queue_spec,
|
36
36
|
on_exception: ->(e) {
|
37
37
|
if logger.respond_to?(:exception)
|
@@ -39,7 +39,8 @@ module Pebbles
|
|
39
39
|
else
|
40
40
|
logger.error("Exception #{e.class}: #{e} #{e.backtrace.join("\n")}")
|
41
41
|
end
|
42
|
-
}
|
42
|
+
}
|
43
|
+
}.merge(worker_options))
|
43
44
|
|
44
45
|
process_name = "#{@name}: queue worker: #{queue_spec[:name]}"
|
45
46
|
logger = @logger
|
data/lib/pebbles/river/worker.rb
CHANGED
@@ -202,6 +202,7 @@ module Pebbles
|
|
202
202
|
Bunny::ConnectionError,
|
203
203
|
Bunny::ForcedChannelCloseError,
|
204
204
|
Bunny::ForcedConnectionCloseError,
|
205
|
+
Bunny::ConnectionClosedError,
|
205
206
|
Bunny::ServerDownError,
|
206
207
|
Bunny::ProtocolError,
|
207
208
|
# These should be caught by Bunny, but apparently aren't.
|
data/pebbles-river.gemspec
CHANGED
@@ -20,8 +20,8 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
21
|
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
-
spec.add_runtime_dependency 'pebblebed', '>= 0.2.
|
24
|
-
spec.add_runtime_dependency 'bunny', '~> 1.
|
23
|
+
spec.add_runtime_dependency 'pebblebed', '>= 0.2.2'
|
24
|
+
spec.add_runtime_dependency 'bunny', '~> 1.4.0'
|
25
25
|
spec.add_runtime_dependency 'activesupport', '>= 3.0'
|
26
26
|
spec.add_runtime_dependency 'servolux', '~> 0.10'
|
27
27
|
spec.add_runtime_dependency 'mercenary', '~> 0.3.3'
|
data/spec/lib/river_spec.rb
CHANGED
@@ -13,6 +13,7 @@ describe Pebbles::River::River do
|
|
13
13
|
|
14
14
|
CONNECTION_EXCEPTIONS = [
|
15
15
|
Bunny::ConnectionError,
|
16
|
+
Bunny::ConnectionClosedError,
|
16
17
|
Bunny::ForcedChannelCloseError,
|
17
18
|
Bunny::ForcedConnectionCloseError,
|
18
19
|
Bunny::ServerDownError,
|
@@ -100,7 +101,7 @@ describe Pebbles::River::River do
|
|
100
101
|
|
101
102
|
CONNECTION_EXCEPTIONS.each do |exception_class|
|
102
103
|
context "on temporary failure with #{exception_class}" do
|
103
|
-
it "retries sending until success" do
|
104
|
+
it "reconnects and retries sending until success" do
|
104
105
|
exchange = double('exchange')
|
105
106
|
|
106
107
|
count = 0
|
@@ -111,6 +112,7 @@ describe Pebbles::River::River do
|
|
111
112
|
end
|
112
113
|
end
|
113
114
|
|
115
|
+
subject.stub(:connect) { }
|
114
116
|
subject.stub(:exchange) { exchange }
|
115
117
|
subject.stub(:sleep) { }
|
116
118
|
Timeout.stub(:timeout) { |&block|
|
@@ -119,10 +121,12 @@ describe Pebbles::River::River do
|
|
119
121
|
expect(Timeout).to receive(:timeout).at_least(1).times
|
120
122
|
|
121
123
|
expect(subject).to receive(:sleep).at_least(2).times
|
124
|
+
expect(subject).to receive(:connect).exactly(3).times
|
125
|
+
expect(subject).to receive(:disconnect).exactly(3).times
|
122
126
|
|
123
127
|
expect(exchange).to receive(:publish).at_least(2).times
|
124
128
|
|
125
|
-
subject.publish(
|
129
|
+
subject.publish(event: 'explode', uid: 'thing:rspec$1')
|
126
130
|
end
|
127
131
|
end
|
128
132
|
end
|
@@ -150,6 +154,8 @@ describe Pebbles::River::River do
|
|
150
154
|
}
|
151
155
|
expect(Timeout).to receive(:timeout).at_least(1).times
|
152
156
|
|
157
|
+
expect(subject).to receive(:disconnect).at_least(11).times
|
158
|
+
|
153
159
|
expect(-> { subject.publish({event: 'explode', uid: 'thing:rspec$1'})}).to raise_error do |e|
|
154
160
|
e.should be Pebbles::River::SendFailure
|
155
161
|
e.exception.should be exception_class
|
metadata
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pebbles-river
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Alexander Staubo
|
@@ -9,39 +10,44 @@ authors:
|
|
9
10
|
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
date: 2014-
|
13
|
+
date: 2014-09-10 00:00:00.000000000 Z
|
13
14
|
dependencies:
|
14
15
|
- !ruby/object:Gem::Dependency
|
15
16
|
name: pebblebed
|
16
17
|
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
17
19
|
requirements:
|
18
20
|
- - ! '>='
|
19
21
|
- !ruby/object:Gem::Version
|
20
|
-
version: 0.2.
|
22
|
+
version: 0.2.2
|
21
23
|
type: :runtime
|
22
24
|
prerelease: false
|
23
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
24
27
|
requirements:
|
25
28
|
- - ! '>='
|
26
29
|
- !ruby/object:Gem::Version
|
27
|
-
version: 0.2.
|
30
|
+
version: 0.2.2
|
28
31
|
- !ruby/object:Gem::Dependency
|
29
32
|
name: bunny
|
30
33
|
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
31
35
|
requirements:
|
32
36
|
- - ~>
|
33
37
|
- !ruby/object:Gem::Version
|
34
|
-
version: 1.
|
38
|
+
version: 1.4.0
|
35
39
|
type: :runtime
|
36
40
|
prerelease: false
|
37
41
|
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
38
43
|
requirements:
|
39
44
|
- - ~>
|
40
45
|
- !ruby/object:Gem::Version
|
41
|
-
version: 1.
|
46
|
+
version: 1.4.0
|
42
47
|
- !ruby/object:Gem::Dependency
|
43
48
|
name: activesupport
|
44
49
|
requirement: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
45
51
|
requirements:
|
46
52
|
- - ! '>='
|
47
53
|
- !ruby/object:Gem::Version
|
@@ -49,6 +55,7 @@ dependencies:
|
|
49
55
|
type: :runtime
|
50
56
|
prerelease: false
|
51
57
|
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
52
59
|
requirements:
|
53
60
|
- - ! '>='
|
54
61
|
- !ruby/object:Gem::Version
|
@@ -56,6 +63,7 @@ dependencies:
|
|
56
63
|
- !ruby/object:Gem::Dependency
|
57
64
|
name: servolux
|
58
65
|
requirement: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
59
67
|
requirements:
|
60
68
|
- - ~>
|
61
69
|
- !ruby/object:Gem::Version
|
@@ -63,6 +71,7 @@ dependencies:
|
|
63
71
|
type: :runtime
|
64
72
|
prerelease: false
|
65
73
|
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
66
75
|
requirements:
|
67
76
|
- - ~>
|
68
77
|
- !ruby/object:Gem::Version
|
@@ -70,6 +79,7 @@ dependencies:
|
|
70
79
|
- !ruby/object:Gem::Dependency
|
71
80
|
name: mercenary
|
72
81
|
requirement: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
73
83
|
requirements:
|
74
84
|
- - ~>
|
75
85
|
- !ruby/object:Gem::Version
|
@@ -77,6 +87,7 @@ dependencies:
|
|
77
87
|
type: :runtime
|
78
88
|
prerelease: false
|
79
89
|
version_requirements: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
80
91
|
requirements:
|
81
92
|
- - ~>
|
82
93
|
- !ruby/object:Gem::Version
|
@@ -84,6 +95,7 @@ dependencies:
|
|
84
95
|
- !ruby/object:Gem::Dependency
|
85
96
|
name: rspec
|
86
97
|
requirement: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
87
99
|
requirements:
|
88
100
|
- - ~>
|
89
101
|
- !ruby/object:Gem::Version
|
@@ -91,6 +103,7 @@ dependencies:
|
|
91
103
|
type: :development
|
92
104
|
prerelease: false
|
93
105
|
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
94
107
|
requirements:
|
95
108
|
- - ~>
|
96
109
|
- !ruby/object:Gem::Version
|
@@ -98,6 +111,7 @@ dependencies:
|
|
98
111
|
- !ruby/object:Gem::Dependency
|
99
112
|
name: bundler
|
100
113
|
requirement: !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
101
115
|
requirements:
|
102
116
|
- - ~>
|
103
117
|
- !ruby/object:Gem::Version
|
@@ -105,6 +119,7 @@ dependencies:
|
|
105
119
|
type: :development
|
106
120
|
prerelease: false
|
107
121
|
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
108
123
|
requirements:
|
109
124
|
- - ~>
|
110
125
|
- !ruby/object:Gem::Version
|
@@ -112,6 +127,7 @@ dependencies:
|
|
112
127
|
- !ruby/object:Gem::Dependency
|
113
128
|
name: rake
|
114
129
|
requirement: !ruby/object:Gem::Requirement
|
130
|
+
none: false
|
115
131
|
requirements:
|
116
132
|
- - ! '>='
|
117
133
|
- !ruby/object:Gem::Version
|
@@ -119,6 +135,7 @@ dependencies:
|
|
119
135
|
type: :development
|
120
136
|
prerelease: false
|
121
137
|
version_requirements: !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
122
139
|
requirements:
|
123
140
|
- - ! '>='
|
124
141
|
- !ruby/object:Gem::Version
|
@@ -126,6 +143,7 @@ dependencies:
|
|
126
143
|
- !ruby/object:Gem::Dependency
|
127
144
|
name: simplecov
|
128
145
|
requirement: !ruby/object:Gem::Requirement
|
146
|
+
none: false
|
129
147
|
requirements:
|
130
148
|
- - ! '>='
|
131
149
|
- !ruby/object:Gem::Version
|
@@ -133,6 +151,7 @@ dependencies:
|
|
133
151
|
type: :development
|
134
152
|
prerelease: false
|
135
153
|
version_requirements: !ruby/object:Gem::Requirement
|
154
|
+
none: false
|
136
155
|
requirements:
|
137
156
|
- - ! '>='
|
138
157
|
- !ruby/object:Gem::Version
|
@@ -170,26 +189,27 @@ files:
|
|
170
189
|
homepage: ''
|
171
190
|
licenses:
|
172
191
|
- MIT
|
173
|
-
metadata: {}
|
174
192
|
post_install_message:
|
175
193
|
rdoc_options: []
|
176
194
|
require_paths:
|
177
195
|
- lib
|
178
196
|
required_ruby_version: !ruby/object:Gem::Requirement
|
197
|
+
none: false
|
179
198
|
requirements:
|
180
199
|
- - ! '>='
|
181
200
|
- !ruby/object:Gem::Version
|
182
201
|
version: '0'
|
183
202
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
203
|
+
none: false
|
184
204
|
requirements:
|
185
205
|
- - ! '>='
|
186
206
|
- !ruby/object:Gem::Version
|
187
207
|
version: '0'
|
188
208
|
requirements: []
|
189
209
|
rubyforge_project:
|
190
|
-
rubygems_version:
|
210
|
+
rubygems_version: 1.8.23.2
|
191
211
|
signing_key:
|
192
|
-
specification_version:
|
212
|
+
specification_version: 3
|
193
213
|
summary: Implements an event river mechanism for Pebblebed.
|
194
214
|
test_files:
|
195
215
|
- spec/lib/river_spec.rb
|
@@ -197,3 +217,4 @@ test_files:
|
|
197
217
|
- spec/lib/subscription_spec.rb
|
198
218
|
- spec/lib/worker_spec.rb
|
199
219
|
- spec/spec_helper.rb
|
220
|
+
has_rdoc:
|
checksums.yaml
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
---
|
2
|
-
!binary "U0hBMQ==":
|
3
|
-
metadata.gz: !binary |-
|
4
|
-
YTgxMDRiZWE4YzZhNzE0ZDM0YjNmM2ViNzY3NWNlMmJiMGRhNDgyZA==
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
NzdjZDZlM2IxY2RlZTM0MDdiYWQzNmE3NDQxYTY5YTY4ZWRkNTQ4Yg==
|
7
|
-
SHA512:
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
MDBmZjkzNmU0ZWYzMjNlNmIyODEyZWJmM2E4YjE1NjU3Mjk1NGM0M2U5N2Ex
|
10
|
-
YWQzZjYxNTI4NTk2MDU0Y2Q2YmIzM2E0YjA2NzZkOGZkYTZiMDdhNDI3NTdi
|
11
|
-
NjI1MDE4ODVmYTA0OWE0Zjg5MTg3NWY4Mjc0MWY0YmI5YTlmNGM=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
MTUxNzljZmM0YzBlZDQ2OTcwOGViYjQwYTA3OTQ4YmNlYjViOTQ0MWVkYmVi
|
14
|
-
YjM2N2RmMTlhMzc1NWUxZTZlZjA0NTJlZjE0YmZiYzMzYTUyNDQxYzU5MDRl
|
15
|
-
ZjY1YjNjNGFiMjhiNjVhNmViZGExNzViMGFmODJjYTEwNWQ0NzY=
|