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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f3fc992f47050fe4d47c782fd18224ea2b7224e3
4
- data.tar.gz: ab6505f1e72cad5d540afc2974ecc5406998bfd8
3
+ metadata.gz: ebd965b855d451ed7c107bb135c3f7097cf39abf
4
+ data.tar.gz: 1154aa6d2f93f73aae83ecc599c9602bb5bcea89
5
5
  SHA512:
6
- metadata.gz: d0d3b3b3525731676f81ad2bfd591c6357887cc0f77e40f66114545462ef7dcd4ba672f8cbbf60eb8ac7aafb26a0eb5f77ce7f9b83df7f947393b45fc4dbdb32
7
- data.tar.gz: ac7bcd1642cae8facd0f24305f777868b1da15681701d389836f3bcaa55c7abd7d270e0770f8c388fd03e38838c427d8cf19d5f60c04e2c54aa6ca22162f58c4
6
+ metadata.gz: c598d6f9af0d610cfc54fc92af86664abd6cb39473c43e8a42f799a09fafc6c03be1319aa2c19e96afd1710e0429f09110bbe6db7c8bbd08c90fe00b31a8979d
7
+ data.tar.gz: cfe0a633ff667cb19c855ccbb8b206df3122dda399f6a195a4b3d844817d56b307730a2cf8c050b4218bc51f4610c1bc0c5f64ec22aae759f88697a3fc7626d8
@@ -1,6 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - 2.1.0
4
+ - 2.2.0
5
+ - 2.0.0
4
6
  - ruby-head
5
7
  services:
6
8
  - rabbitmq
@@ -0,0 +1,6 @@
1
+ # Code of Conduct
2
+
3
+ We are committed to keeping our community open and inclusive.
4
+
5
+ **Our Code of Conduct can be found here**:
6
+ http://opensource.stitchfix.com/code-of-conduct.html
@@ -1,15 +1,23 @@
1
-
2
- ## Contributing
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
- To contribute,
7
- 1. make a fork of the project
8
- 2. write some code (with tests please!)
9
- 3. open a Pull Request
10
- 4. bask in the warm fuzzy Open Source hug from us
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
- ## Testing
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.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pwwka (0.4.2)
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.1)
14
- activesupport (= 4.2.1)
13
+ activemodel (4.2.4)
14
+ activesupport (= 4.2.4)
15
15
  builder (~> 3.1)
16
- activesupport (4.2.1)
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 (1.7.0)
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.2)
29
- minitest (5.6.1)
28
+ json (1.8.3)
29
+ minitest (5.8.1)
30
30
  mono_logger (1.1.0)
31
- multi_json (1.11.0)
32
- rack (1.6.0)
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.2.0)
46
- rspec-core (~> 3.2.0)
47
- rspec-expectations (~> 3.2.0)
48
- rspec-mocks (~> 3.2.0)
49
- rspec-core (3.2.2)
50
- rspec-support (~> 3.2.0)
51
- rspec-expectations (3.2.0)
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.2.0)
54
- rspec-mocks (3.2.1)
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.2.0)
57
- rspec-support (3.2.2)
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 in your class use:
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
- This method will blow up if something goes wrong. If you want to send safely then use:
100
+ ### Error Handling
101
+ This method accepts several strategies for handling errors, pass in using the `on_error` parameter:
100
102
 
101
- ```ruby
102
- send_message_safely(payload, routing_key)
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 record and a race condition keeps catching you out). In that case you can use delayed message options:
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 need to sent from within a transaction block.
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
 
@@ -28,5 +28,7 @@ require 'pwwka/handling'
28
28
  require 'pwwka/receiver'
29
29
  require 'pwwka/transmitter'
30
30
  require 'pwwka/message_queuer'
31
-
32
31
  require 'pwwka/configuration'
32
+ require 'pwwka/send_message_async_job'
33
+
34
+
@@ -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
 
@@ -28,7 +28,9 @@ module Pwwka
28
28
  @message_queue = []
29
29
  end
30
30
 
31
- def queue_message(payload:, routing_key:, delayed: false, delay_by: nil)
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
@@ -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, delayed: false, delay_by: nil)
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
- payload.to_json,
61
- routing_key: routing_key,
62
- persistent: true)
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
- def send_delayed_message!(payload, routing_key, delay_by = 5000)
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
- payload.to_json,
75
- routing_key: routing_key,
76
- expiration: delay_by,
77
- persistent: true)
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}"
@@ -1,3 +1,3 @@
1
1
  module Pwwka
2
- VERSION = '0.4.2'
2
+ VERSION = '0.5.0'
3
3
  end
@@ -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 = ['Stitch Fix Engineering']
10
- s.email = ['opensource@stitchfix.com']
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.add_dependency("bunny")
22
- s.add_dependency("activesupport")
23
- s.add_dependency("activemodel")
24
- s.add_dependency("mono_logger")
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
@@ -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) { Hash[:this, "that"] }
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("blow up")
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("blow up")
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 blow up if exception raised" do
92
- expect(Pwwka::ChannelConnector).to receive(:new).and_raise("blow up")
93
- expect{
94
- Pwwka::Transmitter.send_message!(payload, routing_key)
95
- }.to raise_error
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
- .with(payload, routing_key, 2000)
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
- .with(payload, routing_key)
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
- .with(payload, routing_key, 2000)
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
- .with(payload, routing_key)
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.2
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-06-03 00:00:00.000000000 Z
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.4.1
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