pwwka 0.23.RC1 → 1.0.0.RC1

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
  SHA256:
3
- metadata.gz: 312eaa13f1a4ba429bd2ab95c9c95713e7f95a8436870a268eb889824fde311a
4
- data.tar.gz: '008f9726a92efe538913689cd0b761e09bae1b5d967bf6c521db86a4527a7bb8'
3
+ metadata.gz: bbe20aa33393b941e9a8dfc21eff7c787ca7c1beb7daa8fa81a1e7846717ede9
4
+ data.tar.gz: edaa4a73e2a920241ebb3ffd9598fca93a1fd8c3b975dc11c2035cc059e90905
5
5
  SHA512:
6
- metadata.gz: 38b032c92ccbb1fbb216bb42b53c45f6679426426a2c2813a3d8c1af9e20da851da69ce2b1ca0ce2e90774d6ddcbf4023dbc0667a2c211e51d20b03941dc5ccb
7
- data.tar.gz: 53513f852876b8ce83fb101018205d8dd74dd150d0b61f6dc69fdb91c35cf6a3f5a280e7b890261f1e063220adab1b7ee70a78bce3211d53d7955dce45448f89
6
+ metadata.gz: 669be067f88ac9a7138134cdde10d8ca2888319633d108317f61bf4ea64fb5fc85de2a731273fa88281c85b8444d2ee2033a8513e8ee0926a18eb0b8eb6201af
7
+ data.tar.gz: 87775761df6856f4396e0f1900d794dcf91bfb4a264395cd900f7e485324796644ae7d4223daa87c3120b1f0ebf990abdce32b3a2f80e9213bd5cd93a4cb6a26
data/.circleci/config.yml CHANGED
@@ -1,19 +1,72 @@
1
- # DO NOT MODIFY - this is managed by Git Reduce in goro
1
+ # DO NOT MODIFY - this is managed by Git Reduce in goro and generated from build-matrix.json
2
2
  #
3
3
  ---
4
4
  version: 2
5
5
  jobs:
6
- ruby-2.6.1-rails-5.2:
6
+ generate-and-push-docs:
7
7
  docker:
8
- - image: circleci/ruby:2.6.1
8
+ - image: cimg/ruby:3.0.3
9
+ auth:
10
+ username: "$DOCKERHUB_USERNAME"
11
+ password: "$DOCKERHUB_PASSWORD"
12
+ steps:
13
+ - checkout
14
+ - run: bundle config stitchfix01.jfrog.io $ARTIFACTORY_USER:$ARTIFACTORY_TOKEN
15
+ - run: bundle install
16
+ - run:
17
+ name: Generate documentation
18
+ command: ' if [[ $(bundle exec rake -T docs:generate:custom) ]]; then echo
19
+ "Generating docs using rake task docs:generate:custom" ; bundle exec rake
20
+ docs:generate:custom ; elif [[ $(bundle exec rake -T docs:generate) ]];
21
+ then echo "Generating docs using rake task docs:generate" ; bundle exec
22
+ rake docs:generate ; else echo "Skipping doc generation" ; exit 0 ; fi '
23
+ - run:
24
+ name: Push documentation to Unwritten
25
+ command: if [[ $(bundle exec rake -T docs:push) ]]; then bundle exec rake
26
+ docs:push; fi
27
+ release:
28
+ docker:
29
+ - image: cimg/ruby:3.0.3
30
+ auth:
31
+ username: "$DOCKERHUB_USERNAME"
32
+ password: "$DOCKERHUB_PASSWORD"
33
+ steps:
34
+ - checkout
35
+ - run: bundle config stitchfix01.jfrog.io $ARTIFACTORY_USER:$ARTIFACTORY_TOKEN
36
+ - run: bundle install
37
+ - run:
38
+ name: Artifactory login
39
+ command: mkdir -p ~/.gem && curl -u$ARTIFACTORY_USER:$ARTIFACTORY_TOKEN https://stitchfix01.jfrog.io/stitchfix01/api/gems/eng-gems/api/v1/api_key.yaml
40
+ > ~/.gem/credentials && chmod 0600 ~/.gem/credentials
41
+ - run:
42
+ name: Build/release gem to artifactory
43
+ command: bundle exec rake push_artifactory
44
+ ruby-3.0.3-rails-7.0:
45
+ docker:
46
+ - image: cimg/ruby:3.0.3
47
+ auth:
48
+ username: "$DOCKERHUB_USERNAME"
49
+ password: "$DOCKERHUB_PASSWORD"
9
50
  environment:
10
- BUNDLE_GEMFILE: Gemfile.rails-5.2
51
+ BUNDLE_GEMFILE: Gemfile.rails-7.0
11
52
  - image: redis:2.8.12
53
+ auth:
54
+ username: "$DOCKERHUB_USERNAME"
55
+ password: "$DOCKERHUB_PASSWORD"
12
56
  - image: rabbitmq:3.5.6
57
+ auth:
58
+ username: "$DOCKERHUB_USERNAME"
59
+ password: "$DOCKERHUB_PASSWORD"
13
60
  working_directory: "~/pwwka"
14
61
  steps:
15
62
  - checkout
