pebbles-river 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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=