amqp-boilerplate 0.0.5 → 0.0.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/CHANGELOG +10 -0
- data/lib/amqp/boilerplate/consumer.rb +24 -4
- data/lib/amqp/boilerplate/version.rb +1 -1
- data/lib/amqp/boilerplate.rb +2 -3
- data/spec/amqp/boilerplate/consumer_spec.rb +44 -1
- data/spec/amqp/boilerplate_spec.rb +1 -6
- metadata +4 -4
data/CHANGELOG
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
= version 0.0.6
|
2
|
+
|
3
|
+
* [FEATURE] Do not abort consumer thread when a StandardError-like exception
|
4
|
+
is raised, but log this instead
|
5
|
+
|
6
|
+
= version 0.0.5
|
7
|
+
|
8
|
+
* [FEATURE] Allow additional options to be passed when binding to an
|
9
|
+
exchange
|
10
|
+
|
1
11
|
= version 0.0.4
|
2
12
|
|
3
13
|
* [ENHANCEMENT] Documentation
|
@@ -49,7 +49,7 @@ module AMQP
|
|
49
49
|
end
|
50
50
|
|
51
51
|
# Macro that subscribes to asynchronous message delivery.
|
52
|
-
#
|
52
|
+
#
|
53
53
|
# @param [Hash] options Options that will be passed as options to {http://rdoc.info/github/ruby-amqp/amqp/master/AMQP/Queue#subscribe-instance_method AMQP::Queue#subscribe}
|
54
54
|
def amqp_subscription(options={})
|
55
55
|
@subscription_options = options
|
@@ -64,18 +64,38 @@ module AMQP
|
|
64
64
|
queue = channel.queue(@queue_name, @queue_options)
|
65
65
|
# Binding a queue to a exchange by passing a string (instead of a AMQP::Exchange instance)
|
66
66
|
queue.bind(@exchange_name, @exchange_options) if @exchange_name
|
67
|
-
queue.subscribe(@subscription_options, &consumer.method(:
|
67
|
+
queue.subscribe(@subscription_options, &consumer.method(:handle_message_wrapper))
|
68
68
|
|
69
69
|
AMQP::Boilerplate.logger.info("[#{self.name}.start] Started consumer '#{self.name}'")
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
+
def handle_channel_error(channel, channel_close)
|
74
|
+
AMQP::Boilerplate.logger.error("[#{self.class}#handle_channel_error] Code = #{channel_close.reply_code}, message = #{channel_close.reply_text}")
|
75
|
+
end
|
76
|
+
|
73
77
|
def handle_message(metadata, payload)
|
74
78
|
raise NotImplementedError, "The time has come to implement your own consumer class. Good luck!"
|
75
79
|
end
|
76
80
|
|
77
|
-
|
78
|
-
|
81
|
+
# Wrapper around message handling routine to prevent the consumer from
|
82
|
+
# being killed when an exception occurs
|
83
|
+
#
|
84
|
+
# Catches anything that quacks like a +StandardError+. +SystemExit+s,
|
85
|
+
# +SyntaxError+s and the like will still cause the consumer to be
|
86
|
+
# aborted. See Ruby's exception inheritance hierarchy for a complete
|
87
|
+
# list of what is and what is not handled by this wrapper.
|
88
|
+
def handle_message_wrapper(metadata, payload)
|
89
|
+
handle_message(metadata, payload)
|
90
|
+
rescue StandardError => e
|
91
|
+
message = <<-MSG
|
92
|
+
[#{self.class}] An exception occurred while processing a message
|
93
|
+
Payload: #{payload}
|
94
|
+
Exception: #{e.message}
|
95
|
+
Backtrace: #{e.backtrace.join("\n")}
|
96
|
+
MSG
|
97
|
+
|
98
|
+
AMQP::Boilerplate.logger.error(message)
|
79
99
|
end
|
80
100
|
end
|
81
101
|
end
|
data/lib/amqp/boilerplate.rb
CHANGED
@@ -17,10 +17,9 @@ module AMQP
|
|
17
17
|
if defined?(PhusionPassenger)
|
18
18
|
PhusionPassenger.on_event(:starting_worker_process) do |forked|
|
19
19
|
if forked
|
20
|
-
|
20
|
+
Thread.new do
|
21
21
|
AMQP::Boilerplate.start
|
22
|
-
|
23
|
-
amqp_thread.abort_on_exception = true
|
22
|
+
end
|
24
23
|
end
|
25
24
|
end
|
26
25
|
else
|
@@ -105,7 +105,7 @@ describe AMQP::Boilerplate::Consumer do
|
|
105
105
|
@queue.should_receive(:bind).with(@exchange_name, anything)
|
106
106
|
BarConsumer.start
|
107
107
|
end
|
108
|
-
|
108
|
+
|
109
109
|
it "should pass an empty hash when no amqp_exchange options are defined" do
|
110
110
|
BarConsumer.amqp_exchange(@exchange_name)
|
111
111
|
@queue.should_receive(:bind).with(anything, {})
|
@@ -130,4 +130,47 @@ describe AMQP::Boilerplate::Consumer do
|
|
130
130
|
end
|
131
131
|
end
|
132
132
|
end
|
133
|
+
|
134
|
+
describe "#handle_message_wrapper" do
|
135
|
+
before(:each) do
|
136
|
+
@consumer = BarConsumer.new
|
137
|
+
|
138
|
+
@metadata = mock("metadata")
|
139
|
+
@payload = "payload"
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should let handle_message do the heavy lifting" do
|
143
|
+
@consumer.should_receive(:handle_message).with(@metadata, @payload)
|
144
|
+
@consumer.handle_message_wrapper(@metadata, @payload)
|
145
|
+
end
|
146
|
+
|
147
|
+
describe "when a StandardError-like error is raised" do
|
148
|
+
before(:each) do
|
149
|
+
@consumer.stub(:handle_message).and_raise(StandardError)
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should be caught" do
|
153
|
+
expect {
|
154
|
+
@consumer.handle_message_wrapper(@metadata, @payload)
|
155
|
+
}.to_not raise_error
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should log" do
|
159
|
+
AMQP::Boilerplate.logger.should_receive(:error)
|
160
|
+
@consumer.handle_message_wrapper(@metadata, @payload)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe "when a NotImplementedError is raised" do
|
165
|
+
before(:each) do
|
166
|
+
@consumer.stub(:handle_message).and_raise(NotImplementedError)
|
167
|
+
end
|
168
|
+
|
169
|
+
it "should not be caught" do
|
170
|
+
expect {
|
171
|
+
@consumer.handle_message_wrapper(@metadata, @payload)
|
172
|
+
}.to raise_error(NotImplementedError)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
133
176
|
end
|
@@ -49,7 +49,7 @@ describe AMQP::Boilerplate do
|
|
49
49
|
PhusionPassenger = Class.new
|
50
50
|
PhusionPassenger.stub(:on_event).and_yield(true)
|
51
51
|
|
52
|
-
@thread = mock(Thread
|
52
|
+
@thread = mock(Thread)
|
53
53
|
Thread.stub(:new).and_yield.and_return(@thread)
|
54
54
|
end
|
55
55
|
|
@@ -67,11 +67,6 @@ describe AMQP::Boilerplate do
|
|
67
67
|
Thread.should_receive(:new)
|
68
68
|
AMQP::Boilerplate.boot
|
69
69
|
end
|
70
|
-
|
71
|
-
it "should abort thread on exception" do
|
72
|
-
@thread.should_receive(:abort_on_exception=).with(true)
|
73
|
-
AMQP::Boilerplate.boot
|
74
|
-
end
|
75
70
|
end
|
76
71
|
end
|
77
72
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: amqp-boilerplate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 6
|
10
|
+
version: 0.0.6
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Patrick Baselier
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2011-09-
|
19
|
+
date: 2011-09-21 00:00:00 +02:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|