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.
@@ -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
@@ -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
- @channel.close
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
- exchange.publish(options.to_json,
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], QUEUE_OPTIONS.dup)
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::ConnectionError,
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
@@ -1,5 +1,5 @@
1
1
  module Pebbles
2
2
  module River
3
- VERSION = '0.1.5'
3
+ VERSION = '0.1.6'
4
4
  end
5
5
  end
@@ -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.
@@ -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.1'
24
- spec.add_runtime_dependency 'bunny', '~> 1.3.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'
@@ -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({event: 'explode', uid: 'thing:rspec$1'})
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.5
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-08-19 00:00:00.000000000 Z
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.1
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.1
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.3.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.3.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: 2.2.2
210
+ rubygems_version: 1.8.23.2
191
211
  signing_key:
192
- specification_version: 4
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=