pwwka 0.4.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/CODE_OF_CONDUCT.md +6 -0
- data/CONTRIBUTING.md +18 -10
- data/Gemfile.lock +20 -20
- data/LICENSE +21 -0
- data/README.md +29 -9
- data/lib/pwwka.rb +3 -1
- data/lib/pwwka/configuration.rb +4 -0
- data/lib/pwwka/message_queuer.rb +3 -1
- data/lib/pwwka/send_message_async_job.rb +16 -0
- data/lib/pwwka/transmitter.rb +49 -14
- data/lib/pwwka/version.rb +1 -1
- data/pwwka.gemspec +7 -6
- data/spec/send_message_async_job_spec.rb +15 -0
- data/spec/transmitter_spec.rb +133 -14
- metadata +24 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ebd965b855d451ed7c107bb135c3f7097cf39abf
|
4
|
+
data.tar.gz: 1154aa6d2f93f73aae83ecc599c9602bb5bcea89
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c598d6f9af0d610cfc54fc92af86664abd6cb39473c43e8a42f799a09fafc6c03be1319aa2c19e96afd1710e0429f09110bbe6db7c8bbd08c90fe00b31a8979d
|
7
|
+
data.tar.gz: cfe0a633ff667cb19c855ccbb8b206df3122dda399f6a195a4b3d844817d56b307730a2cf8c050b4218bc51f4610c1bc0c5f64ec22aae759f88697a3fc7626d8
|
data/.travis.yml
CHANGED
data/CODE_OF_CONDUCT.md
ADDED
data/CONTRIBUTING.md
CHANGED
@@ -1,15 +1,23 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# Contributing
|
2
|
+
Thanks for using and improving *pwwka*! If you'd like to help out, check out [the project's issues list](https://github.com/stitchfix/pwwka/issues) for ideas on what could be improved.
|
3
3
|
|
4
4
|
We're actively using Pwwka in production here at [Stitch Fix](http://technology.stitchfix.com/) and look forward to seeing Pwwka grow and improve with your help. Contributions are warmly welcomed.
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
If there's an idea you'd like to propose, or a design change, feel free to file a new issue or send a pull request:
|
7
|
+
|
8
|
+
1. [Fork][fork] the repo.
|
9
|
+
1. [Create a topic branch.][branch]
|
10
|
+
1. Write tests.
|
11
|
+
1. Implement your feature or fix bug.
|
12
|
+
1. Add, commit, and push your changes.
|
13
|
+
1. [Submit a pull request.][pr]
|
14
|
+
|
15
|
+
[fork]: https://help.github.com/articles/fork-a-repo/
|
16
|
+
[branch]: https://help.github.com/articles/creating-and-deleting-branches-within-your-repository/
|
17
|
+
[pr]: https://help.github.com/articles/using-pull-requests/
|
11
18
|
|
12
|
-
##
|
13
|
-
<a name="testing"></a>
|
19
|
+
## General Guidelines
|
14
20
|
|
15
|
-
You must be running RabbitMQ locally on the default port in order for the tests to work.
|
21
|
+
* You must be running RabbitMQ locally on the default port in order for the tests to work.
|
22
|
+
* When in doubt, test it. If you can't test it, re-think what you are doing.
|
23
|
+
* Code formatting and internal application architecture should be consistent.
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
pwwka (0.
|
4
|
+
pwwka (0.5.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.2.
|
14
|
-
activesupport (= 4.2.
|
13
|
+
activemodel (4.2.4)
|
14
|
+
activesupport (= 4.2.4)
|
15
15
|
builder (~> 3.1)
|
16
|
-
activesupport (4.2.
|
16
|
+
activesupport (4.2.4)
|
17
17
|
i18n (~> 0.7)
|
18
18
|
json (~> 1.7, >= 1.7.7)
|
19
19
|
minitest (~> 5.1)
|
@@ -21,15 +21,15 @@ GEM
|
|
21
21
|
tzinfo (~> 1.1)
|
22
22
|
amq-protocol (1.9.2)
|
23
23
|
builder (3.2.2)
|
24
|
-
bunny (
|
24
|
+
bunny (2.0.0)
|
25
25
|
amq-protocol (>= 1.9.2)
|
26
26
|
diff-lcs (1.2.5)
|
27
27
|
i18n (0.7.0)
|
28
|
-
json (1.8.
|
29
|
-
minitest (5.
|
28
|
+
json (1.8.3)
|
29
|
+
minitest (5.8.1)
|
30
30
|
mono_logger (1.1.0)
|
31
|
-
multi_json (1.11.
|
32
|
-
rack (1.6.
|
31
|
+
multi_json (1.11.2)
|
32
|
+
rack (1.6.4)
|
33
33
|
rack-protection (1.5.3)
|
34
34
|
rack
|
35
35
|
rake (10.4.2)
|
@@ -42,19 +42,19 @@ GEM
|
|
42
42
|
redis-namespace (~> 1.3)
|
43
43
|
sinatra (>= 0.9.2)
|
44
44
|
vegas (~> 0.1.2)
|
45
|
-
rspec (3.
|
46
|
-
rspec-core (~> 3.
|
47
|
-
rspec-expectations (~> 3.
|
48
|
-
rspec-mocks (~> 3.
|
49
|
-
rspec-core (3.
|
50
|
-
rspec-support (~> 3.
|
51
|
-
rspec-expectations (3.
|
45
|
+
rspec (3.3.0)
|
46
|
+
rspec-core (~> 3.3.0)
|
47
|
+
rspec-expectations (~> 3.3.0)
|
48
|
+
rspec-mocks (~> 3.3.0)
|
49
|
+
rspec-core (3.3.2)
|
50
|
+
rspec-support (~> 3.3.0)
|
51
|
+
rspec-expectations (3.3.1)
|
52
52
|
diff-lcs (>= 1.2.0, < 2.0)
|
53
|
-
rspec-support (~> 3.
|
54
|
-
rspec-mocks (3.2
|
53
|
+
rspec-support (~> 3.3.0)
|
54
|
+
rspec-mocks (3.3.2)
|
55
55
|
diff-lcs (>= 1.2.0, < 2.0)
|
56
|
-
rspec-support (~> 3.
|
57
|
-
rspec-support (3.
|
56
|
+
rspec-support (~> 3.3.0)
|
57
|
+
rspec-support (3.3.0)
|
58
58
|
sinatra (1.4.6)
|
59
59
|
rack (~> 1.4)
|
60
60
|
rack-protection (~> 1.4)
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Stitch Fix
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
CHANGED
@@ -84,7 +84,8 @@ The payload should be a simple hash containing primitives. Don't send objects be
|
|
84
84
|
Pwwka::Transmitter.send_message_safely(payload, routing_key)
|
85
85
|
```
|
86
86
|
|
87
|
-
You can also use the two convenience methods for sending a message. To include these methods
|
87
|
+
You can also use the two convenience methods for sending a message. To include these methods
|
88
|
+
in your class use:
|
88
89
|
|
89
90
|
```ruby
|
90
91
|
include Pwwka::Handling
|
@@ -96,16 +97,18 @@ Then you can call:
|
|
96
97
|
send_message!(payload, routing_key)
|
97
98
|
```
|
98
99
|
|
99
|
-
|
100
|
+
### Error Handling
|
101
|
+
This method accepts several strategies for handling errors, pass in using the `on_error` parameter:
|
100
102
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
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.
|
103
|
+
* `:raise`: Log the error and raise the exception received from Bunny. (default strategy)
|
104
|
+
* `:ignore`: Log the error and return false.
|
105
|
+
* `:resque`: Log the error and return false. Also, enqueue a job with Resque
|
106
|
+
to send the message. See `send_message_async` below.
|
106
107
|
|
107
108
|
### Delayed Messages
|
108
|
-
You might want to delay sending a message (for example, if you have just created a database
|
109
|
+
You might want to delay sending a message (for example, if you have just created a database
|
110
|
+
record and a race condition keeps catching you out). In that case you can use delayed message
|
111
|
+
options:
|
109
112
|
|
110
113
|
```ruby
|
111
114
|
payload = {client_id: '13452564'}
|
@@ -117,8 +120,25 @@ Pwwka::Transmitter.send_message!(payload, routing_key, delayed: true, delay_by:
|
|
117
120
|
|
118
121
|
These extra arguments work for all message sending methods - the safe ones, the handling, and the `message_queuer` methods (see below).
|
119
122
|
|
123
|
+
|
124
|
+
### Sending message Async with Resque
|
125
|
+
|
126
|
+
To enqueue a message in a background Resque job, use `Transmitter.send_message_async`
|
127
|
+
```ruby
|
128
|
+
Pwwka::Transmitter.send_message_async(payload, routing_key, delay_by_ms: 5000) # default delay is 0
|
129
|
+
```
|
130
|
+
|
131
|
+
If `Resque::Plugins::ExponentialBackoff` is available, the job will use it.
|
132
|
+
Customize the backoff intervals using the configuration `send_message_resque_backoff_strategy`.
|
133
|
+
The default backoff will retry quickly in case of an intermittent glitch, and then every ten
|
134
|
+
minutes for half an hour.
|
135
|
+
|
136
|
+
The name of the queue created is `pwwka_send_message_async`.
|
137
|
+
|
138
|
+
|
120
139
|
### Message Queuer
|
121
|
-
You can queue up messages and send them in a batch. This is most useful when multiple messages
|
140
|
+
You can queue up messages and send them in a batch. This is most useful when multiple messages
|
141
|
+
need to sent from within a transaction block.
|
122
142
|
|
123
143
|
For example:
|
124
144
|
|
data/lib/pwwka.rb
CHANGED
data/lib/pwwka/configuration.rb
CHANGED
@@ -9,6 +9,7 @@ module Pwwka
|
|
9
9
|
attr_accessor :delayed_exchange_name
|
10
10
|
attr_accessor :logger
|
11
11
|
attr_accessor :options
|
12
|
+
attr_accessor :send_message_resque_backoff_strategy
|
12
13
|
|
13
14
|
def initialize
|
14
15
|
@rabbit_mq_host = nil
|
@@ -16,6 +17,9 @@ module Pwwka
|
|
16
17
|
@delayed_exchange_name = "pwwka.delayed.#{Pwwka.environment}"
|
17
18
|
@logger = MonoLogger.new(STDOUT)
|
18
19
|
@options = {}
|
20
|
+
@send_message_resque_backoff_strategy = [5, #intermittent glitch?
|
21
|
+
60, # quick interruption
|
22
|
+
600, 600, 600] # longer-term outage?
|
19
23
|
end
|
20
24
|
|
21
25
|
|
data/lib/pwwka/message_queuer.rb
CHANGED
@@ -28,7 +28,9 @@ module Pwwka
|
|
28
28
|
@message_queue = []
|
29
29
|
end
|
30
30
|
|
31
|
-
def queue_message(payload
|
31
|
+
def queue_message(payload: nil, routing_key: nil, delayed: false, delay_by: nil)
|
32
|
+
raise 'Missing payload' if payload.nil?
|
33
|
+
raise 'Missing routing_key' if routing_key.nil?
|
32
34
|
message_queue.push({
|
33
35
|
payload: payload,
|
34
36
|
routing_key: routing_key,
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Pwwka
|
2
|
+
class SendMessageAsyncJob
|
3
|
+
|
4
|
+
extend Pwwka::Logging
|
5
|
+
|
6
|
+
@queue = 'pwwka_send_message_async'
|
7
|
+
|
8
|
+
extend Resque::Plugins::ExponentialBackoff rescue nil # Optional
|
9
|
+
@backoff_strategy = Pwwka.configuration.send_message_resque_backoff_strategy
|
10
|
+
|
11
|
+
def self.perform(payload, routing_key)
|
12
|
+
info("Sending message async #{routing_key}, #{payload}")
|
13
|
+
Pwwka::Transmitter.send_message!(payload, routing_key, on_error: :raise)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/pwwka/transmitter.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'resque' rescue nil # optional dependency
|
2
|
+
|
1
3
|
module Pwwka
|
2
4
|
# Primary interface for sending messages.
|
3
5
|
#
|
@@ -13,9 +15,12 @@ module Pwwka
|
|
13
15
|
extend Pwwka::Logging
|
14
16
|
include Pwwka::Logging
|
15
17
|
|
18
|
+
DEFAULT_DELAY_BY_MS = 5000
|
19
|
+
|
16
20
|
attr_reader :channel_connector
|
21
|
+
|
17
22
|
def initialize
|
18
|
-
@channel_connector = ChannelConnector.new
|
23
|
+
@channel_connector = ChannelConnector.new
|
19
24
|
end
|
20
25
|
|
21
26
|
# Send an important message that must go through. This method allows any raised exception
|
@@ -25,17 +30,48 @@ module Pwwka
|
|
25
30
|
# routing_key:: String routing key for the message
|
26
31
|
# delayed:: Boolean send this message later
|
27
32
|
# delay_by:: Integer milliseconds to delay the message
|
33
|
+
# on_error:: What is the behavior of
|
34
|
+
# - :ignore (aka as send_message_safely)
|
35
|
+
# - :raise
|
36
|
+
# - :resque -- use Resque to try to send the message later
|
28
37
|
#
|
29
38
|
# Returns true
|
30
39
|
#
|
31
40
|
# Raises any exception generated by the innerworkings of this library.
|
32
|
-
def self.send_message!(payload, routing_key,
|
41
|
+
def self.send_message!(payload, routing_key, on_error: :raise,
|
42
|
+
delayed: false, delay_by: nil)
|
33
43
|
if delayed
|
34
44
|
new.send_delayed_message!(*[payload, routing_key, delay_by].compact)
|
35
45
|
else
|
36
46
|
new.send_message!(payload, routing_key)
|
37
47
|
end
|
38
48
|
info "AFTER Transmitting Message on #{routing_key} -> #{payload}"
|
49
|
+
|
50
|
+
rescue => e
|
51
|
+
|
52
|
+
error "ERROR Transmitting Message on #{routing_key} -> #{payload}: #{e}"
|
53
|
+
|
54
|
+
case on_error
|
55
|
+
|
56
|
+
when :raise
|
57
|
+
raise e
|
58
|
+
|
59
|
+
when :resque
|
60
|
+
begin
|
61
|
+
send_message_async(payload, routing_key, delay_by_ms: delayed ? delay_by || DEFAULT_DELAY_BY_MS : 0)
|
62
|
+
rescue => resque_exception
|
63
|
+
warn(resque_exception.message)
|
64
|
+
raise e
|
65
|
+
end
|
66
|
+
else # ignore
|
67
|
+
end
|
68
|
+
false
|
69
|
+
end
|
70
|
+
|
71
|
+
# Use Resque to enqueue the message.
|
72
|
+
# - :delay_by_ms:: Integer milliseconds to delay the message. Default is 0.
|
73
|
+
def self.send_message_async(payload, routing_key, delay_by_ms: 0)
|
74
|
+
Resque.enqueue_in(delay_by_ms/1000, SendMessageAsyncJob, payload, routing_key)
|
39
75
|
end
|
40
76
|
|
41
77
|
# Send a less important message that doesn't have to go through. This eats
|
@@ -47,34 +83,33 @@ module Pwwka
|
|
47
83
|
# delay_by:: Integer milliseconds to delay the message
|
48
84
|
#
|
49
85
|
# Returns true if the message was sent, false otherwise
|
86
|
+
# @deprecated This is ignoring a message. ::send_message supports this explicitly.
|
50
87
|
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)
|
52
|
-
rescue => e
|
53
|
-
error "ERROR Transmitting Message on #{routing_key} -> #{payload}: #{e}"
|
54
|
-
false
|
88
|
+
send_message!(payload, routing_key, delayed: delayed, delay_by: delay_by, on_error: :ignore)
|
55
89
|
end
|
56
90
|
|
57
91
|
def send_message!(payload, routing_key)
|
58
92
|
info "START Transmitting Message on #{routing_key} -> #{payload}"
|
59
93
|
channel_connector.topic_exchange.publish(
|
60
|
-
|
61
|
-
|
62
|
-
|
94
|
+
payload.to_json,
|
95
|
+
routing_key: routing_key,
|
96
|
+
persistent: true)
|
63
97
|
channel_connector.connection_close
|
64
98
|
# if it gets this far it has succeeded
|
65
99
|
info "END Transmitting Message on #{routing_key} -> #{payload}"
|
66
100
|
true
|
67
101
|
end
|
68
102
|
|
69
|
-
|
103
|
+
|
104
|
+
def send_delayed_message!(payload, routing_key, delay_by = DEFAULT_DELAY_BY_MS)
|
70
105
|
channel_connector.raise_if_delayed_not_allowed
|
71
106
|
info "START Transmitting Delayed Message on #{routing_key} -> #{payload}"
|
72
107
|
channel_connector.create_delayed_queue
|
73
108
|
channel_connector.delayed_exchange.publish(
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
109
|
+
payload.to_json,
|
110
|
+
routing_key: routing_key,
|
111
|
+
expiration: delay_by,
|
112
|
+
persistent: true)
|
78
113
|
channel_connector.connection_close
|
79
114
|
# if it gets this far it has succeeded
|
80
115
|
info "END Transmitting Delayed Message on #{routing_key} -> #{payload}"
|
data/lib/pwwka/version.rb
CHANGED
data/pwwka.gemspec
CHANGED
@@ -6,9 +6,10 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.name = "pwwka"
|
7
7
|
s.version = Pwwka::VERSION
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
|
-
s.authors = [
|
10
|
-
s.email = [
|
9
|
+
s.authors = ["Stitch Fix Engineering","Andrew Peterson","Bill Eisenhauer","Dave Copeland","David A McClain","Jonathan Dean","Nick Reavill","Simeon Willbanks"]
|
10
|
+
s.email = ["opensource@stitchfix.com","andy@ndpsoftware.com","bill@stitchfix.com","davetron5000@gmail.com","david@stitchfix.com","jon@jonathandean.com","nick@fluxequalsrad.com","simeon@simeons.net" ]
|
11
11
|
s.homepage = "https://github.com/stitchfix/pwwka"
|
12
|
+
s.license = "MIT"
|
12
13
|
s.summary = "Send and receive messages via RabbitMQ"
|
13
14
|
s.description = "The purpose of this gem is to normalise the sending and
|
14
15
|
receiving of messages between Rails apps using the shared RabbitMQ
|
@@ -18,10 +19,10 @@ Gem::Specification.new do |s|
|
|
18
19
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
20
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
21
|
s.require_paths = ["lib"]
|
21
|
-
s.
|
22
|
-
s.
|
23
|
-
s.
|
24
|
-
s.
|
22
|
+
s.add_runtime_dependency("bunny")
|
23
|
+
s.add_runtime_dependency("activesupport")
|
24
|
+
s.add_runtime_dependency("activemodel")
|
25
|
+
s.add_runtime_dependency("mono_logger")
|
25
26
|
s.add_development_dependency("rake")
|
26
27
|
s.add_development_dependency("rspec")
|
27
28
|
s.add_development_dependency("resque")
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
describe Pwwka::SendMessageAsyncJob do
|
4
|
+
|
5
|
+
let(:payload) { Hash[:this, "that"] }
|
6
|
+
let(:routing_key) { "this.that.and.theother" }
|
7
|
+
|
8
|
+
describe '::perform' do
|
9
|
+
it 'calls Pwwwka::Transmitter to send the message' do
|
10
|
+
expect(Pwwka::Transmitter).to receive(:send_message!).with(payload, routing_key, on_error: :raise)
|
11
|
+
described_class.perform(payload, routing_key)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
data/spec/transmitter_spec.rb
CHANGED
@@ -10,8 +10,10 @@ describe Pwwka::Transmitter do
|
|
10
10
|
after(:each) { @test_handler.purge_test_queue }
|
11
11
|
after(:all) { @test_handler.test_teardown }
|
12
12
|
|
13
|
-
let(:payload)
|
13
|
+
let(:payload) { Hash[:this, "that"] }
|
14
14
|
let(:routing_key) { "this.that.and.theother" }
|
15
|
+
let(:exception) { RuntimeError.new('blow up')}
|
16
|
+
|
15
17
|
|
16
18
|
describe "#send_message!" do
|
17
19
|
|
@@ -32,10 +34,10 @@ describe Pwwka::Transmitter do
|
|
32
34
|
end
|
33
35
|
|
34
36
|
it "should blow up if exception raised" do
|
35
|
-
expect(Pwwka::ChannelConnector).to receive(:new).and_raise(
|
37
|
+
expect(Pwwka::ChannelConnector).to receive(:new).and_raise(exception)
|
36
38
|
expect {
|
37
39
|
Pwwka::Transmitter.new.send_message!(payload, routing_key)
|
38
|
-
}.to raise_error
|
40
|
+
}.to raise_error(exception)
|
39
41
|
end
|
40
42
|
|
41
43
|
end
|
@@ -63,10 +65,10 @@ describe Pwwka::Transmitter do
|
|
63
65
|
end
|
64
66
|
|
65
67
|
it "should blow up if exception raised" do
|
66
|
-
expect(Pwwka::ChannelConnector).to receive(:new).and_raise(
|
68
|
+
expect(Pwwka::ChannelConnector).to receive(:new).and_raise(exception)
|
67
69
|
expect {
|
68
70
|
Pwwka::Transmitter.new.send_delayed_message!(payload, routing_key, 1)
|
69
|
-
}.to raise_error
|
71
|
+
}.to raise_error(exception)
|
70
72
|
end
|
71
73
|
|
72
74
|
context "delayed not configured" do
|
@@ -82,30 +84,106 @@ describe Pwwka::Transmitter do
|
|
82
84
|
|
83
85
|
describe "::send_message!" do
|
84
86
|
|
87
|
+
|
85
88
|
it "should send the correct payload" do
|
86
89
|
Pwwka::Transmitter.send_message!(payload, routing_key)
|
87
90
|
received_payload = @test_handler.pop_message.payload
|
88
91
|
expect(received_payload["this"]).to eq("that")
|
89
92
|
end
|
90
93
|
|
91
|
-
it "should
|
92
|
-
expect(Pwwka::
|
93
|
-
|
94
|
-
|
95
|
-
|
94
|
+
it "should return true" do
|
95
|
+
expect(Pwwka::Transmitter.send_message!(payload, routing_key)).to eq true
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should ignore delay_by parameter (should it?)" do
|
99
|
+
Pwwka::Transmitter.send_message!(payload, routing_key, delay_by: 5000)
|
100
|
+
received_payload = @test_handler.pop_message.payload
|
101
|
+
expect(received_payload["this"]).to eq("that")
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'default exception policy' do
|
105
|
+
it "should blow up if exception raised" do
|
106
|
+
expect(Pwwka::ChannelConnector).to receive(:new).and_raise(exception)
|
107
|
+
expect {
|
108
|
+
Pwwka::Transmitter.send_message!(payload, routing_key)
|
109
|
+
}.to raise_error(exception)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context 'when on_error: :raise and exception raised' do
|
114
|
+
before(:each) { expect(Pwwka::ChannelConnector).to receive(:new).and_raise(exception) }
|
115
|
+
|
116
|
+
it "should blow up" do
|
117
|
+
expect {
|
118
|
+
Pwwka::Transmitter.send_message!(payload, routing_key, on_error: :raise)
|
119
|
+
}.to raise_error(exception)
|
120
|
+
end
|
121
|
+
it "should not enqueue a resque job" do
|
122
|
+
expect(Resque).not_to receive(:enqueue_in)
|
123
|
+
expect {
|
124
|
+
Pwwka::Transmitter.send_message!(payload, routing_key, on_error: :raise)
|
125
|
+
}.to raise_error(exception)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context 'when on_error: :ignore and exception raised' do
|
130
|
+
before :each do
|
131
|
+
expect(Pwwka::ChannelConnector).to receive(:new).and_raise("blow up")
|
132
|
+
end
|
133
|
+
it "should not blow up" do
|
134
|
+
Pwwka::Transmitter.send_message!(payload, routing_key, on_error: :ignore)
|
135
|
+
# check nothing has been queued
|
136
|
+
expect(@test_handler.test_queue.pop.compact.count).to eq(0)
|
137
|
+
end
|
138
|
+
it "should return false" do
|
139
|
+
expect(Pwwka::Transmitter.send_message!(payload, routing_key, on_error: :ignore)).to eql false
|
140
|
+
end
|
141
|
+
it "should not enqueue a resque job" do
|
142
|
+
expect(Resque).not_to receive(:enqueue_in)
|
143
|
+
Pwwka::Transmitter.send_message!(payload, routing_key, on_error: :ignore)
|
144
|
+
end
|
96
145
|
end
|
97
146
|
|
147
|
+
context 'when on_error: :resque and exception raised' do
|
148
|
+
before :each do
|
149
|
+
allow(Resque).to receive(:enqueue_in)
|
150
|
+
expect(Pwwka::ChannelConnector).to receive(:new).and_raise("blow up")
|
151
|
+
end
|
152
|
+
it "should return false" do
|
153
|
+
expect(Pwwka::Transmitter.send_message!(payload, routing_key, on_error: :resque)).to eq false
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should enqueue a Resque job if exception raised" do
|
157
|
+
expect(Resque).to receive(:enqueue_in).
|
158
|
+
with(0, Pwwka::SendMessageAsyncJob, payload, routing_key)
|
159
|
+
|
160
|
+
Pwwka::Transmitter.send_message!(payload, routing_key, on_error: :resque)
|
161
|
+
# check nothing has been queued
|
162
|
+
expect(@test_handler.test_queue.pop.compact.count).to eq(0)
|
163
|
+
end
|
164
|
+
|
165
|
+
context 'and then resque fails' do
|
166
|
+
it 'returns the original exception' do
|
167
|
+
expect(Resque).to receive(:enqueue_in).and_raise('blow up in resque')
|
168
|
+
expect {
|
169
|
+
Pwwka::Transmitter.send_message!(payload, routing_key, on_error: :resque)
|
170
|
+
}.to raise_exception('blow up')
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
|
98
176
|
context "delayed message" do
|
99
177
|
|
100
178
|
it "should call send_delayed_message! if requested with delay_by" do
|
101
179
|
expect_any_instance_of(Pwwka::Transmitter).to receive(:send_delayed_message!)
|
102
|
-
|
180
|
+
.with(payload, routing_key, 2000)
|
103
181
|
Pwwka::Transmitter.send_message!(payload, routing_key, delayed: true, delay_by: 2000)
|
104
182
|
end
|
105
183
|
|
106
184
|
it "should call send_delayed_message if requested without delay_by" do
|
107
185
|
expect_any_instance_of(Pwwka::Transmitter).to receive(:send_delayed_message!)
|
108
|
-
|
186
|
+
.with(payload, routing_key)
|
109
187
|
Pwwka::Transmitter.send_message!(payload, routing_key, delayed: true)
|
110
188
|
end
|
111
189
|
|
@@ -115,8 +193,49 @@ describe Pwwka::Transmitter do
|
|
115
193
|
Pwwka::Transmitter.send_message_safely(payload, routing_key)
|
116
194
|
end
|
117
195
|
|
196
|
+
it "should enqueue a Resque job if exception raised and on_error: :resque" do
|
197
|
+
expect(Pwwka::ChannelConnector).to receive(:new).and_raise("blow up")
|
198
|
+
|
199
|
+
expect(Resque).to receive(:enqueue_in).
|
200
|
+
with(2, Pwwka::SendMessageAsyncJob, payload, routing_key)
|
201
|
+
|
202
|
+
Pwwka::Transmitter.send_message!(payload, routing_key, delayed: true, delay_by: 2000, on_error: :resque)
|
203
|
+
# check nothing has been queued
|
204
|
+
expect(@test_handler.test_queue.pop.compact.count).to eq(0)
|
205
|
+
end
|
206
|
+
|
207
|
+
|
208
|
+
it "should enqueue a Resque job if exception raised and on_error: :resque without delay_by" do
|
209
|
+
expect(Pwwka::ChannelConnector).to receive(:new).and_raise("blow up")
|
210
|
+
|
211
|
+
expect(Resque).to receive(:enqueue_in).
|
212
|
+
with(Pwwka::Transmitter::DEFAULT_DELAY_BY_MS/1000, Pwwka::SendMessageAsyncJob, payload, routing_key)
|
213
|
+
|
214
|
+
Pwwka::Transmitter.send_message!(payload, routing_key, delayed: true, on_error: :resque)
|
215
|
+
# check nothing has been queued
|
216
|
+
expect(@test_handler.test_queue.pop.compact.count).to eq(0)
|
217
|
+
end
|
218
|
+
|
118
219
|
end
|
220
|
+
end
|
119
221
|
|
222
|
+
|
223
|
+
describe '::send_message_async' do
|
224
|
+
context 'with no delay' do
|
225
|
+
it 'queues the message' do
|
226
|
+
expect(Resque).to receive(:enqueue_in).
|
227
|
+
with(0, Pwwka::SendMessageAsyncJob, payload, routing_key)
|
228
|
+
Pwwka::Transmitter.send_message_async(payload, routing_key)
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
context 'with delay' do
|
233
|
+
it 'queues the message' do
|
234
|
+
expect(Resque).to receive(:enqueue_in).
|
235
|
+
with(3, Pwwka::SendMessageAsyncJob, payload, routing_key)
|
236
|
+
Pwwka::Transmitter.send_message_async(payload, routing_key, delay_by_ms: 3000)
|
237
|
+
end
|
238
|
+
end
|
120
239
|
end
|
121
240
|
|
122
241
|
describe "::send_message_safely" do
|
@@ -138,13 +257,13 @@ describe Pwwka::Transmitter do
|
|
138
257
|
|
139
258
|
it "should call send_delayed_message! if requested with delay_by" do
|
140
259
|
expect_any_instance_of(Pwwka::Transmitter).to receive(:send_delayed_message!)
|
141
|
-
|
260
|
+
.with(payload, routing_key, 2000)
|
142
261
|
Pwwka::Transmitter.send_message_safely(payload, routing_key, delayed: true, delay_by: 2000)
|
143
262
|
end
|
144
263
|
|
145
264
|
it "should call send_delayed_message if requested without delay_by" do
|
146
265
|
expect_any_instance_of(Pwwka::Transmitter).to receive(:send_delayed_message!)
|
147
|
-
|
266
|
+
.with(payload, routing_key)
|
148
267
|
Pwwka::Transmitter.send_message_safely(payload, routing_key, delayed: true)
|
149
268
|
end
|
150
269
|
|
metadata
CHANGED
@@ -1,14 +1,21 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pwwka
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stitch Fix Engineering
|
8
|
+
- Andrew Peterson
|
9
|
+
- Bill Eisenhauer
|
10
|
+
- Dave Copeland
|
11
|
+
- David A McClain
|
12
|
+
- Jonathan Dean
|
13
|
+
- Nick Reavill
|
14
|
+
- Simeon Willbanks
|
8
15
|
autorequire:
|
9
16
|
bindir: bin
|
10
17
|
cert_chain: []
|
11
|
-
date: 2015-
|
18
|
+
date: 2015-12-09 00:00:00.000000000 Z
|
12
19
|
dependencies:
|
13
20
|
- !ruby/object:Gem::Dependency
|
14
21
|
name: bunny
|
@@ -114,6 +121,13 @@ description: |-
|
|
114
121
|
message bus
|
115
122
|
email:
|
116
123
|
- opensource@stitchfix.com
|
124
|
+
- andy@ndpsoftware.com
|
125
|
+
- bill@stitchfix.com
|
126
|
+
- davetron5000@gmail.com
|
127
|
+
- david@stitchfix.com
|
128
|
+
- jon@jonathandean.com
|
129
|
+
- nick@fluxequalsrad.com
|
130
|
+
- simeon@simeons.net
|
117
131
|
executables: []
|
118
132
|
extensions: []
|
119
133
|
extra_rdoc_files: []
|
@@ -122,9 +136,11 @@ files:
|
|
122
136
|
- ".ruby-gemset"
|
123
137
|
- ".ruby-version"
|
124
138
|
- ".travis.yml"
|
139
|
+
- CODE_OF_CONDUCT.md
|
125
140
|
- CONTRIBUTING.md
|
126
141
|
- Gemfile
|
127
142
|
- Gemfile.lock
|
143
|
+
- LICENSE
|
128
144
|
- README.md
|
129
145
|
- Rakefile
|
130
146
|
- docs/images/RabbitMQ_Management-2.png
|
@@ -138,6 +154,7 @@ files:
|
|
138
154
|
- lib/pwwka/message_queuer.rb
|
139
155
|
- lib/pwwka/queue_resque_job_handler.rb
|
140
156
|
- lib/pwwka/receiver.rb
|
157
|
+
- lib/pwwka/send_message_async_job.rb
|
141
158
|
- lib/pwwka/tasks.rb
|
142
159
|
- lib/pwwka/test_handler.rb
|
143
160
|
- lib/pwwka/transmitter.rb
|
@@ -148,10 +165,12 @@ files:
|
|
148
165
|
- spec/message_queuer_spec.rb
|
149
166
|
- spec/queue_resque_job_handler_spec.rb
|
150
167
|
- spec/receiver_spec.rb
|
168
|
+
- spec/send_message_async_job_spec.rb
|
151
169
|
- spec/spec_helper.rb
|
152
170
|
- spec/transmitter_spec.rb
|
153
171
|
homepage: https://github.com/stitchfix/pwwka
|
154
|
-
licenses:
|
172
|
+
licenses:
|
173
|
+
- MIT
|
155
174
|
metadata: {}
|
156
175
|
post_install_message:
|
157
176
|
rdoc_options: []
|
@@ -169,7 +188,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
169
188
|
version: '0'
|
170
189
|
requirements: []
|
171
190
|
rubyforge_project:
|
172
|
-
rubygems_version: 2.
|
191
|
+
rubygems_version: 2.2.0
|
173
192
|
signing_key:
|
174
193
|
specification_version: 4
|
175
194
|
summary: Send and receive messages via RabbitMQ
|
@@ -179,5 +198,6 @@ test_files:
|
|
179
198
|
- spec/message_queuer_spec.rb
|
180
199
|
- spec/queue_resque_job_handler_spec.rb
|
181
200
|
- spec/receiver_spec.rb
|
201
|
+
- spec/send_message_async_job_spec.rb
|
182
202
|
- spec/spec_helper.rb
|
183
203
|
- spec/transmitter_spec.rb
|