16
- - run: bundle install --full-index
63
+ - run:
64
+ name: Check for Gemfile.lock presence
65
+ command: ' if (test -f Gemfile.lock) then echo "Dont commit Gemfile.lock (see
66
+ https://github.com/stitchfix/eng-wiki/blob/main/architecture-decisions/0009-rubygem-dependencies-will-be-managed-more-explicitly.md)"
67
+ 1>&2 ; exit 1 ; else exit 0 ; fi '
68
+ - run: bundle config stitchfix01.jfrog.io $ARTIFACTORY_USER:$ARTIFACTORY_TOKEN
69
+ - run: bundle install
17
70
  - run: bundle exec rspec --format RspecJunitFormatter --out /tmp/test-results/rspec.xml
18
71
  --format=doc
19
72
  - run:
@@ -22,21 +75,36 @@ jobs:
22
75
  fi
23
76
  - run:
24
77
  name: Notify Pager Duty
25
- command: 'bundle exec y-notify #eng-platform'
78
+ command: bundle exec y-notify "#eng-messaging-ops"
26
79
  when: on_fail
27
80
  - store_test_results:
28
81
  path: "/tmp/test-results"
29
- ruby-2.5.3-rails-5.2:
82
+ ruby-2.7.5-rails-7.0:
30
83
  docker:
31
- - image: circleci/ruby:2.5.3
84
+ - image: cimg/ruby:2.7.5
85
+ auth:
86
+ username: "$DOCKERHUB_USERNAME"
87
+ password: "$DOCKERHUB_PASSWORD"
32
88
  environment:
33
- BUNDLE_GEMFILE: Gemfile.rails-5.2
89
+ BUNDLE_GEMFILE: Gemfile.rails-7.0
34
90
  - image: redis:2.8.12
91
+ auth:
92
+ username: "$DOCKERHUB_USERNAME"
93
+ password: "$DOCKERHUB_PASSWORD"
35
94
  - image: rabbitmq:3.5.6
95
+ auth:
96
+ username: "$DOCKERHUB_USERNAME"
97
+ password: "$DOCKERHUB_PASSWORD"
36
98
  working_directory: "~/pwwka"
37
99
  steps:
38
100
  - checkout
39
- - run: bundle install --full-index
101
+ - run:
102
+ name: Check for Gemfile.lock presence
103
+ command: ' if (test -f Gemfile.lock) then echo "Dont commit Gemfile.lock (see
104
+ https://github.com/stitchfix/eng-wiki/blob/main/architecture-decisions/0009-rubygem-dependencies-will-be-managed-more-explicitly.md)"
105
+ 1>&2 ; exit 1 ; else exit 0 ; fi '
106
+ - run: bundle config stitchfix01.jfrog.io $ARTIFACTORY_USER:$ARTIFACTORY_TOKEN
107
+ - run: bundle install
40
108
  - run: bundle exec rspec --format RspecJunitFormatter --out /tmp/test-results/rspec.xml
41
109
  --format=doc
42
110
  - run:
@@ -45,21 +113,36 @@ jobs:
45
113
  fi
46
114
  - run:
47
115
  name: Notify Pager Duty
48
- command: 'bundle exec y-notify #eng-platform'
116
+ command: bundle exec y-notify "#eng-messaging-ops"
49
117
  when: on_fail
50
118
  - store_test_results:
51
119
  path: "/tmp/test-results"
52
- ruby-2.6.1-rails-5.1:
120
+ ruby-3.0.3-rails-6.1:
53
121
  docker:
54
- - image: circleci/ruby:2.6.1
122
+ - image: cimg/ruby:3.0.3
123
+ auth:
124
+ username: "$DOCKERHUB_USERNAME"
125
+ password: "$DOCKERHUB_PASSWORD"
55
126
  environment:
56
- BUNDLE_GEMFILE: Gemfile.rails-5.1
127
+ BUNDLE_GEMFILE: Gemfile.rails-6.1
57
128
  - image: redis:2.8.12
129
+ auth:
130
+ username: "$DOCKERHUB_USERNAME"
131
+ password: "$DOCKERHUB_PASSWORD"
58
132
  - image: rabbitmq:3.5.6
133
+ auth:
134
+ username: "$DOCKERHUB_USERNAME"
135
+ password: "$DOCKERHUB_PASSWORD"
59
136
  working_directory: "~/pwwka"
60
137
  steps:
61
138
  - checkout
62
- - run: bundle install --full-index
139
+ - run:
140
+ name: Check for Gemfile.lock presence
141
+ command: ' if (test -f Gemfile.lock) then echo "Dont commit Gemfile.lock (see
142
+ https://github.com/stitchfix/eng-wiki/blob/main/architecture-decisions/0009-rubygem-dependencies-will-be-managed-more-explicitly.md)"
143
+ 1>&2 ; exit 1 ; else exit 0 ; fi '
144
+ - run: bundle config stitchfix01.jfrog.io $ARTIFACTORY_USER:$ARTIFACTORY_TOKEN
145
+ - run: bundle install
63
146
  - run: bundle exec rspec --format RspecJunitFormatter --out /tmp/test-results/rspec.xml
64
147
  --format=doc
65
148
  - run:
@@ -68,21 +151,36 @@ jobs:
68
151
  fi
69
152
  - run:
70
153
  name: Notify Pager Duty
71
- command: 'bundle exec y-notify #eng-platform'
154
+ command: bundle exec y-notify "#eng-messaging-ops"
72
155
  when: on_fail
