pwwka 0.22.7 → 0.23.RC1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +24 -66
- data/.ruby-version +1 -1
- data/Gemfile.rails-5.1 +2 -1
- data/Gemfile.rails-5.2 +2 -1
- data/README.md +8 -13
- data/lib/pwwka.rb +1 -0
- data/lib/pwwka/configuration.rb +3 -8
- data/lib/pwwka/persistent_transmitter.rb +59 -0
- data/lib/pwwka/transmitter.rb +5 -18
- data/lib/pwwka/version.rb +1 -1
- data/owners.json +1 -1
- data/pwwka.gemspec +1 -1
- data/spec/integration/send_and_receive_spec.rb +5 -25
- data/spec/unit/configuration_spec.rb +1 -5
- data/spec/unit/persistent_transmitter_spec.rb +153 -0
- data/spec/unit/transmitter_spec.rb +7 -7
- metadata +13 -11
- data/CODEOWNERS +0 -1
- data/Gemfile.rails-6.0 +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 312eaa13f1a4ba429bd2ab95c9c95713e7f95a8436870a268eb889824fde311a
|
4
|
+
data.tar.gz: '008f9726a92efe538913689cd0b761e09bae1b5d967bf6c521db86a4527a7bb8'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 38b032c92ccbb1fbb216bb42b53c45f6679426426a2c2813a3d8c1af9e20da851da69ce2b1ca0ce2e90774d6ddcbf4023dbc0667a2c211e51d20b03941dc5ccb
|
7
|
+
data.tar.gz: 53513f852876b8ce83fb101018205d8dd74dd150d0b61f6dc69fdb91c35cf6a3f5a280e7b890261f1e063220adab1b7ee70a78bce3211d53d7955dce45448f89
|
data/.circleci/config.yml
CHANGED
@@ -3,31 +3,16 @@
|
|
3
3
|
---
|
4
4
|
version: 2
|
5
5
|
jobs:
|
6
|
-
|
6
|
+
ruby-2.6.1-rails-5.2:
|
7
7
|
docker:
|
8
|
-
- image: circleci/ruby:2.
|
9
|
-
steps:
|
10
|
-
- checkout
|
11
|
-
- run: bundle config stitchfix01.jfrog.io $ARTIFACTORY_USER:$ARTIFACTORY_TOKEN
|
12
|
-
- run: bundle install --full-index
|
13
|
-
- run:
|
14
|
-
name: Artifactory login
|
15
|
-
command: mkdir -p ~/.gem && curl -u$ARTIFACTORY_USER:$ARTIFACTORY_TOKEN https://stitchfix01.jfrog.io/stitchfix01/api/gems/eng-gems/api/v1/api_key.yaml
|
16
|
-
> ~/.gem/credentials && chmod 0600 ~/.gem/credentials
|
17
|
-
- run:
|
18
|
-
name: Build/release gem to artifactory
|
19
|
-
command: bundle exec rake push_artifactory
|
20
|
-
ruby-2.7.1-rails-6.0:
|
21
|
-
docker:
|
22
|
-
- image: circleci/ruby:2.7.1
|
8
|
+
- image: circleci/ruby:2.6.1
|
23
9
|
environment:
|
24
|
-
BUNDLE_GEMFILE: Gemfile.rails-
|
10
|
+
BUNDLE_GEMFILE: Gemfile.rails-5.2
|
25
11
|
- image: redis:2.8.12
|
26
12
|
- image: rabbitmq:3.5.6
|
27
13
|
working_directory: "~/pwwka"
|
28
14
|
steps:
|
29
15
|
- checkout
|
30
|
-
- run: bundle config stitchfix01.jfrog.io $ARTIFACTORY_USER:$ARTIFACTORY_TOKEN
|
31
16
|
- run: bundle install --full-index
|
32
17
|
- run: bundle exec rspec --format RspecJunitFormatter --out /tmp/test-results/rspec.xml
|
33
18
|
--format=doc
|
@@ -37,21 +22,20 @@ jobs:
|
|
37
22
|
fi
|
38
23
|
- run:
|
39
24
|
name: Notify Pager Duty
|
40
|
-
command: bundle exec y-notify
|
25
|
+
command: 'bundle exec y-notify #eng-platform'
|
41
26
|
when: on_fail
|
42
27
|
- store_test_results:
|
43
28
|
path: "/tmp/test-results"
|
44
|
-
ruby-2.
|
29
|
+
ruby-2.5.3-rails-5.2:
|
45
30
|
docker:
|
46
|
-
- image: circleci/ruby:2.
|
31
|
+
- image: circleci/ruby:2.5.3
|
47
32
|
environment:
|
48
|
-
BUNDLE_GEMFILE: Gemfile.rails-
|
33
|
+
BUNDLE_GEMFILE: Gemfile.rails-5.2
|
49
34
|
- image: redis:2.8.12
|
50
35
|
- image: rabbitmq:3.5.6
|
51
36
|
working_directory: "~/pwwka"
|
52
37
|
steps:
|
53
38
|
- checkout
|
54
|
-
- run: bundle config stitchfix01.jfrog.io $ARTIFACTORY_USER:$ARTIFACTORY_TOKEN
|
55
39
|
- run: bundle install --full-index
|
56
40
|
- run: bundle exec rspec --format RspecJunitFormatter --out /tmp/test-results/rspec.xml
|
57
41
|
--format=doc
|
@@ -61,21 +45,20 @@ jobs:
|
|
61
45
|
fi
|
62
46
|
- run:
|
63
47
|
name: Notify Pager Duty
|
64
|
-
command: bundle exec y-notify
|
48
|
+
command: 'bundle exec y-notify #eng-platform'
|
65
49
|
when: on_fail
|
66
50
|
- store_test_results:
|
67
51
|
path: "/tmp/test-results"
|
68
|
-
ruby-2.
|
52
|
+
ruby-2.6.1-rails-5.1:
|
69
53
|
docker:
|
70
|
-
- image: circleci/ruby:2.
|
54
|
+
- image: circleci/ruby:2.6.1
|
71
55
|
environment:
|
72
|
-
BUNDLE_GEMFILE: Gemfile.rails-5.
|
56
|
+
BUNDLE_GEMFILE: Gemfile.rails-5.1
|
73
57
|
- image: redis:2.8.12
|
74
58
|
- image: rabbitmq:3.5.6
|
75
59
|
working_directory: "~/pwwka"
|
76
60
|
steps:
|
77
61
|
- checkout
|
78
|
-
- run: bundle config stitchfix01.jfrog.io $ARTIFACTORY_USER:$ARTIFACTORY_TOKEN
|
79
62
|
- run: bundle install --full-index
|
80
63
|
- run: bundle exec rspec --format RspecJunitFormatter --out /tmp/test-results/rspec.xml
|
81
64
|
--format=doc
|
@@ -85,21 +68,20 @@ jobs:
|
|
85
68
|
fi
|
86
69
|
- run:
|
87
70
|
name: Notify Pager Duty
|
88
|
-
command: bundle exec y-notify
|
71
|
+
command: 'bundle exec y-notify #eng-platform'
|
89
72
|
when: on_fail
|
90
73
|
- store_test_results:
|
91
74
|
path: "/tmp/test-results"
|
92
|
-
ruby-2.
|
75
|
+
ruby-2.5.3-rails-5.1:
|
93
76
|
docker:
|
94
|
-
- image: circleci/ruby:2.
|
77
|
+
- image: circleci/ruby:2.5.3
|
95
78
|
environment:
|
96
|
-
BUNDLE_GEMFILE: Gemfile.rails-5.
|
79
|
+
BUNDLE_GEMFILE: Gemfile.rails-5.1
|
97
80
|
- image: redis:2.8.12
|
98
81
|
- image: rabbitmq:3.5.6
|
99
82
|
working_directory: "~/pwwka"
|
100
83
|
steps:
|
101
84
|
- checkout
|
102
|
-
- run: bundle config stitchfix01.jfrog.io $ARTIFACTORY_USER:$ARTIFACTORY_TOKEN
|
103
85
|
- run: bundle install --full-index
|
104
86
|
- run: bundle exec rspec --format RspecJunitFormatter --out /tmp/test-results/rspec.xml
|
105
87
|
--format=doc
|
@@ -109,7 +91,7 @@ jobs:
|
|
109
91
|
fi
|
110
92
|
- run:
|
111
93
|
name: Notify Pager Duty
|
112
|
-
command: bundle exec y-notify
|
94
|
+
command: 'bundle exec y-notify #eng-platform'
|
113
95
|
when: on_fail
|
114
96
|
- store_test_results:
|
115
97
|
path: "/tmp/test-results"
|
@@ -117,38 +99,14 @@ workflows:
|
|
117
99
|
version: 2
|
118
100
|
on-commit:
|
119
101
|
jobs:
|
120
|
-
-
|
121
|
-
context: org-global
|
122
|
-
requires:
|
123
|
-
- ruby-2.7.1-rails-6.0
|
124
|
-
- ruby-2.6.6-rails-6.0
|
125
|
-
- ruby-2.7.1-rails-5.2
|
126
|
-
- ruby-2.6.6-rails-5.2
|
127
|
-
filters:
|
128
|
-
tags:
|
129
|
-
only: /^[0-9]+\.[0-9]+\.[0-9]+(\.?(RC|rc)[-\.]?\d*)?$/
|
130
|
-
branches:
|
131
|
-
ignore: /.*/
|
132
|
-
- ruby-2.7.1-rails-6.0:
|
102
|
+
- ruby-2.6.1-rails-5.2:
|
133
103
|
context: org-global
|
134
|
-
|
135
|
-
tags:
|
136
|
-
only: &1 /.*/
|
137
|
-
- ruby-2.6.6-rails-6.0:
|
104
|
+
- ruby-2.5.3-rails-5.2:
|
138
105
|
context: org-global
|
139
|
-
|
140
|
-
tags:
|
141
|
-
only: *1
|
142
|
-
- ruby-2.7.1-rails-5.2:
|
106
|
+
- ruby-2.6.1-rails-5.1:
|
143
107
|
context: org-global
|
144
|
-
|
145
|
-
tags:
|
146
|
-
only: *1
|
147
|
-
- ruby-2.6.6-rails-5.2:
|
108
|
+
- ruby-2.5.3-rails-5.1:
|
148
109
|
context: org-global
|
149
|
-
filters:
|
150
|
-
tags:
|
151
|
-
only: *1
|
152
110
|
scheduled:
|
153
111
|
triggers:
|
154
112
|
- schedule:
|
@@ -158,11 +116,11 @@ workflows:
|
|
158
116
|
only:
|
159
117
|
- master
|
160
118
|
jobs:
|
161
|
-
- ruby-2.
|
119
|
+
- ruby-2.6.1-rails-5.2:
|
162
120
|
context: org-global
|
163
|
-
- ruby-2.
|
121
|
+
- ruby-2.5.3-rails-5.2:
|
164
122
|
context: org-global
|
165
|
-
- ruby-2.
|
123
|
+
- ruby-2.6.1-rails-5.1:
|
166
124
|
context: org-global
|
167
|
-
- ruby-2.
|
125
|
+
- ruby-2.5.3-rails-5.1:
|
168
126
|
context: org-global
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.5.1
|
data/Gemfile.rails-5.1
CHANGED
data/Gemfile.rails-5.2
CHANGED
data/README.md
CHANGED
@@ -148,8 +148,8 @@ Pwwka::Transmitter.send_message!(payload, routing_key, on_error: :ignore)
|
|
148
148
|
|
149
149
|
#### Delayed Messages
|
150
150
|
|
151
|
-
You might want to delay sending a message (for example, if you have just created a database
|
152
|
-
record and a race condition keeps catching you out). In that case you can use delayed message
|
151
|
+
You might want to delay sending a message (for example, if you have just created a database
|
152
|
+
record and a race condition keeps catching you out). In that case you can use delayed message
|
153
153
|
options:
|
154
154
|
|
155
155
|
```ruby
|
@@ -176,12 +176,7 @@ Pwwka.configure do |config|
|
|
176
176
|
end
|
177
177
|
```
|
178
178
|
|
179
|
-
Regardless of which processor you use, the name of the queue created is `pwwka_send_message_async`.
|
180
|
-
|
181
|
-
```ruby
|
182
|
-
pwwka_send_message_async_worker: rake resque:work QUEUE=pwwka_send_message_async
|
183
|
-
```
|
184
|
-
|
179
|
+
Regardless of which processor you use, the name of the queue created is `pwwka_send_message_async`.
|
185
180
|
|
186
181
|
You can also configure Pwwka to use your own custom job using the `async_job_klass` configuration option. An example might be:
|
187
182
|
```
|
@@ -196,7 +191,7 @@ If you are using Resque and `Resque::Plugins::ExponentialBackoff` is available,
|
|
196
191
|
|
197
192
|
#### Message Queuer
|
198
193
|
|
199
|
-
You can queue up messages and send them in a batch. This is most useful when multiple messages
|
194
|
+
You can queue up messages and send them in a batch. This is most useful when multiple messages
|
200
195
|
need to sent from within a transaction block.
|
201
196
|
|
202
197
|
For example:
|
@@ -260,7 +255,7 @@ Here is an example:
|
|
260
255
|
|
261
256
|
```ruby
|
262
257
|
class ClientIndexMessageHandler
|
263
|
-
|
258
|
+
|
264
259
|
def self.handle!(delivery_info, properties, payload)
|
265
260
|
handler.do_a_thing(payload)
|
266
261
|
end
|
@@ -435,7 +430,7 @@ If you use [Resque][resque], and you wish to handle messages in a resque job, yo
|
|
435
430
|
|
436
431
|
Note that you must provide `@queue` in your job. `QueueResqueJobHandler` doesn't support setting a custom queue at enqueue-time (PRs welcome :).
|
437
432
|
|
438
|
-
Note that if you were using this library before version 0.12.0, your job would only be given the payload. If you change your job to accept exatly three arguments, you will be given the payload, routing key, and message properties. If any of those arguments are optional, you will need to set `PWWKA_QUEUE_EXTENDED_INFO` to `"true"` to force pwwka to pass those along. Without it, your job only gets the payload to avoid breaking legacy consumers.
|
433
|
+
Note that if you were using this library before version 0.12.0, your job would only be given the payload. If you change your job to accept exatly three arguments, you will be given the payload, routing key, and message properties. If any of those arguments are optional, you will need to set `PWWKA_QUEUE_EXTENDED_INFO` to `"true"` to force pwwka to pass those along. Without it, your job only gets the payload to avoid breaking legacy consumers.
|
439
434
|
|
440
435
|
3. Profit!
|
441
436
|
|
@@ -459,9 +454,9 @@ describe "my integration test" do
|
|
459
454
|
@test_handler.test_setup
|
460
455
|
end
|
461
456
|
|
462
|
-
after(:all) do
|
457
|
+
after(:all) do
|
463
458
|
# this clears out any messages, so you have a clean test environment next time
|
464
|
-
@test_handler.test_teardown
|
459
|
+
@test_handler.test_teardown
|
465
460
|
end
|
466
461
|
|
467
462
|
it "uses the message bus" do
|
data/lib/pwwka.rb
CHANGED
@@ -27,6 +27,7 @@ require 'pwwka/channel_connector'
|
|
27
27
|
require 'pwwka/handling'
|
28
28
|
require 'pwwka/receiver'
|
29
29
|
require 'pwwka/transmitter'
|
30
|
+
require 'pwwka/persistent_transmitter'
|
30
31
|
require 'pwwka/message_queuer'
|
31
32
|
require 'pwwka/error_handlers'
|
32
33
|
require 'pwwka/configuration'
|
data/lib/pwwka/configuration.rb
CHANGED
@@ -45,15 +45,10 @@ module Pwwka
|
|
45
45
|
def app_id
|
46
46
|
if @app_id.to_s.strip == ""
|
47
47
|
if defined?(Rails)
|
48
|
-
if Rails.respond_to?(:application)
|
49
|
-
|
50
|
-
# of the deprecated Module#parent for Rails 5 compatibility. see
|
51
|
-
# https://github.com/stitchfix/pwwka/issues/91 for context.
|
52
|
-
app_klass = Rails.application.class
|
53
|
-
app_parent = Rails.version =~ /^6/ ? app_klass.module_parent : app_klass.parent
|
54
|
-
app_parent.name
|
48
|
+
if Rails.respond_to?(:application)
|
49
|
+
Rails.application.class.parent.name
|
55
50
|
else
|
56
|
-
raise "'Rails' is defined, but it doesn't respond to #application
|
51
|
+
raise "'Rails' is defined, but it doesn't respond to #application, so could not derive the app_id; you must explicitly set it"
|
57
52
|
end
|
58
53
|
else
|
59
54
|
raise "Could not derive the app_id; you must explicitly set it"
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require_relative "publish_options"
|
2
|
+
|
3
|
+
begin # optional dependency
|
4
|
+
require 'resque'
|
5
|
+
require 'resque-retry'
|
6
|
+
rescue LoadError
|
7
|
+
end
|
8
|
+
|
9
|
+
module Pwwka
|
10
|
+
# Primary interface for sending messages.
|
11
|
+
#
|
12
|
+
# Example:
|
13
|
+
#
|
14
|
+
# # Send a message, blowing up if there's any problem
|
15
|
+
# Pwwka::PersistentTransmitter.batch do |transmitter|
|
16
|
+
# transmitter.send_message!({ user_id: @user.id }, "users.user.activated")
|
17
|
+
# end
|
18
|
+
|
19
|
+
class PersistentTransmitter
|
20
|
+
|
21
|
+
extend Pwwka::Logging
|
22
|
+
include Pwwka::Logging
|
23
|
+
|
24
|
+
DEFAULT_DELAY_BY_MS = 5000
|
25
|
+
|
26
|
+
attr_reader :channel_connector
|
27
|
+
|
28
|
+
def initialize
|
29
|
+
@channel_connector = ChannelConnector.new(connection_name: "p: #{Pwwka.configuration.app_id} #{Pwwka.configuration.process_name}".strip)
|
30
|
+
end
|
31
|
+
|
32
|
+
def send_message!(payload, routing_key, type: nil, headers: nil, message_id: :auto_generate)
|
33
|
+
publish_options = Pwwka::PublishOptions.new(
|
34
|
+
routing_key: routing_key,
|
35
|
+
message_id: message_id,
|
36
|
+
type: type,
|
37
|
+
headers: headers
|
38
|
+
)
|
39
|
+
logf "START Transmitting Message on id[%{id}] %{routing_key} -> %{payload}", id: publish_options.message_id, routing_key: routing_key, payload: payload
|
40
|
+
channel_connector.topic_exchange.publish(payload.to_json, publish_options.to_h)
|
41
|
+
# if it gets this far it has succeeded
|
42
|
+
logf "END Transmitting Message on id[%{id}] %{routing_key} -> %{payload}", id: publish_options.message_id, routing_key: routing_key, payload: payload
|
43
|
+
true
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
class << self
|
48
|
+
private :new
|
49
|
+
|
50
|
+
def batch
|
51
|
+
transmitter = new
|
52
|
+
yield(transmitter)
|
53
|
+
ensure
|
54
|
+
transmitter.channel_connector.connection_close
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/pwwka/transmitter.rb
CHANGED
@@ -29,7 +29,7 @@ module Pwwka
|
|
29
29
|
@channel_connector = ChannelConnector.new(connection_name: "p: #{Pwwka.configuration.app_id} #{Pwwka.configuration.process_name}".strip)
|
30
30
|
end
|
31
31
|
|
32
|
-
# Send an important message that must go through. This method allows any raised exception
|
32
|
+
# Send an important message that must go through. This method allows any raised exception
|
33
33
|
# to pass through.
|
34
34
|
#
|
35
35
|
# payload:: Hash of what you'd like to include in your message
|
@@ -95,24 +95,11 @@ module Pwwka
|
|
95
95
|
job = Pwwka.configuration.async_job_klass
|
96
96
|
|
97
97
|
if background_job_processor == :resque
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
# NOTE: (jdlubrano)
|
102
|
-
# Why can't we pass these options all of the time? Well, if a user
|
103
|
-
# of pwwka has configured their own async_job_klass that only has an
|
104
|
-
# arity of 2 (i.e. payload and routing key), then passing these options
|
105
|
-
# as an additional argument would break the user's application. In
|
106
|
-
# order to maintain compatibility with preceding versions of Pwwka,
|
107
|
-
# we need to ensure that the same arguments passed into this method
|
108
|
-
# result in compatible calls to enqueue any Resque jobs.
|
109
|
-
resque_args << { type: type, message_id: message_id, headers: headers }
|
110
|
-
end
|
111
|
-
|
112
|
-
if delay_by_ms.zero?
|
113
|
-
Resque.enqueue(*resque_args)
|
98
|
+
# Be perhaps too carefully making sure we queue jobs in the legacy way
|
99
|
+
if type == nil && message_id == :auto_generate && headers == nil
|
100
|
+
Resque.enqueue_in(delay_by_ms/1000, job, payload, routing_key)
|
114
101
|
else
|
115
|
-
Resque.enqueue_in(delay_by_ms/1000,
|
102
|
+
Resque.enqueue_in(delay_by_ms/1000, job, payload, routing_key, type: type, message_id: message_id, headers: headers)
|
116
103
|
end
|
117
104
|
elsif background_job_processor == :sidekiq
|
118
105
|
options = { delay_by_ms: delay_by_ms, type: type, message_id: message_id, headers: headers }
|
data/lib/pwwka/version.rb
CHANGED
data/owners.json
CHANGED
data/pwwka.gemspec
CHANGED
@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
|
|
26
26
|
s.add_development_dependency("rake")
|
27
27
|
s.add_development_dependency("rspec")
|
28
28
|
s.add_development_dependency("resque")
|
29
|
-
s.add_development_dependency("resque-retry"
|
29
|
+
s.add_development_dependency("resque-retry")
|
30
30
|
s.add_development_dependency("sidekiq")
|
31
31
|
s.add_development_dependency("simplecov")
|
32
32
|
s.add_development_dependency("resqutils")
|
@@ -11,9 +11,6 @@ describe "sending and receiving messages", :integration do
|
|
11
11
|
include IntegrationTestHelpers
|
12
12
|
include Resqutils::Spec::ResqueHelpers
|
13
13
|
|
14
|
-
let(:async_resque_queue) { 'pwwka_send_message_async' }
|
15
|
-
let(:delayed_resque_queue) { :delayed }
|
16
|
-
|
17
14
|
before do
|
18
15
|
ENV["JOB_KLASS"] = MyTestJob.name
|
19
16
|
ENV["PWWKA_QUEUE_EXTENDED_INFO"] = "true"
|
@@ -33,8 +30,7 @@ describe "sending and receiving messages", :integration do
|
|
33
30
|
FooReceiver.reset!
|
34
31
|
MultiRoutingReceived.reset!
|
35
32
|
OtherFooReceiver.reset!
|
36
|
-
clear_queue(
|
37
|
-
clear_queue(delayed_resque_queue)
|
33
|
+
clear_queue(:delayed)
|
38
34
|
clear_queue(MyTestJob)
|
39
35
|
end
|
40
36
|
|
@@ -148,7 +144,7 @@ describe "sending and receiving messages", :integration do
|
|
148
144
|
|
149
145
|
expect(AllReceiver.messages_received.size).to eq(0)
|
150
146
|
|
151
|
-
process_resque_job(Pwwka::SendMessageAsyncJob
|
147
|
+
process_resque_job(Pwwka::SendMessageAsyncJob,:delayed)
|
152
148
|
|
153
149
|
allow_receivers_to_process_queues
|
154
150
|
|
@@ -170,7 +166,7 @@ describe "sending and receiving messages", :integration do
|
|
170
166
|
|
171
167
|
expect(AllReceiver.messages_received.size).to eq(0)
|
172
168
|
|
173
|
-
process_resque_job(Pwwka::SendMessageAsyncJob
|
169
|
+
process_resque_job(Pwwka::SendMessageAsyncJob,:delayed)
|
174
170
|
|
175
171
|
allow_receivers_to_process_queues
|
176
172
|
|
@@ -190,28 +186,12 @@ describe "sending and receiving messages", :integration do
|
|
190
186
|
|
191
187
|
allow(Pwwka).to receive(:configuration).and_return(configuration)
|
192
188
|
|
193
|
-
allow(Resque).to receive(:
|
189
|
+
allow(Resque).to receive(:enqueue_in)
|
194
190
|
|
195
191
|
Pwwka::Transmitter.send_message_async({ sample: "payload", has: { deeply: true, nested: 4 }},
|
196
192
|
"pwwka.testing.bar")
|
197
193
|
|
198
|
-
expect(Resque).to have_received(:
|
199
|
-
end
|
200
|
-
|
201
|
-
it "can queue a job to send a message with a delay" do
|
202
|
-
Pwwka::Transmitter.send_message_async({ sample: "payload" },
|
203
|
-
"pwwka.testing.bar",
|
204
|
-
delay_by_ms: 1)
|
205
|
-
|
206
|
-
allow_receivers_to_process_queues # not expecting anything to be processed
|
207
|
-
|
208
|
-
expect(AllReceiver.messages_received.size).to eq(0)
|
209
|
-
|
210
|
-
process_resque_job(Pwwka::SendMessageAsyncJob, delayed_resque_queue)
|
211
|
-
|
212
|
-
allow_receivers_to_process_queues
|
213
|
-
|
214
|
-
expect(AllReceiver.messages_received.size).to eq(1)
|
194
|
+
expect(Resque).to have_received(:enqueue_in).with(anything, async_job_klass, anything, anything)
|
215
195
|
end
|
216
196
|
end
|
217
197
|
|
@@ -75,10 +75,6 @@ describe Pwwka::Configuration do
|
|
75
75
|
def self.application
|
76
76
|
MyAmazingApp::Application.new
|
77
77
|
end
|
78
|
-
|
79
|
-
def self.version
|
80
|
-
'5.2.0'
|
81
|
-
end
|
82
78
|
end
|
83
79
|
Object.const_set("Rails",rails)
|
84
80
|
end
|
@@ -101,7 +97,7 @@ describe Pwwka::Configuration do
|
|
101
97
|
it "blows up when not set" do
|
102
98
|
expect {
|
103
99
|
configuration.app_id
|
104
|
-
}.to raise_error(/'Rails' is defined, but it doesn't respond to #application
|
100
|
+
}.to raise_error(/'Rails' is defined, but it doesn't respond to #application, so could not derive the app_id; you must explicitly set it/)
|
105
101
|
end
|
106
102
|
end
|
107
103
|
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
describe Pwwka::PersistentTransmitter do
|
4
|
+
let(:topic_exchange) { double("topic exchange") }
|
5
|
+
let(:delayed_exchange) { double("delayed exchange") }
|
6
|
+
let(:channel_connector) { instance_double(Pwwka::ChannelConnector, topic_exchange: topic_exchange, delayed_exchange: delayed_exchange) }
|
7
|
+
let(:logger) { double(Logger) }
|
8
|
+
let(:payload) {
|
9
|
+
{
|
10
|
+
foo: { bar: "blah" },
|
11
|
+
crud: 12,
|
12
|
+
}
|
13
|
+
}
|
14
|
+
let(:routing_key) { "sf.foo.bar" }
|
15
|
+
|
16
|
+
|
17
|
+
before do
|
18
|
+
@original_logger = Pwwka.configuration.logger
|
19
|
+
Pwwka.configuration.logger = logger
|
20
|
+
allow(logger).to receive(:info)
|
21
|
+
allow(logger).to receive(:warn)
|
22
|
+
allow(logger).to receive(:error)
|
23
|
+
allow(Pwwka::ChannelConnector).to receive(:new).with(connection_name: "p: MyAwesomeApp my_awesome_process").and_return(channel_connector)
|
24
|
+
allow(channel_connector).to receive(:connection_close)
|
25
|
+
allow(topic_exchange).to receive(:publish)
|
26
|
+
allow(delayed_exchange).to receive(:publish)
|
27
|
+
end
|
28
|
+
|
29
|
+
after do
|
30
|
+
Pwwka.configuration.logger = @original_logger
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
shared_examples "it sends standard and overridden data to the exchange" do
|
35
|
+
it "publishes to the topic exchange" do
|
36
|
+
expect(exchange).to have_received(:publish).with(payload.to_json, kind_of(Hash))
|
37
|
+
end
|
38
|
+
|
39
|
+
it "passes the routing key" do
|
40
|
+
expect(exchange).to have_received(:publish).with(
|
41
|
+
payload.to_json,
|
42
|
+
hash_including(routing_key: routing_key))
|
43
|
+
end
|
44
|
+
|
45
|
+
it "sets the type" do
|
46
|
+
expect(exchange).to have_received(:publish).with(
|
47
|
+
payload.to_json,
|
48
|
+
hash_including(type: "Customer"))
|
49
|
+
end
|
50
|
+
|
51
|
+
it "sets the headers" do
|
52
|
+
expect(exchange).to have_received(:publish).with(
|
53
|
+
payload.to_json,
|
54
|
+
hash_including(headers: { "custom" => "value", "other_custom" => "other_value" }))
|
55
|
+
end
|
56
|
+
|
57
|
+
it "uses the overridden message id" do
|
58
|
+
expect(exchange).to have_received(:publish).with(
|
59
|
+
payload.to_json,
|
60
|
+
hash_including(message_id: "snowflake id that is likely a bad idea, but if you must"))
|
61
|
+
end
|
62
|
+
|
63
|
+
it "sets the app id to what's configured" do
|
64
|
+
expect(exchange).to have_received(:publish).with(
|
65
|
+
payload.to_json,
|
66
|
+
hash_including(app_id: "MyAwesomeApp"))
|
67
|
+
end
|
68
|
+
|
69
|
+
it "sets the content type to JSON with a version" do
|
70
|
+
expect(exchange).to have_received(:publish).with(
|
71
|
+
payload.to_json,
|
72
|
+
hash_including(content_type: "application/json; version=1"))
|
73
|
+
end
|
74
|
+
|
75
|
+
it "sets persistent true" do
|
76
|
+
expect(exchange).to have_received(:publish).with(
|
77
|
+
payload.to_json,
|
78
|
+
hash_including(persistent: true))
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
context "no new instance creation" do
|
84
|
+
it "doesn't allow creation of new instances unless inside the batch method" do
|
85
|
+
expect{ Pwwka::PersistentTransmitter.new }.to raise_error
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "#batch" do
|
90
|
+
context "Logging" do
|
91
|
+
it "logs the start and end of the transmission" do
|
92
|
+
described_class.batch do |transmitter|
|
93
|
+
transmitter.send_message!(payload,routing_key)
|
94
|
+
end
|
95
|
+
expect(logger).to have_received(:info).with(/START Transmitting Message on id\[[\w\-\d]+\] #{routing_key} ->/)
|
96
|
+
expect(logger).to have_received(:info).with(/END Transmitting Message on id\[[\w\-\d]+\] #{routing_key} ->/)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
it "closes the channel connector" do
|
101
|
+
described_class.batch do |transmitter|
|
102
|
+
transmitter.send_message!(payload,routing_key)
|
103
|
+
end
|
104
|
+
expect(channel_connector).to have_received(:connection_close)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "only uses one connection" do
|
108
|
+
described_class.batch do |transmitter|
|
109
|
+
10.times do
|
110
|
+
transmitter.send_message!(payload,routing_key)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
expect(channel_connector).to have_received(:connection_close).once
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'when an error is raised' do
|
118
|
+
|
119
|
+
let(:error) { 'oh no' }
|
120
|
+
|
121
|
+
before do
|
122
|
+
allow(topic_exchange).to receive(:publish).and_raise(error)
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'should raise the error and still close the channel_connector' do
|
126
|
+
expect { described_class.batch do |transmitter|
|
127
|
+
transmitter.send_message!(payload,routing_key)
|
128
|
+
end } .to raise_error(error)
|
129
|
+
expect(channel_connector).to have_received(:connection_close)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context "with everything overridden" do
|
134
|
+
before do
|
135
|
+
described_class.batch do |transmitter|
|
136
|
+
transmitter.send_message!(
|
137
|
+
payload,
|
138
|
+
routing_key,
|
139
|
+
message_id: "snowflake id that is likely a bad idea, but if you must",
|
140
|
+
type: "Customer",
|
141
|
+
headers: {
|
142
|
+
"custom" => "value",
|
143
|
+
"other_custom" => "other_value",
|
144
|
+
})
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
it_behaves_like "it sends standard and overridden data to the exchange" do
|
149
|
+
let(:exchange) { topic_exchange }
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
@@ -312,19 +312,19 @@ describe Pwwka::Transmitter do
|
|
312
312
|
end
|
313
313
|
context "on_error: :resque" do
|
314
314
|
it "queues a Resque job" do
|
315
|
-
allow(Resque).to receive(:
|
315
|
+
allow(Resque).to receive(:enqueue_in)
|
316
316
|
described_class.send_message!(payload,routing_key, on_error: :resque)
|
317
|
-
expect(Resque).to have_received(:
|
317
|
+
expect(Resque).to have_received(:enqueue_in).with(0,Pwwka::SendMessageAsyncJob,payload,routing_key)
|
318
318
|
end
|
319
319
|
context "when there is a problem queueing the resque job" do
|
320
320
|
it "raises the original exception job" do
|
321
|
-
allow(Resque).to receive(:
|
321
|
+
allow(Resque).to receive(:enqueue_in).and_raise("NOPE")
|
322
322
|
expect {
|
323
323
|
described_class.send_message!(payload,routing_key, on_error: :resque)
|
324
324
|
}.to raise_error(/OH NOES/)
|
325
325
|
end
|
326
326
|
it "logs the Resque error as a warning" do
|
327
|
-
allow(Resque).to receive(:
|
327
|
+
allow(Resque).to receive(:enqueue_in).and_raise("NOPE")
|
328
328
|
begin
|
329
329
|
described_class.send_message!(payload,routing_key, on_error: :resque)
|
330
330
|
rescue => ex
|
@@ -338,18 +338,18 @@ describe Pwwka::Transmitter do
|
|
338
338
|
context "when configured background_job_processor is Resque" do
|
339
339
|
context "when the job is queued successfully" do
|
340
340
|
before do
|
341
|
-
allow(Resque).to receive(:
|
341
|
+
allow(Resque).to receive(:enqueue_in)
|
342
342
|
end
|
343
343
|
|
344
344
|
it "queues a Resque job" do
|
345
345
|
described_class.send_message!(payload, routing_key, on_error: :retry_async)
|
346
|
-
expect(Resque).to have_received(:
|
346
|
+
expect(Resque).to have_received(:enqueue_in).with(0, Pwwka::SendMessageAsyncJob, payload, routing_key)
|
347
347
|
end
|
348
348
|
end
|
349
349
|
|
350
350
|
context "when there is a problem queueing the Resque job" do
|
351
351
|
before do
|
352
|
-
allow(Resque).to receive(:
|
352
|
+
allow(Resque).to receive(:enqueue_in).and_raise("NOPE")
|
353
353
|
end
|
354
354
|
|
355
355
|
it "raises the original exception job" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pwwka
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.23.RC1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stitch Fix Engineering
|
@@ -15,7 +15,7 @@ authors:
|
|
15
15
|
autorequire:
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
|
-
date:
|
18
|
+
date: 2019-04-25 00:00:00.000000000 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: bunny
|
@@ -119,16 +119,16 @@ dependencies:
|
|
119
119
|
name: resque-retry
|
120
120
|
requirement: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- - "
|
122
|
+
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
124
|
+
version: '0'
|
125
125
|
type: :development
|
126
126
|
prerelease: false
|
127
127
|
version_requirements: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
|
-
- - "
|
129
|
+
- - ">="
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version:
|
131
|
+
version: '0'
|
132
132
|
- !ruby/object:Gem::Dependency
|
133
133
|
name: sidekiq
|
134
134
|
requirement: !ruby/object:Gem::Requirement
|
@@ -235,7 +235,6 @@ files:
|
|
235
235
|
- ".ruby-gemset"
|
236
236
|
- ".ruby-version"
|
237
237
|
- ".travis.yml"
|
238
|
-
- CODEOWNERS
|
239
238
|
- CODE_OF_CONDUCT.md
|
240
239
|
- CONTRIBUTING.md
|
241
240
|
- Gemfile
|
@@ -243,7 +242,6 @@ files:
|
|
243
242
|
- Gemfile.rails-5.0
|
244
243
|
- Gemfile.rails-5.1
|
245
244
|
- Gemfile.rails-5.2
|
246
|
-
- Gemfile.rails-6.0
|
247
245
|
- LICENSE
|
248
246
|
- README.md
|
249
247
|
- Rakefile
|
@@ -265,6 +263,7 @@ files:
|
|
265
263
|
- lib/pwwka/handling.rb
|
266
264
|
- lib/pwwka/logging.rb
|
267
265
|
- lib/pwwka/message_queuer.rb
|
266
|
+
- lib/pwwka/persistent_transmitter.rb
|
268
267
|
- lib/pwwka/publish_options.rb
|
269
268
|
- lib/pwwka/queue_resque_job_handler.rb
|
270
269
|
- lib/pwwka/receiver.rb
|
@@ -294,6 +293,7 @@ files:
|
|
294
293
|
- spec/unit/configuration_spec.rb
|
295
294
|
- spec/unit/logging_spec.rb
|
296
295
|
- spec/unit/message_queuer_spec.rb
|
296
|
+
- spec/unit/persistent_transmitter_spec.rb
|
297
297
|
- spec/unit/queue_resque_job_handler_spec.rb
|
298
298
|
- spec/unit/receiver_spec.rb
|
299
299
|
- spec/unit/send_message_async_job_spec.rb
|
@@ -315,11 +315,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
315
315
|
version: '0'
|
316
316
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
317
317
|
requirements:
|
318
|
-
- - "
|
318
|
+
- - ">"
|
319
319
|
- !ruby/object:Gem::Version
|
320
|
-
version:
|
320
|
+
version: 1.3.1
|
321
321
|
requirements: []
|
322
|
-
|
322
|
+
rubyforge_project:
|
323
|
+
rubygems_version: 2.7.6
|
323
324
|
signing_key:
|
324
325
|
specification_version: 4
|
325
326
|
summary: Send and receive messages via RabbitMQ
|
@@ -342,6 +343,7 @@ test_files:
|
|
342
343
|
- spec/unit/configuration_spec.rb
|
343
344
|
- spec/unit/logging_spec.rb
|
344
345
|
- spec/unit/message_queuer_spec.rb
|
346
|
+
- spec/unit/persistent_transmitter_spec.rb
|
345
347
|
- spec/unit/queue_resque_job_handler_spec.rb
|
346
348
|
- spec/unit/receiver_spec.rb
|
347
349
|
- spec/unit/send_message_async_job_spec.rb
|
data/CODEOWNERS
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
* @stitchfix/eng-messaging
|