pwwka 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +5 -5
- data/README.md +32 -0
- data/lib/pwwka/channel_connector.rb +31 -8
- data/lib/pwwka/configuration.rb +12 -4
- data/lib/pwwka/handling.rb +3 -7
- data/lib/pwwka/message_queuer.rb +66 -0
- data/lib/pwwka/test_handler.rb +8 -7
- data/lib/pwwka/transmitter.rb +33 -5
- data/lib/pwwka/version.rb +1 -1
- data/lib/pwwka.rb +1 -0
- data/spec/handling_spec.rb +6 -6
- data/spec/message_queuer_spec.rb +66 -0
- data/spec/spec_helper.rb +4 -2
- data/spec/transmitter_spec.rb +86 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c195d91e8fc1f10c07a903840900b6e4fc1907ec
|
4
|
+
data.tar.gz: 7d429e0e5d3431f214ac8985299afc3884e3e82e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6ac4140dff8b136fc8b432625c787ce4132c4ce85057678e59acd57ef0475dcf3f676808c62d7c446770b52b732e524dcccbcaa4b6423f1d7f215272da547f47
|
7
|
+
data.tar.gz: fcdfbe94f023dd4a471301636acca4d61b182324b8ea521cc6f2175467c78cd7795785abecdb1036e496b2d2b37f02c99dab91f5ba47b18e3a62bc8a4dd78b93
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
pwwka (0.
|
4
|
+
pwwka (0.3.0)
|
5
5
|
activemodel
|
6
6
|
activesupport
|
7
7
|
bunny
|
@@ -10,10 +10,10 @@ PATH
|
|
10
10
|
GEM
|
11
11
|
remote: https://www.rubygems.org/
|
12
12
|
specs:
|
13
|
-
activemodel (4.1.
|
14
|
-
activesupport (= 4.1.
|
13
|
+
activemodel (4.1.5)
|
14
|
+
activesupport (= 4.1.5)
|
15
15
|
builder (~> 3.1)
|
16
|
-
activesupport (4.1.
|
16
|
+
activesupport (4.1.5)
|
17
17
|
i18n (~> 0.6, >= 0.6.9)
|
18
18
|
json (~> 1.7, >= 1.7.7)
|
19
19
|
minitest (~> 5.1)
|
@@ -26,7 +26,7 @@ GEM
|
|
26
26
|
diff-lcs (1.2.5)
|
27
27
|
i18n (0.6.11)
|
28
28
|
json (1.8.1)
|
29
|
-
minitest (5.4.
|
29
|
+
minitest (5.4.1)
|
30
30
|
mono_logger (1.1.0)
|
31
31
|
rake (10.3.2)
|
32
32
|
rspec (3.0.0)
|
data/README.md
CHANGED
@@ -55,6 +55,7 @@ require 'pwwka'
|
|
55
55
|
Pwwka.configure do |config|
|
56
56
|
config.rabbit_mq_host = ENV['RABBITMQ_URL']
|
57
57
|
config.topic_exchange_name = "mycompany-topics-#{Rails.env}"
|
58
|
+
config.options = {allow_delayed: true}
|
58
59
|
end
|
59
60
|
```
|
60
61
|
|
@@ -93,6 +94,37 @@ send_message_safely(payload, routing_key)
|
|
93
94
|
|
94
95
|
The messages are not transaction safe so for updates do your best to send them after the transaction commits. You must send create messages after the transaction commits or the receivers will probably not find the persisted records.
|
95
96
|
|
97
|
+
### Delayed Messages
|
98
|
+
You might want to delay sending a message (for example, if you have just created a database record and a race condition keeps catching you out). In that case you can use delayed message options:
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
payload = {client_id: '13452564'}
|
102
|
+
routing_key = 'sf.clients.client.created'
|
103
|
+
Pwwka::Transmitter.send_message!(payload, routing_key, delayed: true, delay_by: 3000)
|
104
|
+
```
|
105
|
+
|
106
|
+
`delay_by` is an integer of milliseconds to delay the message. The default (if no value is set) is 5000 (5 seconds).
|
107
|
+
|
108
|
+
These extra arguments work for all message sending methods - the safe ones, the handling, and the message_queuer methods (see below).
|
109
|
+
|
110
|
+
### Message Queuer
|
111
|
+
You can queue up messages and send them in a batch. This is most useful when multiple messages need to sent from within a transaction block.
|
112
|
+
|
113
|
+
For example:
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
# instantiate a message_queuer object
|
117
|
+
message_queuer = MessageQueuerService.new
|
118
|
+
ActiveRecord::Base.transaction do
|
119
|
+
# do a thing, then queue message
|
120
|
+
message_queuer.queue_message(payload: {this: 'that'}, routing_key: 'go.to.there')
|
121
|
+
|
122
|
+
# do another thing, then queue a delayed message
|
123
|
+
message_queuer.queue_message(payload: {the: 'other'}, routing_key: 'go.somewhere.else', delayed: true, delay_by: 3000)
|
124
|
+
end
|
125
|
+
# send the queued messages if we make it out of the transaction alive
|
126
|
+
message_queuer.send_messages_safely
|
127
|
+
```
|
96
128
|
|
97
129
|
## Receiving messages
|
98
130
|
|
@@ -2,24 +2,47 @@ module Pwwka
|
|
2
2
|
class ChannelConnector
|
3
3
|
|
4
4
|
attr_reader :connection
|
5
|
-
attr_reader :
|
5
|
+
attr_reader :configuration
|
6
6
|
attr_reader :channel
|
7
7
|
|
8
8
|
# The channel_connector starts the connection to the message_bus
|
9
9
|
# so it should only be instantiated by a method that has a strategy
|
10
10
|
# for closing the connection
|
11
11
|
def initialize
|
12
|
-
configuration
|
13
|
-
connection_options
|
14
|
-
@connection
|
12
|
+
@configuration = Pwwka.configuration
|
13
|
+
connection_options = {automatically_recover: false}.merge(configuration.options)
|
14
|
+
@connection = Bunny.new(configuration.rabbit_mq_host,
|
15
15
|
connection_options)
|
16
|
-
@topic_exchange_name = configuration.topic_exchange_name
|
17
16
|
@connection.start
|
18
|
-
@channel
|
17
|
+
@channel = @connection.create_channel
|
19
18
|
end
|
20
19
|
|
21
20
|
def topic_exchange
|
22
|
-
@topic_exchange ||= channel.topic(topic_exchange_name, durable: true)
|
21
|
+
@topic_exchange ||= channel.topic(configuration.topic_exchange_name, durable: true)
|
22
|
+
end
|
23
|
+
|
24
|
+
def delayed_exchange
|
25
|
+
raise_if_delayed_not_allowed
|
26
|
+
@delayed_exchange ||= channel.fanout(configuration.delayed_exchange_name, durable: true)
|
27
|
+
end
|
28
|
+
|
29
|
+
def delayed_queue
|
30
|
+
raise_if_delayed_not_allowed
|
31
|
+
@delayed_queue ||= begin
|
32
|
+
queue = channel.queue("pwwka_delayed_#{Pwwka.environment}", durable: true,
|
33
|
+
arguments: {
|
34
|
+
'x-dead-letter-exchange' => configuration.topic_exchange_name,
|
35
|
+
})
|
36
|
+
queue.bind(delayed_exchange)
|
37
|
+
queue
|
38
|
+
end
|
39
|
+
end
|
40
|
+
alias :create_delayed_queue :delayed_queue
|
41
|
+
|
42
|
+
def raise_if_delayed_not_allowed
|
43
|
+
unless configuration.allow_delayed?
|
44
|
+
raise ConfigurationError, "Delayed messages are not allowed. Update your configuration to allow them."
|
45
|
+
end
|
23
46
|
end
|
24
47
|
|
25
48
|
def connection_close
|
@@ -28,4 +51,4 @@ module Pwwka
|
|
28
51
|
end
|
29
52
|
|
30
53
|
end
|
31
|
-
end
|
54
|
+
end
|
data/lib/pwwka/configuration.rb
CHANGED
@@ -1,18 +1,26 @@
|
|
1
1
|
require 'bunny'
|
2
2
|
require 'mono_logger'
|
3
3
|
module Pwwka
|
4
|
+
class ConfigurationError < StandardError; end
|
4
5
|
class Configuration
|
5
6
|
|
6
7
|
attr_accessor :rabbit_mq_host
|
7
8
|
attr_accessor :topic_exchange_name
|
9
|
+
attr_accessor :delayed_exchange_name
|
8
10
|
attr_accessor :logger
|
9
11
|
attr_accessor :options
|
10
12
|
|
11
13
|
def initialize
|
12
|
-
@rabbit_mq_host
|
13
|
-
@topic_exchange_name
|
14
|
-
@
|
15
|
-
@
|
14
|
+
@rabbit_mq_host = nil
|
15
|
+
@topic_exchange_name = "pwwka.topics.#{Pwwka.environment}"
|
16
|
+
@delayed_exchange_name = "pwwka.delayed.#{Pwwka.environment}"
|
17
|
+
@logger = MonoLogger.new(STDOUT)
|
18
|
+
@options = {}
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def allow_delayed?
|
23
|
+
options[:allow_delayed]
|
16
24
|
end
|
17
25
|
|
18
26
|
end
|
data/lib/pwwka/handling.rb
CHANGED
@@ -1,14 +1,10 @@
|
|
1
|
+
require 'forwardable'
|
1
2
|
module Pwwka
|
2
3
|
|
3
4
|
module Handling
|
5
|
+
extend Forwardable
|
4
6
|
|
5
|
-
|
6
|
-
Pwwka::Transmitter.send_message!(payload, routing_key)
|
7
|
-
end
|
8
|
-
|
9
|
-
def send_message_safely(payload, routing_key)
|
10
|
-
Pwwka::Transmitter.send_message_safely(payload, routing_key)
|
11
|
-
end
|
7
|
+
def_delegators :'Pwwka::Transmitter', :send_message!, :send_message_safely
|
12
8
|
|
13
9
|
end
|
14
10
|
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Pwwka
|
2
|
+
# Queue messages for sending in a batch
|
3
|
+
# Primarily used when multiple messages need to sent from within a
|
4
|
+
# transaction block
|
5
|
+
#
|
6
|
+
# Example:
|
7
|
+
#
|
8
|
+
# # instantiate a message_queuer object
|
9
|
+
# message_queuer = MessageQueuerService.new
|
10
|
+
# ActiveRecord::Base.transaction do
|
11
|
+
# # do a thing, then queue message
|
12
|
+
# message_queuer.queue_message(payload: {this: 'that'}, routing_key: 'go.to.there')
|
13
|
+
#
|
14
|
+
# # do another thing, then queue a delayed message
|
15
|
+
# message_queuer.queue_message(payload: {the: 'other'}, routing_key: 'go.somewhere.else', delayed: true, delay_by: 3000)
|
16
|
+
# end
|
17
|
+
# # send the queued messages if we make it out of the transaction alive
|
18
|
+
# message_queuer.send_messages_safely
|
19
|
+
|
20
|
+
|
21
|
+
class MessageQueuer
|
22
|
+
|
23
|
+
include Handling
|
24
|
+
|
25
|
+
attr_reader :message_queue
|
26
|
+
|
27
|
+
def initialize()
|
28
|
+
@message_queue = []
|
29
|
+
end
|
30
|
+
|
31
|
+
def queue_message(payload:, routing_key:, delayed: false, delay_by: nil)
|
32
|
+
message_queue.push({
|
33
|
+
payload: payload,
|
34
|
+
routing_key: routing_key,
|
35
|
+
delayed: delayed,
|
36
|
+
delay_by: delay_by
|
37
|
+
})
|
38
|
+
end
|
39
|
+
|
40
|
+
def send_messages_safely
|
41
|
+
message_queue.each do |message|
|
42
|
+
delay_hash = {delayed: message[:delayed], delay_by: message[:delay_by]}.delete_if{|_,v|!v}
|
43
|
+
send_message_safely(*message_arguments(message))
|
44
|
+
end
|
45
|
+
clear_messages
|
46
|
+
end
|
47
|
+
|
48
|
+
def send_messages!
|
49
|
+
message_queue.each do |message|
|
50
|
+
send_message!(*message_arguments(message))
|
51
|
+
end
|
52
|
+
clear_messages
|
53
|
+
end
|
54
|
+
|
55
|
+
def clear_messages
|
56
|
+
@message_queue.clear
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
def message_arguments(message)
|
61
|
+
delay_hash = {delayed: message[:delayed], delay_by: message[:delay_by]}.delete_if{|_,v|!v}
|
62
|
+
[message[:payload], message[:routing_key], (delay_hash.any? ? delay_hash : nil)].compact
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
data/lib/pwwka/test_handler.rb
CHANGED
@@ -10,13 +10,9 @@ module Pwwka
|
|
10
10
|
class TestHandler
|
11
11
|
|
12
12
|
attr_reader :channel_connector
|
13
|
-
attr_reader :channel
|
14
|
-
attr_reader :topic_exchange
|
15
13
|
|
16
14
|
def initialize
|
17
15
|
@channel_connector = ChannelConnector.new
|
18
|
-
@channel = channel_connector.channel
|
19
|
-
@topic_exchange = channel_connector.topic_exchange
|
20
16
|
end
|
21
17
|
|
22
18
|
# call this method to create the queue used for testing
|
@@ -28,8 +24,8 @@ module Pwwka
|
|
28
24
|
|
29
25
|
def test_queue
|
30
26
|
@test_queue ||= begin
|
31
|
-
test_queue = channel.queue("test-queue", durable: true)
|
32
|
-
test_queue.bind(topic_exchange, routing_key: "#.#")
|
27
|
+
test_queue = channel_connector.channel.queue("test-queue", durable: true)
|
28
|
+
test_queue.bind(channel_connector.topic_exchange, routing_key: "#.#")
|
33
29
|
test_queue
|
34
30
|
end
|
35
31
|
end
|
@@ -62,11 +58,16 @@ module Pwwka
|
|
62
58
|
|
63
59
|
def purge_test_queue
|
64
60
|
test_queue.purge
|
61
|
+
channel_connector.delayed_queue.purge if channel_connector.configuration.allow_delayed?
|
65
62
|
end
|
66
63
|
|
67
64
|
def test_teardown
|
68
65
|
test_queue.delete
|
69
|
-
topic_exchange.delete
|
66
|
+
channel_connector.topic_exchange.delete
|
67
|
+
# delayed messages
|
68
|
+
channel_connector.delayed_queue.delete
|
69
|
+
channel_connector.delayed_exchange.delete
|
70
|
+
|
70
71
|
channel_connector.connection_close
|
71
72
|
end
|
72
73
|
|
data/lib/pwwka/transmitter.rb
CHANGED
@@ -13,17 +13,28 @@ module Pwwka
|
|
13
13
|
extend Pwwka::Logging
|
14
14
|
include Pwwka::Logging
|
15
15
|
|
16
|
+
attr_reader :channel_connector
|
17
|
+
def initialize
|
18
|
+
@channel_connector = ChannelConnector.new
|
19
|
+
end
|
20
|
+
|
16
21
|
# Send an important message that must go through. This method allows any raised exception
|
17
22
|
# to pass through.
|
18
23
|
#
|
19
24
|
# payload:: Hash of what you'd like to include in your message
|
20
25
|
# routing_key:: String routing key for the message
|
26
|
+
# delayed:: Boolean send this message later
|
27
|
+
# delay_by:: Integer milliseconds to delay the message
|
21
28
|
#
|
22
29
|
# Returns true
|
23
30
|
#
|
24
31
|
# Raises any exception generated by the innerworkings of this library.
|
25
|
-
def self.send_message!(payload, routing_key)
|
26
|
-
|
32
|
+
def self.send_message!(payload, routing_key, delayed: false, delay_by: nil)
|
33
|
+
if delayed
|
34
|
+
new.send_delayed_message!(*[payload, routing_key, delay_by].compact)
|
35
|
+
else
|
36
|
+
new.send_message!(payload, routing_key)
|
37
|
+
end
|
27
38
|
info "AFTER Transmitting Message on #{routing_key} -> #{payload}"
|
28
39
|
end
|
29
40
|
|
@@ -32,10 +43,12 @@ module Pwwka
|
|
32
43
|
#
|
33
44
|
# payload:: Hash of what you'd like to include in your message
|
34
45
|
# routing_key:: String routing key for the message
|
46
|
+
# delayed:: Boolean send this message later
|
47
|
+
# delay_by:: Integer milliseconds to delay the message
|
35
48
|
#
|
36
49
|
# Returns true if the message was sent, false otherwise
|
37
|
-
def self.send_message_safely(payload, routing_key)
|
38
|
-
send_message!(payload, routing_key)
|
50
|
+
def self.send_message_safely(payload, routing_key, delayed: false, delay_by: nil)
|
51
|
+
send_message!(payload, routing_key, delayed: delayed, delay_by: delay_by)
|
39
52
|
rescue => e
|
40
53
|
error "ERROR Transmitting Message on #{routing_key} -> #{payload}: #{e}"
|
41
54
|
false
|
@@ -43,7 +56,6 @@ module Pwwka
|
|
43
56
|
|
44
57
|
def send_message!(payload, routing_key)
|
45
58
|
info "START Transmitting Message on #{routing_key} -> #{payload}"
|
46
|
-
channel_connector = ChannelConnector.new
|
47
59
|
channel_connector.topic_exchange.publish(
|
48
60
|
payload.to_json,
|
49
61
|
routing_key: routing_key,
|
@@ -53,5 +65,21 @@ module Pwwka
|
|
53
65
|
info "END Transmitting Message on #{routing_key} -> #{payload}"
|
54
66
|
true
|
55
67
|
end
|
68
|
+
|
69
|
+
def send_delayed_message!(payload, routing_key, delay_by = 5000)
|
70
|
+
channel_connector.raise_if_delayed_not_allowed
|
71
|
+
info "START Transmitting Delayed Message on #{routing_key} -> #{payload}"
|
72
|
+
channel_connector.create_delayed_queue
|
73
|
+
channel_connector.delayed_exchange.publish(
|
74
|
+
payload.to_json,
|
75
|
+
routing_key: routing_key,
|
76
|
+
expiration: delay_by,
|
77
|
+
persistent: true)
|
78
|
+
channel_connector.connection_close
|
79
|
+
# if it gets this far it has succeeded
|
80
|
+
info "END Transmitting Delayed Message on #{routing_key} -> #{payload}"
|
81
|
+
true
|
82
|
+
end
|
83
|
+
|
56
84
|
end
|
57
85
|
end
|
data/lib/pwwka/version.rb
CHANGED
data/lib/pwwka.rb
CHANGED
data/spec/handling_spec.rb
CHANGED
@@ -9,17 +9,17 @@ describe Pwwka::Handling do
|
|
9
9
|
describe "adding handler methods" do
|
10
10
|
|
11
11
|
let(:handling_class) { HKlass.new }
|
12
|
-
let(:payload)
|
13
|
-
let(:routing_key)
|
12
|
+
let(:payload) { { this: 'that'} }
|
13
|
+
let(:routing_key) { 'sf.merch.style.updated' }
|
14
14
|
|
15
15
|
it "should respond to 'send_message!'" do
|
16
|
-
expect(Pwwka::Transmitter).to receive(:send_message!).with(payload, routing_key)
|
17
|
-
handling_class.send_message!(payload, routing_key)
|
16
|
+
expect(Pwwka::Transmitter).to receive(:send_message!).with(payload, routing_key, delayed: false, delay_by: nil)
|
17
|
+
handling_class.send_message!(payload, routing_key, delayed: false, delay_by: nil)
|
18
18
|
end
|
19
19
|
|
20
20
|
it "should respond to 'send_message_safely'" do
|
21
|
-
expect(Pwwka::Transmitter).to receive(:send_message_safely).with(payload, routing_key)
|
22
|
-
handling_class.send_message_safely(payload, routing_key)
|
21
|
+
expect(Pwwka::Transmitter).to receive(:send_message_safely).with(payload, routing_key, delayed: true, delay_by: 4000)
|
22
|
+
handling_class.send_message_safely(payload, routing_key, delayed: true, delay_by: 4000)
|
23
23
|
end
|
24
24
|
|
25
25
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Pwwka::MessageQueuer do
|
4
|
+
|
5
|
+
let(:message_queuer) { Pwwka::MessageQueuer.new }
|
6
|
+
let(:message_queuer_with_messages) {
|
7
|
+
message_queuer = Pwwka::MessageQueuer.new
|
8
|
+
message_queuer.queue_message(payload: payload1, routing_key: routing_key1)
|
9
|
+
message_queuer.queue_message(
|
10
|
+
payload: payload2, routing_key: routing_key2, delayed: true, delay_by: 3500
|
11
|
+
)
|
12
|
+
message_queuer
|
13
|
+
}
|
14
|
+
let(:payload1) { {this: 'that'} }
|
15
|
+
let(:routing_key1) { "thing.7.happened" }
|
16
|
+
let(:payload2) { {shim: 'sham'} }
|
17
|
+
let(:routing_key2) { "thing.8.happened" }
|
18
|
+
|
19
|
+
describe "#queue_message" do
|
20
|
+
|
21
|
+
it "should add a message to the queue" do
|
22
|
+
expect(message_queuer.message_queue).to eq([])
|
23
|
+
message_queuer.queue_message(payload: payload1, routing_key: routing_key1)
|
24
|
+
message_queuer.queue_message(
|
25
|
+
payload: payload2, routing_key: routing_key2, delayed: true, delay_by: 3500
|
26
|
+
)
|
27
|
+
expect(message_queuer.message_queue).to eq([{payload: payload1, routing_key: routing_key1, delayed: false, delay_by: nil}, {payload: payload2, routing_key: routing_key2, delayed: true, delay_by: 3500}])
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
describe "#send_messages_safely" do
|
34
|
+
|
35
|
+
it "should send the queued messages" do
|
36
|
+
expect(message_queuer_with_messages).to receive(:send_message_safely).with(payload1, routing_key1).and_call_original
|
37
|
+
expect(message_queuer_with_messages).to receive(:send_message_safely).with(payload2, routing_key2, delayed: true, delay_by: 3500).and_call_original
|
38
|
+
message_queuer_with_messages.send_messages_safely
|
39
|
+
expect(message_queuer_with_messages.message_queue).to eq([])
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "#send_messages!" do
|
45
|
+
|
46
|
+
it "should send the queued messages" do
|
47
|
+
expect(message_queuer_with_messages).to receive(:send_message!).with(payload1, routing_key1).and_call_original
|
48
|
+
expect(message_queuer_with_messages).to receive(:send_message!).with(payload2, routing_key2, delayed: true, delay_by: 3500).and_call_original
|
49
|
+
message_queuer_with_messages.send_messages!
|
50
|
+
expect(message_queuer_with_messages.message_queue).to eq([])
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#clear_messages" do
|
56
|
+
|
57
|
+
it "should clear the queued messages" do
|
58
|
+
expect(message_queuer_with_messages.message_queue.size).to eq(2)
|
59
|
+
message_queuer_with_messages.clear_messages
|
60
|
+
expect(message_queuer_with_messages.message_queue).to eq([])
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
GEM_ROOT = File.expand_path(File.join(File.dirname(__FILE__),'..'))
|
2
|
+
ENV['RAILS_ENV'] ||= 'test'
|
2
3
|
require 'pwwka'
|
3
4
|
require 'pwwka/test_handler'
|
4
5
|
Dir["#{GEM_ROOT}/spec/support/**/*.rb"].sort.each {|f| require f}
|
@@ -12,6 +13,7 @@ RSpec.configure do |config|
|
|
12
13
|
end
|
13
14
|
|
14
15
|
Pwwka.configure do |config|
|
15
|
-
config.topic_exchange_name
|
16
|
-
config.logger
|
16
|
+
config.topic_exchange_name = "topics-test"
|
17
|
+
config.logger = MonoLogger.new("/dev/null")
|
18
|
+
config.options[:allow_delayed] = true
|
17
19
|
end
|
data/spec/transmitter_spec.rb
CHANGED
@@ -7,6 +7,7 @@ describe Pwwka::Transmitter do
|
|
7
7
|
@test_handler.test_setup
|
8
8
|
end
|
9
9
|
|
10
|
+
after(:each) { @test_handler.purge_test_queue }
|
10
11
|
after(:all) { @test_handler.test_teardown }
|
11
12
|
|
12
13
|
let(:payload) { Hash[:this, "that"] }
|
@@ -22,7 +23,7 @@ describe Pwwka::Transmitter do
|
|
22
23
|
expect(received_payload["this"]).to eq("that")
|
23
24
|
end
|
24
25
|
|
25
|
-
it "should
|
26
|
+
it "should deliver on the expected routing key" do
|
26
27
|
success = Pwwka::Transmitter.new.send_message!(payload, routing_key)
|
27
28
|
expect(success).to be_truthy
|
28
29
|
delivery_info = @test_handler.pop_message.delivery_info
|
@@ -39,6 +40,46 @@ describe Pwwka::Transmitter do
|
|
39
40
|
|
40
41
|
end
|
41
42
|
|
43
|
+
describe "#send_delayed_message!" do
|
44
|
+
|
45
|
+
context "happy path" do
|
46
|
+
it "should send the correct payload" do
|
47
|
+
success = Pwwka::Transmitter.new.send_delayed_message!(payload, routing_key, 1000)
|
48
|
+
expect(success).to be_truthy
|
49
|
+
expect(@test_handler.test_queue.message_count).to eq(0)
|
50
|
+
sleep 5
|
51
|
+
expect(@test_handler.test_queue.message_count).to eq(1)
|
52
|
+
received_payload = @test_handler.pop_message.payload
|
53
|
+
expect(received_payload["this"]).to eq("that")
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should deliver on the expected routing key" do
|
57
|
+
success = Pwwka::Transmitter.new.send_delayed_message!(payload, routing_key, 1)
|
58
|
+
expect(success).to be_truthy
|
59
|
+
sleep 1
|
60
|
+
delivery_info = @test_handler.pop_message.delivery_info
|
61
|
+
expect(delivery_info.routing_key).to eq(routing_key)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should blow up if exception raised" do
|
66
|
+
expect(Pwwka::ChannelConnector).to receive(:new).and_raise("blow up")
|
67
|
+
expect {
|
68
|
+
Pwwka::Transmitter.new.send_delayed_message!(payload, routing_key, 1)
|
69
|
+
}.to raise_error
|
70
|
+
end
|
71
|
+
|
72
|
+
context "delayed not configured" do
|
73
|
+
it "should blow up if allow_delayed? is false" do
|
74
|
+
expect(@test_handler.channel_connector.configuration).to receive(:allow_delayed?).at_least(:once).and_return(false)
|
75
|
+
expect {
|
76
|
+
Pwwka::Transmitter.new.send_delayed_message!(payload, routing_key, 1)
|
77
|
+
}.to raise_error(Pwwka::ConfigurationError)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
42
83
|
describe "::send_message!" do
|
43
84
|
|
44
85
|
it "should send the correct payload" do
|
@@ -54,6 +95,28 @@ describe Pwwka::Transmitter do
|
|
54
95
|
}.to raise_error
|
55
96
|
end
|
56
97
|
|
98
|
+
context "delayed message" do
|
99
|
+
|
100
|
+
it "should call send_delayed_message! if requested with delay_by" do
|
101
|
+
expect_any_instance_of(Pwwka::Transmitter).to receive(:send_delayed_message!)
|
102
|
+
.with(payload, routing_key, 2000)
|
103
|
+
Pwwka::Transmitter.send_message!(payload, routing_key, delayed: true, delay_by: 2000)
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should call send_delayed_message if requested without delay_by" do
|
107
|
+
expect_any_instance_of(Pwwka::Transmitter).to receive(:send_delayed_message!)
|
108
|
+
.with(payload, routing_key)
|
109
|
+
Pwwka::Transmitter.send_message!(payload, routing_key, delayed: true)
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should not call send_delayed_message if not requested" do
|
113
|
+
expect_any_instance_of(Pwwka::Transmitter).not_to receive(:send_delayed_message!)
|
114
|
+
expect_any_instance_of(Pwwka::Transmitter).to receive(:send_message!)
|
115
|
+
Pwwka::Transmitter.send_message_safely(payload, routing_key)
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
|
57
120
|
end
|
58
121
|
|
59
122
|
describe "::send_message_safely" do
|
@@ -71,6 +134,28 @@ describe Pwwka::Transmitter do
|
|
71
134
|
expect(@test_handler.test_queue.pop.compact.count).to eq(0)
|
72
135
|
end
|
73
136
|
|
137
|
+
context "delayed message" do
|
138
|
+
|
139
|
+
it "should call send_delayed_message! if requested with delay_by" do
|
140
|
+
expect_any_instance_of(Pwwka::Transmitter).to receive(:send_delayed_message!)
|
141
|
+
.with(payload, routing_key, 2000)
|
142
|
+
Pwwka::Transmitter.send_message_safely(payload, routing_key, delayed: true, delay_by: 2000)
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should call send_delayed_message if requested without delay_by" do
|
146
|
+
expect_any_instance_of(Pwwka::Transmitter).to receive(:send_delayed_message!)
|
147
|
+
.with(payload, routing_key)
|
148
|
+
Pwwka::Transmitter.send_message_safely(payload, routing_key, delayed: true)
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should not call send_delayed_message if not requested" do
|
152
|
+
expect_any_instance_of(Pwwka::Transmitter).not_to receive(:send_delayed_message!)
|
153
|
+
expect_any_instance_of(Pwwka::Transmitter).to receive(:send_message!)
|
154
|
+
Pwwka::Transmitter.send_message_safely(payload, routing_key)
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
|
74
159
|
end
|
75
160
|
|
76
161
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pwwka
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stitch Fix Engineering
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-09-
|
11
|
+
date: 2014-09-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bunny
|
@@ -119,6 +119,7 @@ files:
|
|
119
119
|
- lib/pwwka/configuration.rb
|
120
120
|
- lib/pwwka/handling.rb
|
121
121
|
- lib/pwwka/logging.rb
|
122
|
+
- lib/pwwka/message_queuer.rb
|
122
123
|
- lib/pwwka/receiver.rb
|
123
124
|
- lib/pwwka/tasks.rb
|
124
125
|
- lib/pwwka/test_handler.rb
|
@@ -127,6 +128,7 @@ files:
|
|
127
128
|
- pwwka.gemspec
|
128
129
|
- spec/handling_spec.rb
|
129
130
|
- spec/logging_spec.rb
|
131
|
+
- spec/message_queuer_spec.rb
|
130
132
|
- spec/receiver_spec.rb
|
131
133
|
- spec/spec_helper.rb
|
132
134
|
- spec/transmitter_spec.rb
|
@@ -149,13 +151,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
149
151
|
version: '0'
|
150
152
|
requirements: []
|
151
153
|
rubyforge_project:
|
152
|
-
rubygems_version: 2.2.0
|
154
|
+
rubygems_version: 2.2.0
|
153
155
|
signing_key:
|
154
156
|
specification_version: 4
|
155
157
|
summary: Send and receive messages via RabbitMQ
|
156
158
|
test_files:
|
157
159
|
- spec/handling_spec.rb
|
158
160
|
- spec/logging_spec.rb
|
161
|
+
- spec/message_queuer_spec.rb
|
159
162
|
- spec/receiver_spec.rb
|
160
163
|
- spec/spec_helper.rb
|
161
164
|
- spec/transmitter_spec.rb
|