73
156
  - store_test_results:
74
157
  path: "/tmp/test-results"
75
- ruby-2.5.3-rails-5.1:
158
+ ruby-2.7.5-rails-6.1:
76
159
  docker:
77
- - image: circleci/ruby:2.5.3
160
+ - image: cimg/ruby:2.7.5
161
+ auth:
162
+ username: "$DOCKERHUB_USERNAME"
163
+ password: "$DOCKERHUB_PASSWORD"
78
164
  environment:
79
- BUNDLE_GEMFILE: Gemfile.rails-5.1
165
+ BUNDLE_GEMFILE: Gemfile.rails-6.1
80
166
  - image: redis:2.8.12
167
+ auth:
168
+ username: "$DOCKERHUB_USERNAME"
169
+ password: "$DOCKERHUB_PASSWORD"
81
170
  - image: rabbitmq:3.5.6
171
+ auth:
172
+ username: "$DOCKERHUB_USERNAME"
173
+ password: "$DOCKERHUB_PASSWORD"
82
174
  working_directory: "~/pwwka"
83
175
  steps:
84
176
  - checkout
85
- - run: bundle install --full-index
177
+ - run:
178
+ name: Check for Gemfile.lock presence
179
+ command: ' if (test -f Gemfile.lock) then echo "Dont commit Gemfile.lock (see
180
+ https://github.com/stitchfix/eng-wiki/blob/main/architecture-decisions/0009-rubygem-dependencies-will-be-managed-more-explicitly.md)"
181
+ 1>&2 ; exit 1 ; else exit 0 ; fi '
182
+ - run: bundle config stitchfix01.jfrog.io $ARTIFACTORY_USER:$ARTIFACTORY_TOKEN
183
+ - run: bundle install
86
184
  - run: bundle exec rspec --format RspecJunitFormatter --out /tmp/test-results/rspec.xml
87
185
  --format=doc
88
186
  - run:
@@ -91,7 +189,7 @@ jobs:
91
189
  fi
92
190
  - run:
93
191
  name: Notify Pager Duty
94
- command: 'bundle exec y-notify #eng-platform'
192
+ command: bundle exec y-notify "#eng-messaging-ops"
95
193
  when: on_fail
96
194
  - store_test_results:
97
195
  path: "/tmp/test-results"
@@ -99,14 +197,47 @@ workflows:
99
197
  version: 2
100
198
  on-commit:
101
199
  jobs:
102
- - ruby-2.6.1-rails-5.2:
200
+ - release:
201
+ context: org-global
202
+ requires:
203
+ - ruby-3.0.3-rails-7.0
204
+ - ruby-2.7.5-rails-7.0
205
+ - ruby-3.0.3-rails-6.1
206
+ - ruby-2.7.5-rails-6.1
207
+ filters:
208
+ tags:
209
+ only: /^[0-9]+\.[0-9]+\.[0-9]+(\.?(RC|rc)[-\.]?\w*)?$/
210
+ branches:
211
+ ignore: /.*/
212
+ - generate-and-push-docs:
213
+ context: org-global
214
+ requires:
215
+ - release
216
+ filters:
217
+ tags:
218
+ only: /^[0-9]+\.[0-9]+\.[0-9]+(\.?(RC|rc)[-\.]?\w*)?$/
219
+ branches:
220
+ ignore: /.*/
221
+ - ruby-3.0.3-rails-7.0:
103
222
  context: org-global
104
- - ruby-2.5.3-rails-5.2:
223
+ filters:
224
+ tags:
225
+ only: &1 /.*/
226
+ - ruby-2.7.5-rails-7.0:
105
227
  context: org-global
106
- - ruby-2.6.1-rails-5.1:
228
+ filters:
229
+ tags:
230
+ only: *1
231
+ - ruby-3.0.3-rails-6.1:
107
232
  context: org-global
108
- - ruby-2.5.3-rails-5.1:
233
+ filters:
234
+ tags:
235
+ only: *1
236
+ - ruby-2.7.5-rails-6.1:
109
237
  context: org-global
238
+ filters:
239
+ tags:
240
+ only: *1
110
241
  scheduled:
111
242
  triggers:
112
243
  - schedule:
@@ -114,13 +245,13 @@ workflows:
114
245
  filters:
115
246
  branches:
116
247
  only:
117
- - master
248
+ - main
118
249
  jobs:
119
- - ruby-2.6.1-rails-5.2:
250
+ - ruby-3.0.3-rails-7.0:
120
251
  context: org-global
121
- - ruby-2.5.3-rails-5.2:
252
+ - ruby-2.7.5-rails-7.0:
122
253
  context: org-global
123
- - ruby-2.6.1-rails-5.1:
254
+ - ruby-3.0.3-rails-6.1:
124
255
  context: org-global
