queue_classic_plus 4.0.0.alpha18 → 4.0.0.alpha19

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: f4194444b2e3b6bc8d08ebfe7393e9efa53bc31fdb8c7e79c5b1a6aff31e8776
4
- data.tar.gz: a12f2b01acea5e2fb4fc6e6b257c6aafc228ff38f73280a3deb974452f2e7220
3
+ metadata.gz: 4ded39f47849c6dacb9e4efe8bc535bf9fae56cf15cc366cdde177e12176ae37
4
+ data.tar.gz: 228a9d4ed7b5a4541e1d93e9887c3f3ec9193e9464c9766817ffd1690530d864
5
5
  SHA512:
6
- metadata.gz: 42399e627f40795df59f4235e6d616527506758af7a988c2e7e923ce3fbad2bac49b188563ad508d66e95f9935149eaafd1928d6eac6c97bfeb9f1a437fffabe
7
- data.tar.gz: b08d05305a8772d2aacf0e5984b5d2254f3b1f83cb8e6d4d02b7f1bb3d929d70e3ddd02b1130f9845ebec3d9ef409d7a86d63f44ff04ea3fb998dd0cab2080a0
6
+ metadata.gz: 447ed6984427a1649f76ed733c2eafcf6324a5591265cd3f3ec9d29ca8f09552c2a93134b3a481ab06fd1d64b1f78db405fd4ade10e1b372eb62b6e8cbdfe364
7
+ data.tar.gz: c4b1823ae678c44d3d0892ff2bb44dc6ec844339717e1a8e0ce62ff564aee690e3f5d19c9ab254c6538ce2e3e4466c1789bc5b50beba787e49a8af22d60f892f
data/README.md CHANGED
@@ -124,6 +124,59 @@ class Jobs::NoTransaction < QueueClassicPlus::Base
124
124
  end
