queue_worker 1.0.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/queue_worker/version.rb +1 -1
- data/lib/queue_worker.rb +19 -37
- data/spec/lib/queue_worker_spec.rb +56 -32
- 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: f626efd2e37e8b59b15ed2493d51a5ebc789bee3
|
4
|
+
data.tar.gz: 19e29f12f964ca7c94f036ac1d3b35e3fe10a16d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: be5e1738bcc633ed4de448738b6cfb8b475ca88c002d58947253e31ef9f48759bcf21fc816403193e099ab9f9ac7dc35f9495002593a2ec44e26c2c447dc4f14
|
7
|
+
data.tar.gz: d1033af1039fcf89cc7347a34b2fa0c88ab555f6090f764d9c9655ac798598fafa9587276fd792588e64f9547acbd55adfecfcb31cd15500f2992a5f750d42f5
|
data/lib/queue_worker/version.rb
CHANGED
data/lib/queue_worker.rb
CHANGED
@@ -18,15 +18,16 @@ class QueueWorker
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
attr_writer :client
|
21
|
+
attr_writer :client, :log
|
22
22
|
attr_accessor :queue, :handler
|
23
23
|
|
24
24
|
# @param [String] queue_name the queue to pub/sub
|
25
|
-
# @param [
|
26
|
-
|
25
|
+
# @param [#info, #warn, #error] log
|
26
|
+
# @param [Proc] block to handle the subscription callback
|
27
|
+
def initialize(queue_name = nil, log = nil, &block)
|
27
28
|
@queue = queue_name
|
28
|
-
@
|
29
|
-
@handler = proc { |
|
29
|
+
@log = log
|
30
|
+
@handler = block || proc { |body| Kernel.const_get(body[:class]).call(body[:args]) }
|
30
31
|
end
|
31
32
|
|
32
33
|
# = Publish one or more messages to a queue
|
@@ -68,11 +69,12 @@ class QueueWorker
|
|
68
69
|
|
69
70
|
# = Subscribe (listen) to a queue
|
70
71
|
#
|
72
|
+
# @param [String] queue_name specify the queue name
|
71
73
|
# @param [Integer] size specify the number of messages the block may receive without sending +ack+
|
72
74
|
# @param [Proc] block to handle the subscribe callback
|
73
|
-
def subscribe(size = 1, &block)
|
74
|
-
callback = block || method(:
|
75
|
-
client.subscribe("/queue/#{queue}", { :ack => 'client', 'activemq.prefetchSize' => size }, &callback)
|
75
|
+
def subscribe(queue_name = nil, size = 1, &block)
|
76
|
+
callback = block || method(:call)
|
77
|
+
client.subscribe("/queue/#{queue_name || queue}", { :ack => 'client', 'activemq.prefetchSize' => size }, &callback)
|
76
78
|
end
|
77
79
|
|
78
80
|
# = Subscribe to a queue for a limited time
|
@@ -82,7 +84,7 @@ class QueueWorker
|
|
82
84
|
# @param [Proc] block to handle the subscribe callback
|
83
85
|
def subscribe_with_timeout(duration, size = 1, &block)
|
84
86
|
Timeout::timeout(duration) do
|
85
|
-
subscribe(size, &block)
|
87
|
+
subscribe(nil, size, &block)
|
86
88
|
join
|
87
89
|
end
|
88
90
|
rescue Timeout::Error
|
@@ -90,13 +92,13 @@ class QueueWorker
|
|
90
92
|
end
|
91
93
|
|
92
94
|
# = Unsubscribe from the current queue
|
93
|
-
def unsubscribe
|
94
|
-
client.unsubscribe("/queue/#{queue}")
|
95
|
+
def unsubscribe(queue_name = nil)
|
96
|
+
client.unsubscribe("/queue/#{queue_name || queue}")
|
95
97
|
end
|
96
98
|
|
97
99
|
# = Unsubscribe from the current queue and close the connection
|
98
|
-
def quit
|
99
|
-
unsubscribe
|
100
|
+
def quit(queue_name = nil)
|
101
|
+
unsubscribe(queue_name)
|
100
102
|
close
|
101
103
|
end
|
102
104
|
|
@@ -109,34 +111,14 @@ class QueueWorker
|
|
109
111
|
#
|
110
112
|
# @param [Stomp::Message] message is the container object Stomp gives us for what is really a "frame" or package from the queue
|
111
113
|
def call(message)
|
112
|
-
|
114
|
+
if message.command == 'MESSAGE'
|
115
|
+
handler.call(JSON.parse(message.body, symbolize_names: true), message)
|
116
|
+
end
|
113
117
|
rescue => e
|
114
118
|
log.error(e.message) { "\n#{e.backtrace.inspect}" }
|
115
119
|
ensure
|
116
120
|
ack(message)
|
117
|
-
log.info('Processed') { message }
|
118
|
-
end
|
119
|
-
|
120
|
-
#
|
121
|
-
# Private
|
122
|
-
#
|
123
|
-
|
124
|
-
def default_subscribe_callback(message)
|
125
|
-
if message.command == 'MESSAGE'
|
126
|
-
if message.body == 'UNSUBSCRIBE'
|
127
|
-
unsubscribe
|
128
|
-
else
|
129
|
-
call(message)
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
# = Converts the queue name to a constant
|
135
|
-
#
|
136
|
-
# @param [String] destination_queue
|
137
|
-
#
|
138
|
-
def load_handler_class(destination_queue)
|
139
|
-
destination_queue.gsub(%r!^/?queue/!, '').camelize.constantize
|
121
|
+
log.info('Processed') { "#{message.headers['message-id']} for #{message.headers['destination']}" }
|
140
122
|
end
|
141
123
|
|
142
124
|
def client
|
@@ -2,8 +2,11 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe QueueWorker, slow: true do
|
4
4
|
let(:queue_name) { 'queue_foo' }
|
5
|
+
let(:log) { Logger.new(STDOUT).tap { |x| x.level = Logger::ERROR } }
|
5
6
|
|
6
|
-
subject { described_class.new(queue_name,
|
7
|
+
subject { described_class.new(queue_name, log) }
|
8
|
+
|
9
|
+
before { allow(subject).to receive(:client).and_return(double(Stomp::Client)) }
|
7
10
|
|
8
11
|
describe '.publish' do
|
9
12
|
let(:message) { { id: 101 } }
|
@@ -37,40 +40,42 @@ describe QueueWorker, slow: true do
|
|
37
40
|
end
|
38
41
|
|
39
42
|
describe '#subscribe' do
|
40
|
-
let(:
|
41
|
-
|
42
|
-
|
43
|
-
|
43
|
+
let(:size) { 1 }
|
44
|
+
let(:headers) { { :ack => 'client', 'activemq.prefetchSize' => size } }
|
45
|
+
let(:message) { Struct.new(:command, :body).new('MESSAGE', '{}') }
|
46
|
+
|
47
|
+
it 'pass the -message- to +call+' do
|
48
|
+
expect(subject.client).to receive(:subscribe).with("/queue/#{queue_name}", headers).and_yield(message)
|
49
|
+
expect(subject).to receive(:call).with(message)
|
50
|
+
subject.subscribe
|
51
|
+
end
|
44
52
|
|
45
|
-
|
46
|
-
|
47
|
-
expect(subject).
|
48
|
-
expect(subject).
|
49
|
-
subject.subscribe
|
53
|
+
context 'when -queue_name- is given' do
|
54
|
+
it 'subscribes to the specified queue' do
|
55
|
+
expect(subject.client).to receive(:subscribe).with("/queue/test", headers).and_yield(message)
|
56
|
+
expect(subject).to receive(:call).with(message)
|
57
|
+
subject.subscribe('test')
|
50
58
|
end
|
51
59
|
end
|
52
60
|
|
53
|
-
context
|
54
|
-
let(:
|
55
|
-
|
56
|
-
context "when message body is 'UNSUBSCRIBE'" do
|
57
|
-
before { message.body = 'UNSUBSCRIBE' }
|
61
|
+
context 'when -size- is given' do
|
62
|
+
let(:size) { 5 }
|
58
63
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
end
|
64
|
+
it 'fetches the specified number of messages' do
|
65
|
+
expect(subject.client).to receive(:subscribe).with("/queue/#{queue_name}", headers).and_yield(message)
|
66
|
+
expect(subject).to receive(:call).with(message)
|
67
|
+
subject.subscribe(nil, size)
|
64
68
|
end
|
69
|
+
end
|
65
70
|
|
66
|
-
|
67
|
-
|
71
|
+
context 'when a block is given' do
|
72
|
+
let(:handler_double) { double('Handler block') }
|
68
73
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
+
it 'yields the given block instead of calling +call+' do
|
75
|
+
expect(subject.client).to receive(:subscribe).with("/queue/#{queue_name}", headers).and_yield(message)
|
76
|
+
expect(handler_double).to receive(:call).with(message)
|
77
|
+
expect(subject).to_not receive(:call)
|
78
|
+
subject.subscribe { |message| handler_double.call(message) }
|
74
79
|
end
|
75
80
|
end
|
76
81
|
end
|
@@ -83,12 +88,31 @@ describe QueueWorker, slow: true do
|
|
83
88
|
end
|
84
89
|
|
85
90
|
describe '#call' do
|
86
|
-
let(:message) { double("Stomp::Message", body: %({"
|
91
|
+
let(:message) { double("Stomp::Message", body: %({"class":"QueueWorker", "args": [101]}), command: 'MESSAGE', headers: { 'destination' => '/queue/null' }) }
|
87
92
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
93
|
+
context "when message command is 'MESSAGE'" do
|
94
|
+
it 'acknowledges the message and passes it along to the handler' do
|
95
|
+
expect(subject.handler).to receive(:call).with({ class: 'QueueWorker', args: [101] }, message)
|
96
|
+
expect(subject).to receive(:ack).with(message)
|
97
|
+
subject.call(message)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context "when message command is not 'MESSAGE'" do
|
102
|
+
let(:message) { Struct.new(:command).new('PING') }
|
103
|
+
|
104
|
+
it 'does nothing' do
|
105
|
+
expect(subject.handler).to_not receive(:call)
|
106
|
+
expect(subject).to receive(:ack).with(message)
|
107
|
+
subject.call(message)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'default handler' do
|
112
|
+
it 'loads the :class and calls it with the message body' do
|
113
|
+
expect(QueueWorker).to receive(:call).with([101])
|
114
|
+
subject.handler.call(JSON.parse(message.body, symbolize_names: true))
|
115
|
+
end
|
92
116
|
end
|
93
117
|
end
|
94
118
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: queue_worker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Buckley
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-12-
|
11
|
+
date: 2014-12-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|