125
- - ruby-2.5.3-rails-5.1:
256
+ - ruby-2.7.5-rails-6.1:
126
257
  context: org-global
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.5.1
1
+ ruby-2.7.3
data/CODEOWNERS ADDED
@@ -0,0 +1 @@
1
+ * @stitchfix/eng-messaging
data/Gemfile.rails-6.1 ADDED
@@ -0,0 +1,7 @@
1
+ # DO NOT MODIFY - this is managed by Git Reduce in goro
2
+ #
3
+ source 'https://stitchfix01.jfrog.io/stitchfix01/api/gems/eng-gems/'
4
+
5
+ gemspec
6
+
7
+ gem 'activesupport', '~> 6.1.0'
data/Gemfile.rails-7.0 ADDED
@@ -0,0 +1,7 @@
1
+ # DO NOT MODIFY - this is managed by Git Reduce in goro
2
+ #
3
+ source 'https://stitchfix01.jfrog.io/stitchfix01/api/gems/eng-gems/'
4
+
5
+ gemspec
6
+
7
+ gem 'activesupport', '~> 7.0.0'
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,7 +176,12 @@ 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`.
179
+ Regardless of which processor you use, the name of the queue created is `pwwka_send_message_async`. You will need to start a worker process to work the queue. For a `Procfile` setup, with Resque as the processor, that could look something like this:
180
+
181
+ ```ruby
182
+ pwwka_send_message_async_worker: rake resque:work QUEUE=pwwka_send_message_async
183
+ ```
184
+
180
185
 
181
186
  You can also configure Pwwka to use your own custom job using the `async_job_klass` configuration option. An example might be:
182
187
  ```
@@ -191,7 +196,7 @@ If you are using Resque and `Resque::Plugins::ExponentialBackoff` is available,
191
196
 
192
197
  #### Message Queuer
193
198
 
194
- You can queue up messages and send them in a batch. This is most useful when multiple messages
199
+ You can queue up messages and send them in a batch. This is most useful when multiple messages
195
200
  need to sent from within a transaction block.
196
201
 
197
202
  For example:
@@ -255,7 +260,7 @@ Here is an example:
255
260
 
256
261
  ```ruby
257
262
  class ClientIndexMessageHandler
258
-
263
+
259
264
  def self.handle!(delivery_info, properties, payload)
260
265
  handler.do_a_thing(payload)
261
266
  end
@@ -430,7 +435,7 @@ If you use [Resque][resque], and you wish to handle messages in a resque job, yo
430
435
 
431
436
  Note that you must provide `@queue` in your job. `QueueResqueJobHandler` doesn't support setting a custom queue at enqueue-time (PRs welcome :).
432
437
 
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.
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 exactly 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.
434
439
 
435
440
  3. Profit!
436
441
 
@@ -454,9 +459,9 @@ describe "my integration test" do
454
459
  @test_handler.test_setup
455
460
  end
456
461
 
457
- after(:all) do
462
+ after(:all) do
458
463
  # this clears out any messages, so you have a clean test environment next time
459
- @test_handler.test_teardown
464
+ @test_handler.test_teardown
460
465
  end
461
466
 
462
467
  it "uses the message bus" do
@@ -527,6 +532,12 @@ Pwwka.configuration.payload_logging = :error # Only log payloads for ERROR or FA
527
532
  Pwwka.configuration.payload_logging = :fatal # Only log payloads for FATAL messages
528
533
  ```
529
534
 
535
+ You can also hook into logging by passing a hash containing keys of strings to match and corresponding `Proc` objects for the logger to execute instead of logging a message. The `Proc` will be called with the original message string that was to be logged and the params specific for that log event. So, if for instance, you wanted to emit a count metric to your monitoring system instead of logging each processed message you could set the configuration:
536
+
537
+ ```ruby
538
+ Pwwka.configuration.log_hooks = { 'Processed Message on' => ->(message, params){ $stats.count('message_processed') } }
539
+ ```
540
+
530
541
  #### Manual monitoring
531
542
 
532
543
  RabbitMQ has a web interface for checking out the health of connections, channels, exchanges and queues. Your RabbitMQ provider should
@@ -10,6 +10,7 @@ module Pwwka
10
10
  attr_accessor :delayed_exchange_name
11
11
  attr_accessor :logger
12
12
  attr_accessor :log_level
13
+ attr_accessor :log_hooks
13
14
  attr_accessor :options
14
15
  attr_accessor :background_job_processor
15
16
  attr_accessor :send_message_resque_backoff_strategy
@@ -26,6 +27,7 @@ module Pwwka
26
27
  @delayed_exchange_name = "pwwka.delayed.#{Pwwka.environment}"
27
28
  @logger = MonoLogger.new(STDOUT)
28
29
  @log_level = :info
30
+ @log_hooks = {}
29
31
  @options = {}