125
125
  ```
126
126
 
127
+
128
+ #### Callbacks
129
+
130
+ Jobs support the following callbacks:
131
+ ```
132
+ before_enqueue
133
+ after_enqueue
134
+ before_perform
135
+ after_perform
136
+ ```
137
+
138
+ - `enqueue` callbacks are called when the job is initially enqueued. Caveats:
139
+ - not called on retries
140
+ - not called when scheduled in the future (i.e. `Job.enqueue_perform_in`)
141
+ - still called if enqueuing fails because a job with `lock!` is already enqueued.
142
+ - `perform` callbacks are called any time the job is picked up and run by a worker, including retries and jobs scheduled in the future.
143
+
144
+ Callbacks can either be implemented by providing a method to be called:
145
+
146
+ ```ruby
147
+ class Jobs::WithCallbackMethods < QueueClassicPlus::Base
148
+ before_enqueue :before_enqueue_method
149
+
150
+ @queue = :low
151
+
152
+ def self.before_enqueue_method(*args)
153
+ # ...
154
+ end
155
+
156
+ def self.perform(user_id)
157
+ # ...
158
+ end
159
+ end
160
+ ```
161
+
162
+ or by providing a block:
163
+
164
+ ```ruby
165
+ class Jobs::WithCallbackBlocks < QueueClassicPlus::Base
166
+ before_enqueue do |*args|
167
+ # ...
168
+ end
169
+
170
+ @queue = :low
171
+
172
+ def self.perform(user_id)
173
+ # ...
174
+ end
175
+ end
176
+ ```
177
+
178
+ The `args` passed to the callback method/block will be the same as the arguments passed to `QueueClassicPlus::Base.do` and `QueueClassicPlus::Base.perform`.
179
+
127
180
  ## Advanced configuration
128
181
 
129
182
  If you want to log exceptions in your favorite exception tracker. You can configured it like so:
@@ -136,6 +136,22 @@ module QueueClassicPlus
136
136
  end
137
137
  end
138
138
 
139
+ def self.before_enqueue(callback_method = nil, &block)
140
+ define_callback(:enqueue, :before, callback_method, &block)
141
+ end
142
+
143
+ def self.after_enqueue(callback_method = nil, &block)
144
+ define_callback(:enqueue, :after, callback_method, &block)
145
+ end
146
+
147
+ def self.before_perform(callback_method = nil, &block)
148
+ define_callback(:perform, :before, callback_method, &block)
149
+ end
150
+
151
+ def self.after_perform(callback_method = nil, &block)
152
+ define_callback(:perform, :after, callback_method, &block)
153
+ end
154
+
139
155
  # Debugging
140
156
  def self.list
141
157
  q = "SELECT * FROM queue_classic_jobs WHERE q_name = '#{@queue}'"
@@ -165,5 +181,26 @@ module QueueClassicPlus
165
181
  def self.execute(sql, *args)
166
182
  QC.default_conn_adapter.execute(sql, *args)
167
183
  end
184
+
185
+ def self.define_callback(name, type, callback_method, &_block)
186
+ singleton_class.prepend(
187
+ Module.new do |callback_module|
188
+ callback_module.define_method(name) do |*args|
189
+ callback_args = args
190
+ if name == :enqueue
191
+ callback_args = callback_args.drop(1) # Class/method is the first argument. Callbacks don't need that.
192
+ end
193
+
194
+ if type == :before
195
+ block_given? ? yield(*callback_args) : send(callback_method, *callback_args)
196
+ end
197
+ super(*args)
198
+ if type == :after
199
+ block_given? ? yield(*callback_args) : send(callback_method, *callback_args)
200
+ end
201
+ end
202
+ end
203
+ )
204
+ end
168
205
  end
169
206
  end
@@ -1,3 +1,3 @@
1
1
  module QueueClassicPlus
2
- VERSION = '4.0.0.alpha18'.freeze
2
+ VERSION = '4.0.0.alpha19'.freeze
3
3
  end
data/spec/base_spec.rb CHANGED
@@ -184,6 +184,172 @@ describe QueueClassicPlus::Base do
184
184
  subject._perform(42, true)
185
185
  end
186
186
  end
187
+
188
+ context "with callbacks defined" do
189
+ subject do
190
+ Class.new(QueueClassicPlus::Base) do
191
+ @queue = :test
192
+
193
+ before_enqueue :before_enqueue_method
194
+ after_enqueue :after_enqueue_method
195
+
196
+ before_perform :before_perform_method
197
+ after_perform :after_perform_method
198
+
199
+ def self.before_enqueue_method(*_args); end;
200
+ def self.after_enqueue_method(*_args); end;
201
+ def self.before_perform_method(*_args); end;
202
+ def self.after_perform_method(*_args); end;
203
+
204
+ def self.perform(*_args); end;
205
+ end
206
+ end
207
+
208
+ it "passes enqueue arguments to callbacks" do
209
+ expect(subject).to receive(:before_enqueue_method).with("enqueue_argument").once
210
+ expect(subject).to receive(:after_enqueue_method).with("enqueue_argument").once
211
+
212
+ subject.do("enqueue_argument")
213
+ end
214
+
215
+ it "passes perform arguments to callbacks" do
216
+ expect(subject).to receive(:before_perform_method).with("perform_argument").once
217
+ expect(subject).to receive(:after_perform_method).with("perform_argument").once
218
+
219
+ subject.perform("perform_argument")
220
+ end
221
+
222
+ context "when enqueued" do
223
+ it "calls the enqueue callback methods" do
224
+ expect(subject).to receive(:before_enqueue_method).once
225
+ expect(subject).to receive(:after_enqueue_method).once
226
+
227
+ subject.do
228
+ end
229
+
230
+ it "does not call the perform callbacks" do
231
+ expect(subject).to_not receive(:before_perform_method)
232
+ expect(subject).to_not receive(:after_perform_method)
233
+
234
+ subject.do
235
+ end
236
+ end
237
+
238
+ context "when perform" do
239
+ it "calls the perform callback methods" do
240
+ expect(subject).to receive(:before_perform_method).once
241
+ expect(subject).to receive(:after_perform_method).once
242
+
243
+ subject.perform
244
+ end
245
+
246
+ it "does not call the enqueue callbacks" do
247
+ expect(subject).to_not receive(:before_enqueue_method)
248
+ expect(subject).to_not receive(:after_enqueue_method)
249
+
250
+ subject.perform
251
+ end
252
+
253
+ context "when perform fails" do
254
+ subject do
255
+ Class.new(QueueClassicPlus::Base) do
256
+ @queue = :test
257
+
258
+ before_perform :before_perform_method
259
+ after_perform :after_perform_method
260
+
261
+ def self.before_perform_method(*_args); end;
262
+ def self.after_perform_method(*_args); end;
263
+
264
+ def self.perform(*_args)
265
+ raise StandardError
266
+ end
267
+ end
268
+ end
269
+
270
+ it "does not call after callbacks" do
271
+ expect(subject).to receive(:before_perform_method).once
272
+ expect(subject).to_not receive(:after_perform_method)
273
+
274
+ begin
275
+ subject.perform
276
+ rescue StandardError
277
+ end
278
+ end
279
+ end
280
+ end
281
+
282
+ context "when callback defined multiple times" do
283
+ subject do
284
+ Class.new(QueueClassicPlus::Base) do
285
+ @queue = :test
286
+
287
+ before_enqueue :before_enqueue_method_1
288
+ before_enqueue :before_enqueue_method_2
289
+ before_enqueue :before_enqueue_method_3
290
+
291
+ def self.before_enqueue_method_1(*_args); end;
292
+ def self.before_enqueue_method_2(*_args); end;
293
+ def self.before_enqueue_method_3(*_args); end;
294
+
295
+ def self.perform(*_args); end;
296
+ end
297
+ end
298
+
299
+ it "calls each callback" do
300
+ expect(subject).to receive(:before_enqueue_method_1).once
301
+ expect(subject).to receive(:before_enqueue_method_2).once
302
+ expect(subject).to receive(:before_enqueue_method_3).once
303
+
304
+ subject.do
305
+ end
306
+ end
307
+ end
308
+
309
+ context "with callback blocks defined" do
310
+ subject do
311
+ Class.new(QueueClassicPlus::Base) do
312
+ @queue = :test
313
+ class_variable_set(:@@block_result, [])
314
+
315
+ before_enqueue do |*_args|
316
+ class_variable_get(:@@block_result).append("before_enqueue_block")
317
+ end
318
+ after_enqueue do |*_args|
319
+ class_variable_get(:@@block_result).append("after_enqueue_block")
320
+ end
321
+
322
+ before_perform do |*_args|
323
+ class_variable_get(:@@block_result).append("before_perform_block")
324
+ end
325
+ after_perform do |*_args|
326
+ class_variable_get(:@@block_result).append("after_perform_block")
327
+ end
328
+
329
+ def self.perform; end;
330
+ end
331
+ end
332
+
333
+ context "when enqueued" do
334
+ it "calls the enqueue callback blocks" do
335
+ subject.do
336
+
337
+ expect(subject.class_variable_get(:@@block_result)).to eq(
338
+ %w(before_enqueue_block after_enqueue_block)
339
+ )
340
+ end
341
+ end
342
+
343
+ context "when perform" do
344
+ it "calls the perform callback blocks" do
345
+ subject.perform
346
+
347
+ expect(subject.class_variable_get(:@@block_result)).to eq(
348
+ %w(before_perform_block after_perform_block)
349
+ )
350
+ end
351
+ end
352
+ end
187
353
  end
188
354
 
189
355
  describe ".librato_key" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: queue_classic_plus
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0.alpha18
4
+ version: 4.0.0.alpha19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Mathieu
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-09-06 00:00:00.000000000 Z
13
+ date: 2023-09-10 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: queue_classic