lapine 1.1.3 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/lapine/consumer/config.rb +4 -0
- data/lib/lapine/consumer/runner.rb +67 -12
- data/lib/lapine/consumer/topology.rb +16 -6
- data/lib/lapine/version.rb +1 -1
- data/spec/lib/lapine/consumer/config_spec.rb +17 -0
- data/spec/lib/lapine/consumer/runner_spec.rb +2 -0
- data/spec/lib/lapine/consumer/topology_spec.rb +37 -16
- data/spec/spec_helper.rb +2 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 606eec9764b4ad0c59adde34f12ba6eac251657a
|
4
|
+
data.tar.gz: 2acceab836b17cfe7a7c8121c149d6a176ebb7e9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fc643eec3ba896154c77828b7db6833c4eb2d11f018fb27a8fbb65490a3e2a9f3d246fef82292a3274910d60c1ffa7f2d6b04fe07f95bd8d1924076618d894c5
|
7
|
+
data.tar.gz: 06e26f733603299950b18f2b499d1d7ea3ca83a767b2677dd52c7429579df9580abf3997dec658a2b3a212f22cf39719bb319f5012f138b0a12003aef565793f
|
@@ -28,23 +28,28 @@ module Lapine
|
|
28
28
|
|
29
29
|
@queue_properties = queue_properties
|
30
30
|
EventMachine.run do
|
31
|
-
topology.each_binding do |q, conn, routing_key,
|
31
|
+
topology.each_binding do |q, conn, routing_key, handlers|
|
32
32
|
queue = conn.channel.queue(q, @queue_properties).bind(conn.exchange, routing_key: routing_key)
|
33
33
|
queue.subscribe(ack: true) do |metadata, payload|
|
34
|
+
process(metadata, payload, handlers)
|
35
|
+
EventMachine.stop_event_loop if should_exit?
|
36
|
+
end
|
37
|
+
queues << queue
|
38
|
+
end
|
34
39
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
+
topology.each_queue_to_delete do |q, conn, routing_key, handlers|
|
41
|
+
# if queue does not exist in RabbitMQ, skip processing
|
42
|
+
# else
|
43
|
+
queue = conn.channel.queue(q, @queue_properties)
|
44
|
+
queues_to_delete << queue
|
40
45
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
end
|
45
|
-
end
|
46
|
+
queue.subscribe(ack: true) do |metadata, payload|
|
47
|
+
process(metadata, payload, handlers)
|
48
|
+
end
|
46
49
|
|
47
|
-
|
50
|
+
EventMachine.add_timer(0.5) do
|
51
|
+
logger.info "Lapine::Consumer unbinding #{queue.name} from exchange: #{exchange.name}, routing_key: #{routing_key}"
|
52
|
+
queue.unbind(conn.exchange, routing_key: routing_key)
|
48
53
|
end
|
49
54
|
end
|
50
55
|
|
@@ -58,6 +63,8 @@ module Lapine
|
|
58
63
|
EventMachine.add_periodic_timer(5) do
|
59
64
|
EventMachine.stop_event_loop if should_exit?
|
60
65
|
end
|
66
|
+
|
67
|
+
schedule_queue_deletion
|
61
68
|
end
|
62
69
|
|
63
70
|
logger.warn 'exiting Lapine::Consumer'
|
@@ -90,6 +97,54 @@ module Lapine
|
|
90
97
|
Signal.trap('INT') { EventMachine.stop }
|
91
98
|
Signal.trap('TERM') { $STOP_LAPINE_CONSUMER = true }
|
92
99
|
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def queues
|
104
|
+
@queues ||= []
|
105
|
+
end
|
106
|
+
|
107
|
+
def queues_to_delete
|
108
|
+
@queues_to_delete ||= []
|
109
|
+
end
|
110
|
+
|
111
|
+
def schedule_queue_deletion
|
112
|
+
EventMachine.add_timer(30) do
|
113
|
+
queues_to_delete.each do |queue|
|
114
|
+
logger.info "Lapine::Consumer checking #{queue.name} for deletion"
|
115
|
+
|
116
|
+
begin
|
117
|
+
queue.status do |message_count, consumer_count|
|
118
|
+
if message_count == 0
|
119
|
+
logger.info "Lapine::Consumer deleting #{queue.name}"
|
120
|
+
queue.unsubscribe
|
121
|
+
queue.delete unless config.transient?
|
122
|
+
queues_to_delete.delete(queue)
|
123
|
+
else
|
124
|
+
logger.info "Lapine::Consumer skipping #{queue.name} deletion, message count: #{message_count}"
|
125
|
+
schedule_queue_deletion
|
126
|
+
end
|
127
|
+
end
|
128
|
+
rescue => e
|
129
|
+
logger.error "Unable to delete queue #{queue.name}, error: #{e.message}"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def process(metadata, payload, handlers)
|
136
|
+
message = Consumer::Message.new(payload, metadata, logger)
|
137
|
+
Middleware.app.call(message) do |message|
|
138
|
+
handlers.each do |handler|
|
139
|
+
Lapine::Consumer::Dispatcher.new(handler, message).dispatch
|
140
|
+
end
|
141
|
+
|
142
|
+
if config.debug?
|
143
|
+
@message_count += 1
|
144
|
+
@running_message_count += 1
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
93
148
|
end
|
94
149
|
end
|
95
150
|
end
|
@@ -6,16 +6,17 @@ module Lapine
|
|
6
6
|
|
7
7
|
def each_binding
|
8
8
|
config.queues.each do |node|
|
9
|
-
classes = node['handlers']
|
10
|
-
handler.split('::').inject(Object) do |const, name|
|
11
|
-
const.const_get(name)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
9
|
+
classes = classify(node['handlers'])
|
15
10
|
yield node['q'], get_conn(node['topic']), node['routing_key'], classes
|
16
11
|
end
|
17
12
|
end
|
18
13
|
|
14
|
+
def each_queue_to_delete
|
15
|
+
config.delete_queues.each do |node|
|
16
|
+
classes = classify(node['handlers'])
|
17
|
+
yield node['q'], get_conn(node['topic']), node['routing_key'], classes
|
18
|
+
end
|
19
|
+
end
|
19
20
|
|
20
21
|
def each_topic
|
21
22
|
config.topics.each do |topic|
|
@@ -32,6 +33,15 @@ module Lapine
|
|
32
33
|
|
33
34
|
private
|
34
35
|
|
36
|
+
def classify(handlers)
|
37
|
+
return [] unless handlers
|
38
|
+
handlers.map do |handler|
|
39
|
+
handler.split('::').inject(Object) do |const, name|
|
40
|
+
const.const_get(name)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
35
45
|
def get_conn(name)
|
36
46
|
@cons ||= {}.tap do |cons|
|
37
47
|
each_topic do |topic|
|
data/lib/lapine/version.rb
CHANGED
@@ -170,6 +170,23 @@ RSpec.describe Lapine::Consumer::Config do
|
|
170
170
|
end
|
171
171
|
end
|
172
172
|
|
173
|
+
describe '#delete_queues' do
|
174
|
+
let(:config_from_file) { {} }
|
175
|
+
|
176
|
+
it 'defaults to empty array' do
|
177
|
+
expect(config.delete_queues).to eq([])
|
178
|
+
end
|
179
|
+
|
180
|
+
context 'with an array' do
|
181
|
+
let(:config_from_file) { {'delete_queues' => ['a.b.c', 'e.f.g']} }
|
182
|
+
|
183
|
+
it 'reads from config' do
|
184
|
+
expect(config.delete_queues).to eq(['a.b.c', 'e.f.g'])
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
173
190
|
describe '#transient?' do
|
174
191
|
it 'is false by default' do
|
175
192
|
expect(config.transient?).to be false
|
@@ -39,11 +39,13 @@ RSpec.describe Lapine::Consumer::Runner do
|
|
39
39
|
connection_properties: connection_properties,
|
40
40
|
require: [],
|
41
41
|
queues: queues,
|
42
|
+
delete_queues: delete_queues,
|
42
43
|
topics: ['testing.topic'],
|
43
44
|
debug?: true,
|
44
45
|
transient?: true) }
|
45
46
|
let(:connection_properties) { {host: '127.0.0.1', port: 5672, ssl: false, vhost: '/', username: 'guest', password: 'guest'} }
|
46
47
|
let(:message) { Oj.dump({'pay' => 'load'}) }
|
48
|
+
let(:delete_queues) { [] }
|
47
49
|
|
48
50
|
describe '#run' do
|
49
51
|
before do
|
@@ -9,26 +9,27 @@ RSpec.describe Lapine::Consumer::Topology do
|
|
9
9
|
|
10
10
|
let(:topics) {
|
11
11
|
[
|
12
|
-
|
13
|
-
|
12
|
+
'a.topic',
|
13
|
+
'b.topic'
|
14
14
|
]
|
15
15
|
}
|
16
16
|
let(:queues) {
|
17
17
|
[{
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
"handlers" => ["MessageBusTest::Clazz"]
|
18
|
+
'q' => 'store.buyable',
|
19
|
+
'topic' => 'a.topic',
|
20
|
+
'routing_key' => 'store.buyable.update',
|
21
|
+
'handlers' => ['MessageBusTest::Clazz']
|
23
22
|
}]
|
24
23
|
}
|
25
24
|
let(:connection_properties) {
|
26
25
|
{}
|
27
26
|
}
|
27
|
+
let(:queues_to_delete) { [] }
|
28
28
|
let(:config) do
|
29
29
|
double('config',
|
30
30
|
topics: topics,
|
31
31
|
queues: queues,
|
32
|
+
delete_queues: queues_to_delete,
|
32
33
|
connection_properties: connection_properties,
|
33
34
|
debug?: debug)
|
34
35
|
end
|
@@ -37,33 +38,53 @@ RSpec.describe Lapine::Consumer::Topology do
|
|
37
38
|
let(:debug) { false }
|
38
39
|
let(:logger) { nil }
|
39
40
|
|
40
|
-
describe
|
41
|
-
it
|
41
|
+
describe '#each_topic' do
|
42
|
+
it 'yields correct dount' do
|
42
43
|
expect { |b| topology.each_topic(&b) }.to yield_control.twice
|
43
44
|
end
|
44
45
|
|
45
|
-
it
|
46
|
-
expect { |b| topology.each_topic(&b) }.to yield_successive_args(
|
46
|
+
it 'yields all topics in order' do
|
47
|
+
expect { |b| topology.each_topic(&b) }.to yield_successive_args('a.topic', 'b.topic')
|
47
48
|
end
|
48
49
|
end
|
49
50
|
|
50
|
-
describe
|
51
|
+
describe '#each_queue_to_delete' do
|
52
|
+
let(:conn) { double('connection') }
|
53
|
+
let(:queues_to_delete) { [
|
54
|
+
{'q' => 'queue.name', 'topic' => 'a.topic', 'handlers' => ['MessageBusTest::Clazz']},
|
55
|
+
{'q' => 'other.queue.name', 'topic' => 'a.topic', 'handlers' => ['MessageBusTest::Clazz']}
|
56
|
+
] }
|
57
|
+
before do
|
58
|
+
allow(Lapine::Consumer::Connection).to receive(:new) { conn }
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'yields queue name with connection' do
|
62
|
+
expect { |b|
|
63
|
+
topology.each_queue_to_delete(&b)
|
64
|
+
}.to yield_successive_args(
|
65
|
+
['queue.name', conn, nil, [MessageBusTest::Clazz]],
|
66
|
+
['other.queue.name', conn, nil, [MessageBusTest::Clazz]]
|
67
|
+
)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#each_binding' do
|
51
72
|
let(:conn) { double('connection') }
|
52
73
|
|
53
74
|
before do
|
54
75
|
allow(Lapine::Consumer::Connection).to receive(:new) { conn }
|
55
76
|
end
|
56
77
|
|
57
|
-
it
|
78
|
+
it 'yields correct count' do
|
58
79
|
expect { |b| topology.each_binding(&b) }.to yield_control.once
|
59
80
|
end
|
60
81
|
|
61
|
-
it
|
82
|
+
it 'yields expected arguments' do
|
62
83
|
expect { |b|
|
63
84
|
topology.each_binding(&b)
|
64
|
-
}.to yield_with_args(
|
85
|
+
}.to yield_with_args('store.buyable',
|
65
86
|
conn,
|
66
|
-
|
87
|
+
'store.buyable.update',
|
67
88
|
[MessageBusTest::Clazz])
|
68
89
|
end
|
69
90
|
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lapine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Saxby
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-05-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: amqp
|