30
32
  @send_message_resque_backoff_strategy = [5, #intermittent glitch?
31
33
  60, # quick interruption
@@ -45,10 +47,12 @@ module Pwwka
45
47
  def app_id
46
48
  if @app_id.to_s.strip == ""
47
49
  if defined?(Rails)
48
- if Rails.respond_to?(:application)
49
- Rails.application.class.parent.name
50
+ if Rails.respond_to?(:application) && Rails.respond_to?(:version)
51
+ app_klass = Rails.application.class
52
+ app_parent = app_klass.module_parent
53
+ app_parent.name
50
54
  else
51
- raise "'Rails' is defined, but it doesn't respond to #application, so could not derive the app_id; you must explicitly set it"
55
+ raise "'Rails' is defined, but it doesn't respond to #application or #version, so could not derive the app_id; you must explicitly set it"
52
56
  end
53
57
  else
54
58
  raise "Could not derive the app_id; you must explicitly set it"
data/lib/pwwka/logging.rb CHANGED
@@ -22,7 +22,10 @@ module Pwwka
22
22
  params[:payload] = "[omitted]" if params[:payload]
23
23
  end
24
24
  message = format % params
25
- logger.send(level,message)
25
+
26
+ if Pwwka.configuration.log_hooks.select { |key, _value| message.match key }.each { |_key, value| value.call(message, params) }.empty?
27
+ logger.send(level,message)
28
+ end
26
29
  end
27
30
  end
28
31
  end
@@ -23,13 +23,20 @@ module Pwwka
23
23
 
24
24
  DEFAULT_DELAY_BY_MS = 5000
25
25
 
26
+ attr_reader :caller_manages_connector
26
27
  attr_reader :channel_connector
27
28
 
28
- def initialize
29
- @channel_connector = ChannelConnector.new(connection_name: "p: #{Pwwka.configuration.app_id} #{Pwwka.configuration.process_name}".strip)
29
+ def initialize(channel_connector: nil)
30
+ if channel_connector
31
+ @caller_manages_connector = true
32
+ @channel_connector = channel_connector
33
+ else
34
+ @caller_manages_connector = false
35
+ @channel_connector = ChannelConnector.new(connection_name: "p: #{Pwwka.configuration.app_id} #{Pwwka.configuration.process_name}".strip)
36
+ end
30
37
  end
31
38
 
32
- # Send an important message that must go through. This method allows any raised exception
39
+ # Send an important message that must go through. This method allows any raised exception
33
40
  # to pass through.
34
41
  #
35
42
  # payload:: Hash of what you'd like to include in your message
@@ -54,11 +61,13 @@ module Pwwka
54
61
  delay_by: nil,
55
62
  type: nil,
56
63
  message_id: :auto_generate,
57
- headers: nil)
64
+ headers: nil,
65
+ channel_connector: nil
66
+ )
58
67
  if delayed
59
- new.send_delayed_message!(*[payload, routing_key, delay_by].compact, type: type, headers: headers, message_id: message_id)
68
+ new(channel_connector: channel_connector).send_delayed_message!(*[payload, routing_key, delay_by].compact, type: type, headers: headers, message_id: message_id)
60
69
  else
61
- new.send_message!(payload, routing_key, type: type, headers: headers, message_id: message_id)
70
+ new(channel_connector: channel_connector).send_message!(payload, routing_key, type: type, headers: headers, message_id: message_id)
62
71
  end
63
72
  logf "AFTER Transmitting Message on %{routing_key} -> %{payload}",routing_key: routing_key, payload: payload
64
73
  true
@@ -95,11 +104,24 @@ module Pwwka
95
104
  job = Pwwka.configuration.async_job_klass
96
105
 
97
106
  if background_job_processor == :resque
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)
107
+ resque_args = [job, payload, routing_key]
108
+
109
+ unless type == nil && message_id == :auto_generate && headers == nil
110
+ # NOTE: (jdlubrano)
111
+ # Why can't we pass these options all of the time? Well, if a user
112
+ # of pwwka has configured their own async_job_klass that only has an
113
+ # arity of 2 (i.e. payload and routing key), then passing these options
114
+ # as an additional argument would break the user's application. In
115
+ # order to maintain compatibility with preceding versions of Pwwka,
116
+ # we need to ensure that the same arguments passed into this method
117
+ # result in compatible calls to enqueue any Resque jobs.
118
+ resque_args << { type: type, message_id: message_id, headers: headers }
119
+ end
120
+
121
+ if delay_by_ms.zero?
122
+ Resque.enqueue(*resque_args)
101
123
  else
102
- Resque.enqueue_in(delay_by_ms/1000, job, payload, routing_key, type: type, message_id: message_id, headers: headers)
124
+ Resque.enqueue_in(delay_by_ms/1000, *resque_args)
103
125
  end
104
126
  elsif background_job_processor == :sidekiq
105
127
  options = { delay_by_ms: delay_by_ms, type: type, message_id: message_id, headers: headers }
@@ -134,7 +156,9 @@ module Pwwka
134
156
  logf "END Transmitting Message on id[%{id}] %{routing_key} -> %{payload}", id: publish_options.message_id, routing_key: routing_key, payload: payload
135
157
  true
136
158
  ensure
137
- channel_connector.connection_close
159
+ unless caller_manages_connector
160
+ channel_connector.connection_close
161
+ end
138
162
  end
139
163
 
140
164
 
@@ -154,7 +178,9 @@ module Pwwka
154
178
  logf "END Transmitting Delayed Message on id[%{id}] %{routing_key} -> %{payload}", id: publish_options.message_id, routing_key: routing_key, payload: payload
155
179
  true
156
180
  ensure
157
- channel_connector.connection_close
181
+ unless caller_manages_connector
182
+ channel_connector.connection_close
183
+ end
158
184
  end
159
185
 
160
186
  end
data/lib/pwwka/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Pwwka
2
- VERSION = '0.23.RC1'
2
+ VERSION = '1.0.0.RC1'
3
3
  end
4
4
 
data/lib/pwwka.rb CHANGED
@@ -27,7 +27,6 @@ require 'pwwka/channel_connector'
27
27
  require 'pwwka/handling'
28
28
  require 'pwwka/receiver'
29
29
  require 'pwwka/transmitter'
30
- require 'pwwka/persistent_transmitter'
31
30
  require 'pwwka/message_queuer'
32
31
  require 'pwwka/error_handlers'
33
32
  require 'pwwka/configuration'
data/owners.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "owners": [
3
3
  {
4
- "team": "platform"
4
+ "team": "messaging"
5
5
  }
6
6
  ]
7
7
  }
data/pwwka.gemspec CHANGED
@@ -20,13 +20,13 @@ Gem::Specification.new do |s|
20
20
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
21
  s.require_paths = ["lib"]
22
22
  s.add_runtime_dependency("bunny")
23
- s.add_runtime_dependency("activesupport")
23
+ s.add_runtime_dependency("activesupport", ">= 6.0.0")
24
24
  s.add_runtime_dependency("activemodel")
25
25
  s.add_runtime_dependency("mono_logger")
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", "~> 1.5.3")
30
30
  s.add_development_dependency("sidekiq")
31
31
  s.add_development_dependency("simplecov")
32
32
  s.add_development_dependency("resqutils")
@@ -2,6 +2,7 @@ require 'spec_helper.rb'
2
2
  require 'resqutils/spec/resque_helpers'
3
3
  require 'resqutils/spec/resque_matchers'
4
4
  require 'pwwka/queue_resque_job_handler'
5
+ require 'active_support/time'
5
6
 
6
7
  require_relative "support/integration_test_setup"
7
8
  require_relative "support/logging_receiver"
@@ -11,6 +12,9 @@ describe "sending and receiving messages", :integration do
11
12
  include IntegrationTestHelpers
12
13
  include Resqutils::Spec::ResqueHelpers
13
14
 
15
+ let(:async_resque_queue) { 'pwwka_send_message_async' }
16
+ let(:delayed_resque_queue) { :delayed }
17
+
14
18
  before do
15
19
  ENV["JOB_KLASS"] = MyTestJob.name
16
20
  ENV["PWWKA_QUEUE_EXTENDED_INFO"] = "true"
@@ -30,7 +34,8 @@ describe "sending and receiving messages", :integration do
30
34
  FooReceiver.reset!
31
35
  MultiRoutingReceived.reset!
32
36
  OtherFooReceiver.reset!
33
- clear_queue(:delayed)
37
+ clear_queue(async_resque_queue)
38
+ clear_queue(delayed_resque_queue)
34
39
  clear_queue(MyTestJob)
35
40
  end
36
41
 
@@ -144,7 +149,7 @@ describe "sending and receiving messages", :integration do
144
149
 
145
150
  expect(AllReceiver.messages_received.size).to eq(0)
146
151
 
147
- process_resque_job(Pwwka::SendMessageAsyncJob,:delayed)
152
+ process_resque_job(Pwwka::SendMessageAsyncJob, async_resque_queue)
148
153
 
149
154
  allow_receivers_to_process_queues
150
155
 
@@ -166,7 +171,7 @@ describe "sending and receiving messages", :integration do
166
171
 
167
172
  expect(AllReceiver.messages_received.size).to eq(0)
168
173
 
169
- process_resque_job(Pwwka::SendMessageAsyncJob,:delayed)
174
+ process_resque_job(Pwwka::SendMessageAsyncJob, async_resque_queue)
170
175
 
171
176
  allow_receivers_to_process_queues
172
177
 
@@ -186,12 +191,28 @@ describe "sending and receiving messages", :integration do
186
191
 
187
192
  allow(Pwwka).to receive(:configuration).and_return(configuration)
188
193
 
189
- allow(Resque).to receive(:enqueue_in)
194
+ allow(Resque).to receive(:enqueue)
190
195
 
191
196
  Pwwka::Transmitter.send_message_async({ sample: "payload", has: { deeply: true, nested: 4 }},
192
197
  "pwwka.testing.bar")
193
198
 
194
- expect(Resque).to have_received(:enqueue_in).with(anything, async_job_klass, anything, anything)
199
+ expect(Resque).to have_received(:enqueue).with(async_job_klass, anything, anything)
200
+ end
201
+
202
+ it "can queue a job to send a message with a delay" do
203
+ Pwwka::Transmitter.send_message_async({ sample: "payload" },
204
+ "pwwka.testing.bar",
205
+ delay_by_ms: 1_000)
206
+
207
+ allow_receivers_to_process_queues # not expecting anything to be processed
208
+
209
+ expect(AllReceiver.messages_received.size).to eq(0)
210
+
211
+ process_resque_job(Pwwka::SendMessageAsyncJob, delayed_resque_queue)
212
+
213
+ allow_receivers_to_process_queues
214
+
215
+ expect(AllReceiver.messages_received.size).to eq(1)
195
216
  end
196
217
  end
197
218
 
data/spec/spec_helper.rb CHANGED
@@ -11,7 +11,12 @@ end
11
11
 
12
12
  require 'pwwka'
13
13
  require 'pwwka/test_handler'
14
- require 'active_support/core_ext/hash'
14
+ begin
15
+ require 'active_support/core_ext/hash'
16
+ rescue NameError
17
+ require "active_support/isolated_execution_state"
18
+ require 'active_support/core_ext/hash'
19
+ end
15
20
 
16
21
  # These are required in pwwka proper, but they are guarded to not cause
17
22
  # an error if missing. Requiring here so their absence will fail the tests
@@ -26,7 +31,7 @@ test_configuration = TestConfiguration.new(File.join(GEM_ROOT,"docker-compose.ym
26
31
  RSpec.configure do |config|
27
32
 
28
33
  config.expect_with :rspec do |c|
29
- c.syntax = [:should,:expect] # should is needed to make a resque helper
34
+ c.syntax = [:should,:expect] # should is needed to make a resque helper
30
35
  # from resqutils work
31
36
  end
32
37
 
@@ -75,6 +75,14 @@ describe Pwwka::Configuration do
75
75
  def self.application
76
76
  MyAmazingApp::Application.new
77
77
  end
78
+
79
+ def self.version
80
+ active_support_dependency = Bundler.locked_gems.dependencies.detect do |name, dep|
81
+ name == "activesupport"
82
+ end.last
83
+ version_specification = active_support_dependency.requirement.to_s
84
+ version_specification[/\d.+/]
85
+ end
78
86
  end
79
87
  Object.const_set("Rails",rails)
80
88
  end
@@ -97,7 +105,7 @@ describe Pwwka::Configuration do
97
105
  it "blows up when not set" do
98
106
  expect {
99
107
  configuration.app_id
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/)
108
+ }.to raise_error(/'Rails' is defined, but it doesn't respond to #application or #version, so could not derive the app_id; you must explicitly set it/)
101
109
  end
102
110
  end
103
111
  end
@@ -93,6 +93,44 @@ describe Pwwka::Logging do
93
93
  expect(logger).to have_received(:error).with("This is also the payload: [omitted]")
94
94
  end
95
95
  end
96
+
97
+ context "log_hook matching" do
98
+ def test_func(message, params)
99
+ end
100
+
101
+ before do
102
+ Pwwka.configuration.log_hooks = { "test message" => ->(message, params){ test_func(message, params) } }
103
+ end
104
+
105
+ after do
106
+ Pwwka.configuration.log_hooks = {}
107
+ end
108
+
109
+ context "message matches hook" do
110
+ it "overrides logging" do
111
+ ForLogging.logf("test message", {})
112
+
113
+ expect(logger).not_to have_received(:info)
114
+ end
115
+
116
+ it "calls the hook" do
117
+ allow(self).to receive(:test_func)
118
+ test_params = { param: :test }
119
+
120
+ ForLogging.logf("test message", test_params)
121
+
122
+ expect(self).to have_received(:test_func).with("test message", test_params)
123
+ end
124
+ end
125
+
126
+ context "message doesn't match hook" do
127
+ it "logs as normal" do
128
+ ForLogging.logf("other message", {})
129
+
130
+ expect(logger).to have_received(:info).with("other message")
131
+ end
132
+ end
133
+ end
96
134
  end
97
135
 
98
136
  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(:enqueue_in)
315
+ allow(Resque).to receive(:enqueue)
316
316
  described_class.send_message!(payload,routing_key, on_error: :resque)
317
- expect(Resque).to have_received(:enqueue_in).with(0,Pwwka::SendMessageAsyncJob,payload,routing_key)
317
+ expect(Resque).to have_received(:enqueue).with(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(:enqueue_in).and_raise("NOPE")
321
+ allow(Resque).to receive(:enqueue).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(:enqueue_in).and_raise("NOPE")
327
+ allow(Resque).to receive(:enqueue).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(:enqueue_in)
341
+ allow(Resque).to receive(:enqueue)
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(:enqueue_in).with(0, Pwwka::SendMessageAsyncJob, payload, routing_key)
346
+ expect(Resque).to have_received(:enqueue).with(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(:enqueue_in).and_raise("NOPE")
352
+ allow(Resque).to receive(:enqueue).and_raise("NOPE")
353
353
  end
354
354
 
355
355
  it "raises the original exception job" do
@@ -576,5 +576,41 @@ describe Pwwka::Transmitter do
576
576
  end
577
577
  end
578
578
  end
579
- end
580
579
 
580
+ context "application manages connection" do
581
+ let(:managed_connector) { instance_double(Pwwka::ChannelConnector,
582
+ topic_exchange: double(:topic_exchange).as_null_object,
583
+ delayed_exchange: double(:delayed_exchange).as_null_object
584
+ ).as_null_object }
585
+ describe ".send_message!" do
586
+
587
+ context "send immediate" do
588
+ it "doesn't open a new connection" do
589
+ described_class.send_message!(payload, routing_key, delayed: false, channel_connector: managed_connector)
590
+
591
+ expect(Pwwka::ChannelConnector).not_to have_received(:new)
592
+ end
593
+
594
+ it "doesn't close a passed in connection" do
595
+ described_class.send_message!(payload, routing_key, delayed: false, channel_connector: managed_connector)
596
+
597
+ expect(managed_connector).not_to have_received(:connection_close)
598
+ end
599
+ end
600
+
601
+ context "send delayed" do
602
+ it "doesn't open a new connection" do
603
+ described_class.send_message!(payload, routing_key, delayed: true, channel_connector: managed_connector)
604
+
605
+ expect(Pwwka::ChannelConnector).not_to have_received(:new)
606
+ end
607
+
608
+ it "doesn't close a passed in connection" do
609
+ described_class.send_message!(payload, routing_key, delayed: true, channel_connector: managed_connector)
610
+
611
+ expect(managed_connector).not_to have_received(:connection_close)
612
+ end
613
+ end
614
+ end
615
+ end
616
+ end
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.23.RC1
4
+ version: 1.0.0.RC1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stitch Fix Engineering
@@ -12,10 +12,10 @@ authors:
12
12
  - Jonathan Dean
13
13
  - Nick Reavill
14
14
  - Simeon Willbanks
15
- autorequire:
15
+ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
- date: 2019-04-25 00:00:00.000000000 Z
18
+ date: 2022-01-27 00:00:00.000000000 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: bunny
@@ -37,14 +37,14 @@ dependencies:
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: 6.0.0
41
41
  type: :runtime
42
42
  prerelease: false
43
43
  version_requirements: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: 6.0.0
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: activemodel
50
50
  requirement: !ruby/object:Gem::Requirement
@@ -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: '0'
124
+ version: 1.5.3
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: '0'
131
+ version: 1.5.3
132
132
  - !ruby/object:Gem::Dependency
133
133
  name: sidekiq
134
134
  requirement: !ruby/object:Gem::Requirement
@@ -235,13 +235,12 @@ files:
235
235
  - ".ruby-gemset"
236
236
  - ".ruby-version"
237
237
  - ".travis.yml"
238
+ - CODEOWNERS
238
239
  - CODE_OF_CONDUCT.md
239
240
  - CONTRIBUTING.md
240
241
  - Gemfile
241
- - Gemfile.rails-4.2
242
- - Gemfile.rails-5.0
243
- - Gemfile.rails-5.1
244
- - Gemfile.rails-5.2
242
+ - Gemfile.rails-6.1
243
+ - Gemfile.rails-7.0
245
244
  - LICENSE
246
245
  - README.md
247
246
  - Rakefile
@@ -263,7 +262,6 @@ files:
263
262
  - lib/pwwka/handling.rb
264
263
  - lib/pwwka/logging.rb
265
264
  - lib/pwwka/message_queuer.rb
266
- - lib/pwwka/persistent_transmitter.rb
267
265
  - lib/pwwka/publish_options.rb
268
266
  - lib/pwwka/queue_resque_job_handler.rb
269
267
  - lib/pwwka/receiver.rb
@@ -293,7 +291,6 @@ files:
293
291
  - spec/unit/configuration_spec.rb
294
292
  - spec/unit/logging_spec.rb
295
293
  - spec/unit/message_queuer_spec.rb
296
- - spec/unit/persistent_transmitter_spec.rb
297
294
  - spec/unit/queue_resque_job_handler_spec.rb
298
295
  - spec/unit/receiver_spec.rb
299
296
  - spec/unit/send_message_async_job_spec.rb
@@ -304,7 +301,7 @@ homepage: https://github.com/stitchfix/pwwka
304
301
  licenses:
305
302
  - MIT
306
303
  metadata: {}
307
- post_install_message:
304
+ post_install_message:
308
305
  rdoc_options: []
309
306
  require_paths:
310
307
  - lib
@@ -319,9 +316,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
319
316
  - !ruby/object:Gem::Version
320
317
  version: 1.3.1
321
318
  requirements: []
322
- rubyforge_project:
323
- rubygems_version: 2.7.6
324
- signing_key:
319
+ rubygems_version: 3.1.6
320
+ signing_key:
325
321
  specification_version: 4
326
322
  summary: Send and receive messages via RabbitMQ
327
323
  test_files:
@@ -343,7 +339,6 @@ test_files:
343
339
  - spec/unit/configuration_spec.rb
344
340
  - spec/unit/logging_spec.rb
345
341
  - spec/unit/message_queuer_spec.rb
346
- - spec/unit/persistent_transmitter_spec.rb
347
342
  - spec/unit/queue_resque_job_handler_spec.rb
348
343
  - spec/unit/receiver_spec.rb
349
344
  - spec/unit/send_message_async_job_spec.rb
data/Gemfile.rails-4.2 DELETED
@@ -1,8 +0,0 @@
1
- # DO NOT MODIFY - this is managed by Git Reduce in goro
2
- #
3
- source 'https://gem.fury.io/me/'
4
- source 'https://www.rubygems.org'
5
-
6
- gemspec
7
-
8
- gem 'activesupport', '~> 4.2.0'
data/Gemfile.rails-5.0 DELETED
@@ -1,8 +0,0 @@
1
- # DO NOT MODIFY - this is managed by Git Reduce in goro
2
- #
3
- source 'https://gem.fury.io/me/'
4
- source 'https://www.rubygems.org'
5
-
6
- gemspec
7
-
8
- gem 'activesupport', '~> 5.0.0'
data/Gemfile.rails-5.1 DELETED
@@ -1,8 +0,0 @@
1
- # DO NOT MODIFY - this is managed by Git Reduce in goro
2
- #
3
- source 'https://gem.fury.io/me/'
4
- source 'https://www.rubygems.org'
5
-
6
- gemspec
7
-
8
- gem 'activesupport', '~> 5.1.0'
data/Gemfile.rails-5.2 DELETED
@@ -1,8 +0,0 @@
1
- # DO NOT MODIFY - this is managed by Git Reduce in goro
2
- #
3
- source 'https://gem.fury.io/me/'
4
- source 'https://www.rubygems.org'
5
-
6
- gemspec
7
-
8
- gem 'activesupport', '~> 5.2.0'
@@ -1,59 +0,0 @@
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
@@ -1,153 +0,0 @@
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