sidekiq-unique-jobs 7.0.0 → 7.0.5

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sidekiq-unique-jobs might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3a0ef0c8257f0c79b137bab502492428dcbd9060b44d1b1fa754e5c591ef9185
4
- data.tar.gz: '03380b590a1e077f429e2b9bce284716b6f6d891cf35a1eeb7c01e82b2b23782'
3
+ metadata.gz: 35af721bd8342dc7bbfcc204b12869ee3e78bb0c644db358c479d6ab2de5bba3
4
+ data.tar.gz: ca936a331cd5d2c591de1d74c000f4e62be908076d188dc7d2e8995965c69b5d
5
5
  SHA512:
6
- metadata.gz: b7c5881985fd2b2d96a2af3ad29e39e56a1df353b888e0a10720d4bee03cebeafee05e327b5fe54f809b0a1e567f0466e5754bee4e5e0179d14ce232a39a1e8b
7
- data.tar.gz: 4fa3667cb51c5b44791b10f3672dbebd5f3733adae80b512775629a29d3feed4e67c5df8ce20993fa89d4810a6ca9aef7c0922e1f03bd305e0421679316ba3f9
6
+ metadata.gz: 9dcc1eec857d0d66d5eee722a85b4312fd8736c901bf03d5df4529e2c661c58ee493e51910966627c00534268da6a5e5e48b88bc767fdb44b2109ac6be33173a
7
+ data.tar.gz: 5a01f57c898b29354b83729b120e9488846f364e69fd022ce7b29a6c23b35ad789046a1ab8c41c38c221a273cc15eff3e41cae75589468ab52b62207eb7de241
data/CHANGELOG.md CHANGED
@@ -1,5 +1,93 @@
1
1
  # Changelog
2
2
 
3
+ ## [v7.0.4](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v7.0.4) (2021-02-17)
4
+
5
+ [Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v7.0.3...v7.0.4)
6
+
7
+ **Fixed bugs:**
8
+
9
+ - Fix uninitialized scheduled task [\#577](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/577) ([ArturT](https://github.com/ArturT))
10
+
11
+ ## [v7.0.3](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v7.0.3) (2021-02-17)
12
+
13
+ [Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v7.0.2...v7.0.3)
14
+
15
+ **Fixed bugs:**
16
+
17
+ - Reduce reaper threads [\#576](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/576) ([mhenrixon](https://github.com/mhenrixon))
18
+
19
+ **Merged pull requests:**
20
+
21
+ - Fix typo in README.md \[ci skip\] [\#575](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/575) ([yujideveloper](https://github.com/yujideveloper))
22
+
23
+ ## [v7.0.2](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v7.0.2) (2021-02-08)
24
+
25
+ [Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v7.0.1...v7.0.2)
26
+
27
+ **Fixed bugs:**
28
+
29
+ - Lock not getting properly cleared for some jobs [\#560](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/560)
30
+ - while\_executing + raise let non-unique jobs to be executed [\#534](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/534)
31
+ - delete\_by\_digest does not work with the msg\['unique\_digest'\] value available in sidekiq\_retries\_exhausted [\#532](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/532)
32
+ - Multiple jobs running at the same time [\#531](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/531)
33
+ - Unable to setup in standalone Ruby project [\#523](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/523)
34
+ - v7.0.0.beta15 Can't push new jobs to queue [\#501](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/501)
35
+ - Reaper doesn't work - lua or ruby [\#498](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/498)
36
+ - Tasks run once, and then there is no launch [\#464](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/464)
37
+ - Jobs executing and immediately returning [\#418](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/418)
38
+ - until\_and\_while\_executing + sidekiq retry mechanism [\#395](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/395)
39
+ - Failed jobs waiting to be retried are not considered when fetching uniqueness [\#394](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/394)
40
+
41
+ **Closed issues:**
42
+
43
+ - Just some clarification on the documentation. [\#530](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/530)
44
+ - Unique Digests dashboard not filtering the full set of results [\#529](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/529)
45
+ - after\_unlock isn't called unless it's a class method [\#526](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/526)
46
+ - The job gets JID and goes to dead right away [\#522](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/522)
47
+ - Able to assign customise Redis setup [\#509](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/509)
48
+ - SidekiqUniqueJobs::UniqueArgs\#create\_digest is getting called twice [\#391](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/391)
49
+
50
+ **Merged pull requests:**
51
+
52
+ - Fix example url in documentation [\#572](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/572) ([yboulkaid](https://github.com/yboulkaid))
53
+
54
+ ## [v7.0.1](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v7.0.1) (2021-01-22)
55
+
56
+ [Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v7.0.0...v7.0.1)
57
+
58
+ **Implemented enhancements:**
59
+
60
+ - Any way to manually clear/reset the changelog history? [\#568](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/568)
61
+ - Present the entire changelog in its own view [\#569](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/569) ([mhenrixon](https://github.com/mhenrixon))
62
+
63
+ **Fixed bugs:**
64
+
65
+ - Fix configuration [\#570](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/570) ([mhenrixon](https://github.com/mhenrixon))
66
+
67
+ **Closed issues:**
68
+
69
+ - undefined method 'delete\_by\_digest' for SidekiqUniqueJobs::Digests:Class [\#567](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/567)
70
+ - Rejected jobs are still displayed as 'Queued' with gem 'sidekiq-status' on /sidekiq/statuses [\#564](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/564)
71
+
72
+ ## [v7.0.0](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v7.0.0) (2021-01-20)
73
+
74
+ [Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v7.0.0.beta29...v7.0.0)
75
+
76
+ **Implemented enhancements:**
77
+
78
+ - Give user full control over adding middleware [\#566](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/566) ([mhenrixon](https://github.com/mhenrixon))
79
+ - Fix coverage reporting and add coverage [\#565](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/565) ([mhenrixon](https://github.com/mhenrixon))
80
+
81
+ **Fixed bugs:**
82
+
83
+ - Race condition in ruby reaper [\#559](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/559)
84
+ - Fix until and while executed and improve documentation [\#397](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/397)
85
+ - Fix race condition to avoid reaping active jobs [\#563](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/563) ([mhenrixon](https://github.com/mhenrixon))
86
+
87
+ **Closed issues:**
88
+
89
+ - Is it possible to have a :until\_executed lock with an expiration time? [\#524](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/524)
90
+
3
91
  ## [v7.0.0.beta29](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v7.0.0.beta29) (2021-01-16)
4
92
 
5
93
  [Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v7.0.0.beta28...v7.0.0.beta29)
@@ -7,6 +95,7 @@
7
95
  **Fixed bugs:**
8
96
 
9
97
  - Ruby Reaper active check incorrect [\#557](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/557)
98
+ - Fix that :PRIMED keys are seemingly not removed [\#574](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/574) ([mhenrixon](https://github.com/mhenrixon))
10
99
  - Routes with authentication should work with web [\#562](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/562) ([mhenrixon](https://github.com/mhenrixon))
11
100
 
12
101
  **Closed issues:**
@@ -81,10 +170,6 @@
81
170
 
82
171
  - ConnectionPool::TimeoutError and :until\_executed [\#535](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/535)
83
172
 
84
- **Merged pull requests:**
85
-
86
- - Support apartment [\#540](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/540) ([mhenrixon](https://github.com/mhenrixon))
87
-
88
173
  ## [v7.0.0.beta24](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v7.0.0.beta24) (2020-09-27)
89
174
 
90
175
  [Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v7.0.0.beta23...v7.0.0.beta24)
@@ -240,10 +325,6 @@
240
325
 
241
326
  [Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v7.0.0.beta12...v7.0.0.beta13)
242
327
 
243
- **Fixed bugs:**
244
-
245
- - Remove digest deletion for concurrent locks [\#482](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/482) ([mhenrixon](https://github.com/mhenrixon))
246
-
247
328
  ## [v7.0.0.beta12](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v7.0.0.beta12) (2020-03-25)
248
329
 
249
330
  [Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.20...v7.0.0.beta12)
@@ -260,6 +341,7 @@
260
341
  **Fixed bugs:**
261
342
 
262
343
  - Deletion of digest doesn't work from admin UI [\#438](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/438)
344
+ - Remove digest deletion for concurrent locks [\#482](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/482) ([mhenrixon](https://github.com/mhenrixon))
263
345
 
264
346
  **Closed issues:**
265
347
 
@@ -274,6 +356,10 @@
274
356
 
275
357
  [Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v7.0.0.beta10...v7.0.0.beta11)
276
358
 
359
+ **Fixed bugs:**
360
+
361
+ - Only configure RSpec when constant is defined [\#477](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/477) ([mhenrixon](https://github.com/mhenrixon))
362
+
277
363
  ## [v7.0.0.beta10](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v7.0.0.beta10) (2020-03-21)
278
364
 
279
365
  [Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.19...v7.0.0.beta10)
@@ -284,12 +370,14 @@
284
370
  - Split calculator into two separate [\#474](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/474) ([mhenrixon](https://github.com/mhenrixon))
285
371
  - Prepare for improving tests [\#473](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/473) ([mhenrixon](https://github.com/mhenrixon))
286
372
  - Update gemspec: thor [\#465](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/465) ([masawo](https://github.com/masawo))
373
+ - Various changes to test and verify reliability [\#463](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/463) ([mhenrixon](https://github.com/mhenrixon))
374
+ - Separate client and server on\_conflict [\#462](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/462) ([mhenrixon](https://github.com/mhenrixon))
287
375
 
288
376
  **Fixed bugs:**
289
377
 
290
378
  - With v6.0.18, Sidekiq doesn't run at all [\#471](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/471)
291
- - Only configure RSpec when constant is defined [\#477](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/477) ([mhenrixon](https://github.com/mhenrixon))
292
379
  - Fix errors\_as\_string on lock\_config.rb [\#469](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/469) ([donaldpiret](https://github.com/donaldpiret))
380
+ - Pass redis\_version into scripts [\#431](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/431) ([mhenrixon](https://github.com/mhenrixon))
293
381
 
294
382
  **Merged pull requests:**
295
383
 
@@ -312,7 +400,6 @@
312
400
  **Implemented enhancements:**
313
401
 
314
402
  - Keys without TTL [\#417](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/417)
315
- - Various changes to test and verify reliability [\#463](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/463) ([mhenrixon](https://github.com/mhenrixon))
316
403
 
317
404
  **Closed issues:**
318
405
 
@@ -325,7 +412,6 @@
325
412
  **Implemented enhancements:**
326
413
 
327
414
  - Allow worker to configure client and server strategies separately [\#402](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/402)
328
- - Separate client and server on\_conflict [\#462](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/462) ([mhenrixon](https://github.com/mhenrixon))
329
415
 
330
416
  **Fixed bugs:**
331
417
 
@@ -357,7 +443,6 @@
357
443
  **Merged pull requests:**
358
444
 
359
445
  - Fix that Sidekiq now sends instance of worker [\#459](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/459) ([mhenrixon](https://github.com/mhenrixon))
360
- - Fix typo in readme [\#456](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/456) ([sheerun](https://github.com/sheerun))
361
446
 
362
447
  ## [v6.0.18](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v6.0.18) (2019-11-28)
363
448
 
@@ -380,7 +465,6 @@
380
465
 
381
466
  - Bump rails [\#450](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/450) ([mhenrixon](https://github.com/mhenrixon))
382
467
  - Rename myapp [\#449](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/449) ([mhenrixon](https://github.com/mhenrixon))
383
- - Just to keep track of this [\#445](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/445) ([mhenrixon](https://github.com/mhenrixon))
384
468
 
385
469
  **Fixed bugs:**
386
470
 
@@ -408,6 +492,10 @@
408
492
 
409
493
  - Ensure runtime locks are removed [\#447](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/447) ([mhenrixon](https://github.com/mhenrixon))
410
494
 
495
+ **Merged pull requests:**
496
+
497
+ - Fix typo in readme [\#456](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/456) ([sheerun](https://github.com/sheerun))
498
+
411
499
  ## [v7.0.0.beta4](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v7.0.0.beta4) (2019-11-25)
412
500
 
413
501
  [Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v7.0.0.beta3...v7.0.0.beta4)
@@ -422,12 +510,14 @@
422
510
 
423
511
  **Implemented enhancements:**
424
512
 
513
+ - Just to keep track of this [\#445](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/445) ([mhenrixon](https://github.com/mhenrixon))
425
514
  - Brpoplpush redis script [\#434](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/434) ([mhenrixon](https://github.com/mhenrixon))
426
515
  - Drop support for almost EOL ruby 2.4 [\#433](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/433) ([mhenrixon](https://github.com/mhenrixon))
427
516
 
428
517
  **Fixed bugs:**
429
518
 
430
519
  - Redis is busy running script and script never terminates [\#441](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/441)
520
+ - Make the ruby reaper plain ruby [\#443](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/443) ([mhenrixon](https://github.com/mhenrixon))
431
521
 
432
522
  **Closed issues:**
433
523
 
@@ -441,11 +531,6 @@
441
531
 
442
532
  [Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v7.0.0.beta1...v7.0.0.beta2)
443
533
 
444
- **Fixed bugs:**
445
-
446
- - Make the ruby reaper plain ruby [\#443](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/443) ([mhenrixon](https://github.com/mhenrixon))
447
- - Pass redis\_version into scripts [\#431](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/431) ([mhenrixon](https://github.com/mhenrixon))
448
-
449
534
  **Closed issues:**
450
535
 
451
536
  - incorrect `:until\_and\_while\_executing` behavior [\#424](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/424)
@@ -467,6 +552,7 @@
467
552
  **Fixed bugs:**
468
553
 
469
554
  - Allow Sidekiq::Context to be used for logging [\#429](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/429) ([mhenrixon](https://github.com/mhenrixon))
555
+ - Fix v6 [\#428](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/428) ([mhenrixon](https://github.com/mhenrixon))
470
556
  - Fix sidekiq develop [\#426](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/426) ([mhenrixon](https://github.com/mhenrixon))
471
557
  - Reap as many orphans as advertised [\#403](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/403) ([mhenrixon](https://github.com/mhenrixon))
472
558
  - Reaper should remove :INFO keys [\#399](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/399) ([mhenrixon](https://github.com/mhenrixon))
@@ -493,7 +579,6 @@
493
579
  - Duplicate job was pushed \( v6.0.13 \) [\#414](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/414)
494
580
  - Constant SidekiqUniqueJobs::Web::Digests not found [\#396](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/396)
495
581
  - Include redis directory [\#430](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/430) ([mhenrixon](https://github.com/mhenrixon))
496
- - Fix v6 [\#428](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/428) ([mhenrixon](https://github.com/mhenrixon))
497
582
 
498
583
  **Closed issues:**
499
584
 
@@ -548,7 +633,6 @@
548
633
  - Version 6: lets you schedule job with missing arguments [\#351](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/351)
549
634
  - Version 6 Ignores Jobs Enqueued in Version 5 [\#345](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/345)
550
635
  - Job will not enqueue even with no existing match [\#342](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/342)
551
- - Convert v5 locks when needed [\#375](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/375) ([mhenrixon](https://github.com/mhenrixon))
552
636
 
553
637
  **Closed issues:**
554
638
 
@@ -586,6 +670,10 @@
586
670
 
587
671
  [Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.7...v6.0.8)
588
672
 
673
+ **Fixed bugs:**
674
+
675
+ - Close \#359 [\#364](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/364) ([mhenrixon](https://github.com/mhenrixon))
676
+
589
677
  **Closed issues:**
590
678
 
591
679
  - Automatic unlock of jobs [\#362](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/362)
@@ -608,7 +696,7 @@
608
696
  **Fixed bugs:**
609
697
 
610
698
  - Version 5: Job ID Hash Entries Not Removed if Unique Key Expires [\#346](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/346)
611
- - Close \#359 [\#364](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/364) ([mhenrixon](https://github.com/mhenrixon))
699
+ - Convert v5 locks when needed [\#375](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/375) ([mhenrixon](https://github.com/mhenrixon))
612
700
  - Move the lpush last [\#354](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/354) ([mhenrixon](https://github.com/mhenrixon))
613
701
  - Convert expiration time to integer [\#330](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/330) ([dareddov](https://github.com/dareddov))
614
702
 
@@ -623,6 +711,7 @@
623
711
  - fix CHANGELOG syntax [\#344](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/344) ([timoschilling](https://github.com/timoschilling))
624
712
  - Define Config class inside SidekiqUniqueJobs module [\#343](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/343) ([Slike9](https://github.com/Slike9))
625
713
  - fix readme testing section [\#333](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/333) ([edmartins](https://github.com/edmartins))
714
+ - Fix typo in documentation \[ci-skip\] [\#327](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/327) ([mhenrixon](https://github.com/mhenrixon))
626
715
 
627
716
  ## [v5.0.11](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.11) (2018-11-19)
628
717
 
@@ -667,10 +756,6 @@
667
756
 
668
757
  - Why is lock\_timeout: nil VERY DANGEROUS? [\#313](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/313)
669
758
 
670
- **Merged pull requests:**
671
-
672
- - Fix typo in documentation \[ci-skip\] [\#327](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/327) ([mhenrixon](https://github.com/mhenrixon))
673
-
674
759
  ## [v6.0.4](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v6.0.4) (2018-08-02)
675
760
 
676
761
  [Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.3...v6.0.4)
@@ -797,16 +882,13 @@
797
882
 
798
883
  **Implemented enhancements:**
799
884
 
885
+ - Prepare for v6 [\#286](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/286) ([mhenrixon](https://github.com/mhenrixon))
800
886
  - Only unlock not delete [\#285](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/285) ([mhenrixon](https://github.com/mhenrixon))
801
887
 
802
888
  ## [v6.0.0.rc3](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v6.0.0.rc3) (2018-06-29)
803
889
 
804
890
  [Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.0.rc2...v6.0.0.rc3)
805
891
 
806
- **Implemented enhancements:**
807
-
808
- - Prepare for v6 [\#286](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/286) ([mhenrixon](https://github.com/mhenrixon))
809
-
810
892
  **Fixed bugs:**
811
893
 
812
894
  - Fix waiting for locks [\#284](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/284) ([mhenrixon](https://github.com/mhenrixon))
@@ -819,7 +901,7 @@
819
901
 
820
902
  - Within tests: workers enqueued in the future don't clear their unique locks after being drained/executed [\#254](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/254)
821
903
  - Unexpected behavior with until\_executed [\#250](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/250)
822
- - Fix UntilExpired [\#278](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/278) ([mhenrixon](https://github.com/mhenrixon))
904
+ - Code smells [\#275](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/275) ([mhenrixon](https://github.com/mhenrixon))
823
905
 
824
906
  **Fixed bugs:**
825
907
 
@@ -849,6 +931,7 @@
849
931
  - Legacy support [\#280](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/280)
850
932
  - Adds legacy support [\#281](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/281) ([mhenrixon](https://github.com/mhenrixon))
851
933
  - Adds guard-reek [\#279](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/279) ([mhenrixon](https://github.com/mhenrixon))
934
+ - Fix UntilExpired [\#278](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/278) ([mhenrixon](https://github.com/mhenrixon))
852
935
 
853
936
  ## [v6.0.0.beta2](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v6.0.0.beta2) (2018-06-25)
854
937
 
@@ -865,7 +948,6 @@
865
948
 
866
949
  **Implemented enhancements:**
867
950
 
868
- - Code smells [\#275](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/275) ([mhenrixon](https://github.com/mhenrixon))
869
951
  - Reject while scheduling [\#273](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/273) ([mhenrixon](https://github.com/mhenrixon))
870
952
  - Improve testing [\#272](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/272) ([mhenrixon](https://github.com/mhenrixon))
871
953
 
@@ -1288,6 +1370,7 @@
1288
1370
  - Add after unlock hook [\#92](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/92) ([HParker](https://github.com/HParker))
1289
1371
  - Do not unlock on sidekiq shutdown [\#87](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/87) ([deltaroe](https://github.com/deltaroe))
1290
1372
  - Remove no-op code, protect global space from test code [\#86](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/86) ([stevenjonescgm](https://github.com/stevenjonescgm))
1373
+ - Remove unique lock when executing and clearing jobs in sidekiq fake mode [\#83](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/83) ([crberube](https://github.com/crberube))
1291
1374
  - Fix tests. Tests with latest sidekiq versions and ruby versions [\#82](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/82) ([simonoff](https://github.com/simonoff))
1292
1375
  - Duplicate Payload logging configuration [\#81](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/81) ([jprincipe](https://github.com/jprincipe))
1293
1376
  - output log if not unique [\#79](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/79) ([sonots](https://github.com/sonots))
@@ -1334,7 +1417,6 @@
1334
1417
 
1335
1418
  **Merged pull requests:**
1336
1419
 
1337
- - Remove unique lock when executing and clearing jobs in sidekiq fake mode [\#83](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/83) ([crberube](https://github.com/crberube))
1338
1420
  - Refactoring connectors to use them in client and server [\#56](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/56) ([salrepe](https://github.com/salrepe))
1339
1421
  - Fix dependency error in inline testing connector [\#54](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/54) ([salrepe](https://github.com/salrepe))
1340
1422
  - Add extension to Sidekiq API that is uniqueness-aware [\#52](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/52) ([rickenharp](https://github.com/rickenharp))
data/README.md CHANGED
@@ -98,21 +98,23 @@ bundle
98
98
 
99
99
  Before v7, the middleware was configured automatically. Since some people reported issues with other gems (see [Other Sidekiq Gems](#other-sidekiq-gems)) it was decided to give full control over to the user.
100
100
 
101
- [A full and hopefully working example](https://github.com/mhenrixon/sidekiq-unique-jobs/blob/master/myapp/config/sidekiq.rb#L12)
101
+ *NOTE* if you want to use the reaper you also need to configure the server middleware.
102
+
103
+ [A full example](https://github.com/mhenrixon/sidekiq-unique-jobs/blob/master/myapp/config/initializers/sidekiq.rb#L12)
102
104
 
103
105
  ```ruby
104
106
  Sidekiq.configure_server do |config|
105
107
  config.redis = { url: ENV["REDIS_URL"], driver: :hiredis }
106
108
 
109
+ config.client_middleware do |chain|
110
+ chain.add SidekiqUniqueJobs::Middleware::Client
111
+ end
112
+
107
113
  config.server_middleware do |chain|
108
114
  chain.add SidekiqUniqueJobs::Middleware::Server
109
115
  end
110
116
 
111
- config.error_handlers << ->(ex, ctx_hash) { p ex, ctx_hash }
112
- config.death_handlers << lambda do |job, _ex|
113
- digest = job["lock_digest"]
114
- SidekiqUniqueJobs::Digests.delete_by_digest(digest) if digest
115
- end
117
+ SidekiqUniqueJobs::Server.configure(config)
116
118
  end
117
119
 
118
120
  Sidekiq.configure_client do |config|
@@ -158,12 +160,12 @@ Want to show me some ❤️ for the hard work I do on this gem? You can use the
158
160
 
159
161
  ## Requirements
160
162
 
161
- - Sidekiq `>= 4.0` (`>= 5.2` recommended)
163
+ - Sidekiq `>= 5.0` (`>= 5.2` recommended)
162
164
  - Ruby:
163
165
  - MRI `>= 2.5` (`>= 2.6` recommended)
164
166
  - JRuby `>= 9.0` (`>= 9.2` recommended)
165
167
  - Truffleruby
166
- - Redis Server `>= 3.0.2` (`>= 3.2` recommended)
168
+ - Redis Server `>= 3.2` (`>= 5.0` recommended)
167
169
  - [ActiveJob officially not supported][48]
168
170
  - [redis-namespace officially not supported][49]
169
171
 
@@ -183,16 +185,16 @@ Configure SidekiqUniqueJobs in an initializer or the sidekiq initializer on appl
183
185
 
184
186
  ```ruby
185
187
  SidekiqUniqueJobs.configure do |config|
186
- config.debug_lua = true
187
- config.lock_info = true
188
- config.lock_ttl = 10.minutes
189
- config.lock_timeout = 10.minutes
190
- config.logger = Sidekiq.logger
191
- config.max_history = 10_000
192
- config.reaper = :lua
193
- config.reaper_count = 100
194
- config.reaper_interval = 10
195
- config.reaper_timeout = 5
188
+ config.logger = Sidekiq.logger # default, change at your own discretion
189
+ config.debug_lua = false # Turn on when debugging
190
+ config.lock_info = false # Turn on when debugging
191
+ config.lock_ttl = 600 # Expire locks after 10 minutes
192
+ config.lock_timeout = nil # turn off lock timeout
193
+ config.max_history = 0 # Turn on when debugging
194
+ config.reaper = :ruby # :ruby, :lua or :none/nil
195
+ config.reaper_count = 1000 # Stop reaping after this many keys
196
+ config.reaper_interval = 600 # Reap orphans every 10 minutes
197
+ config.reaper_timeout = 150 # Timeout reaper after 2.5 minutes
196
198
  end
197
199
  ```
198
200
 
@@ -507,7 +509,7 @@ The last one is log which can be be used with the lock `UntilExecuted` and `Unti
507
509
  It is possible for locks to have different conflict strategy for the client and server. This is useful for `:until_and_while_executing`.
508
510
 
509
511
  ```ruby
510
- sidekiq_options lock: :until_and_while_executing,
512
+ sidekiq_options lock: :until_and_while_executing,
511
513
  on_conflict: { client: :log, server: :reject }
512
514
  ```
513
515
 
@@ -707,7 +709,7 @@ class MyWorker
707
709
  end
708
710
  ```
709
711
 
710
- Starting in v5.1, Sidekiq can also fire a global callback when a job dies:
712
+ Starting in v5.1, Sidekiq can also fire a global callback when a job dies: In version 7, this is handled automatically for you. You don't need to add a death handler, if you configure v7 like in [Add the middleware](#add-the-middleware) you don't have to worry about the below.
711
713
 
712
714
  ```ruby
713
715
  Sidekiq.configure_server do |config|
@@ -751,8 +753,8 @@ Sidekiq.client_middleware do |chain|
751
753
  end
752
754
 
753
755
  Sidekiq.server_middleware do |chain|
754
- chain.add SidekiqUniqueJobs::Middleware::Server
755
756
  chain.add Sidekiq::GlobalId::ServerMiddleware
757
+ chain.add SidekiqUniqueJobs::Middleware::Server
756
758
  end
757
759
  ```
758
760
 
@@ -763,14 +765,28 @@ The reason for this is that the global id needs to be set before the unique jobs
763
765
  It was reported in [#564](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/564) that the order of the middleware needs to be as follows.
764
766
 
765
767
  ```ruby
766
- Sidekiq.client_middleware do |chain|
767
- chain.add Sidekiq::Status::ClientMiddleware, expiration: 10.minutes
768
- chain.add Sidekiq::Status::ServerMiddleware
768
+ # Thanks to @ArturT for the correction
769
+
770
+ Sidekiq.configure_server do |config|
771
+ config.client_middleware do |chain|
772
+ chain.add SidekiqUniqueJobs::Middleware::Client
773
+ chain.add Sidekiq::Status::ClientMiddleware, expiration: 30.minutes
774
+ end
775
+
776
+ config.server_middleware do |chain|
777
+ chain.add Sidekiq::Status::ServerMiddleware, expiration: 30.minutes
778
+ chain.add SidekiqUniqueJobs::Middleware::Server
779
+ end
780
+
781
+ SidekiqUniqueJobs::Server.configure(config)
769
782
  end
770
783
 
771
- Sidekiq.server_middleware do |chain|
772
- chain.add Sidekiq::Status::ServerMiddleware, expiration: 10.minutes
773
- chain.add SidekiqUniqueJobs::Middleware::Server
784
+
785
+ Sidekiq.configure_client do |config|
786
+ config.client_middleware do |chain|
787
+ chain.add SidekiqUniqueJobs::Middleware::Client
788
+ chain.add Sidekiq::Status::ClientMiddleware, expiration: 30.minutes
789
+ end
774
790
  end
775
791
  ```
776
792
 
@@ -845,7 +861,6 @@ If you are not using RSpec (a lot of people prefer minitest or test unit) you ca
845
861
  assert SidekiqUniqueJobs.validate_worker!(BadWorker.get_sidekiq_options)
846
862
  ```
847
863
 
848
-
849
864
  ### Uniqueness
850
865
 
851
866
  This has been probably the most confusing part of this gem. People get really confused with how unreliable the unique jobs have been. I there for decided to do what Mike is doing for sidekiq enterprise. Read the section about unique jobs: [Enterprise unique jobs][]
@@ -888,7 +903,7 @@ RSpec.describe Workers::CoolOne do
888
903
  end
889
904
  ```
890
905
 
891
- It is recommened to leave the uniqueness testing to the gem maintainers. If you care about how the gem is integration tested have a look at the following specs:
906
+ It is recommended to leave the uniqueness testing to the gem maintainers. If you care about how the gem is integration tested have a look at the following specs:
892
907
 
893
908
  - [spec/integration/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb](https://github.com/mhenrixon/sidekiq-unique-jobs/blob/master/spec/integration/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb)
894
909
  - [spec/integration/sidekiq_unique_jobs/lock/until_executed_spec.rb](https://github.com/mhenrixon/sidekiq-unique-jobs/blob/master/spec/integration/sidekiq_unique_jobs/lock/until_executed_spec.rb)
@@ -3,9 +3,10 @@
3
3
  require "brpoplpush/redis_script"
4
4
  require "concurrent/future"
5
5
  require "concurrent/promises"
6
- require "concurrent/timer_task"
7
6
  require "concurrent/map"
8
7
  require "concurrent/mutable_struct"
8
+ require "concurrent/timer_task"
9
+ require "concurrent/executor/ruby_single_thread_executor"
9
10
  require "digest"
10
11
  require "digest/sha1"
11
12
  require "erb"
@@ -14,6 +15,7 @@ require "json"
14
15
  require "pathname"
15
16
  require "sidekiq"
16
17
 
18
+ require "sidekiq_unique_jobs/timer_task"
17
19
  require "sidekiq_unique_jobs/version"
18
20
  require "sidekiq_unique_jobs/version_check"
19
21
  require "sidekiq_unique_jobs/constants"
@@ -71,3 +73,4 @@ require "sidekiq_unique_jobs/config"
71
73
  require "sidekiq_unique_jobs/sidekiq_unique_jobs"
72
74
  require "sidekiq_unique_jobs/update_version"
73
75
  require "sidekiq_unique_jobs/upgrade_locks"
76
+ require "sidekiq_unique_jobs/server"
@@ -44,7 +44,7 @@ module SidekiqUniqueJobs
44
44
  #
45
45
  # @return [void]
46
46
  #
47
- def self.call(digests, conn)
47
+ def self.call(digests, conn = nil)
48
48
  new(digests, conn).call
49
49
  end
50
50
 
@@ -7,6 +7,13 @@ module SidekiqUniqueJobs
7
7
  # @author Mikael Henriksson <mikael@mhenrixon.com>
8
8
  #
9
9
  class Changelog < Redis::SortedSet
10
+ #
11
+ # @return [Integer] the number of matches to return by default
12
+ DEFAULT_COUNT = 1_000
13
+ #
14
+ # @return [String] the default pattern to use for matching
15
+ SCAN_PATTERN = "*"
16
+
10
17
  def initialize
11
18
  super(CHANGELOGS)
12
19
  end
@@ -34,10 +41,10 @@ module SidekiqUniqueJobs
34
41
  #
35
42
  # @return [Array<Hash>] an array of entries
36
43
  #
37
- def entries(pattern: "*", count: nil)
44
+ def entries(pattern: SCAN_PATTERN, count: DEFAULT_COUNT)
38
45
  options = {}
39
46
  options[:match] = pattern
40
- options[:count] = count if count
47
+ options[:count] = count
41
48
 
42
49
  redis do |conn|
43
50
  conn.zscan_each(key, **options).to_a.map { |entry| load_json(entry[0]) }
@@ -53,7 +60,7 @@ module SidekiqUniqueJobs
53
60
  #
54
61
  # @return [Array<Integer, Integer, Array<Hash>] the total size, next cursor and changelog entries
55
62
  #
56
- def page(cursor, pattern: "*", page_size: 100)
63
+ def page(cursor: 0, pattern: "*", page_size: 100)
57
64
  redis do |conn|
58
65
  total_size, result = conn.multi do
59
66
  conn.zcard(key)
@@ -15,11 +15,17 @@ module SidekiqUniqueJobs
15
15
  # @return [Object]
16
16
  #
17
17
  def load_json(string)
18
- return unless string && !string.empty?
18
+ return if string.nil? || string.empty?
19
19
 
20
20
  ::JSON.parse(string)
21
21
  end
22
22
 
23
+ def safe_load_json(string)
24
+ return string if string.is_a?(Hash)
25
+
26
+ load_json(string)
27
+ end
28
+
23
29
  #
24
30
  # Dumps an object into a JSON string
25
31
  #
@@ -53,7 +53,7 @@ module SidekiqUniqueJobs
53
53
  #
54
54
  # Locks a job_id
55
55
  #
56
- # @note intended only for testing purposez
56
+ # @note intended only for testing purposes
57
57
  #
58
58
  # @param [String] job_id a sidekiq JID
59
59
  # @param [Hash] lock_info information about the lock
@@ -73,6 +73,36 @@ module SidekiqUniqueJobs
73
73
  end
74
74
  end
75
75
 
76
+ #
77
+ # Create the :QUEUED key
78
+ #
79
+ # @note intended only for testing purposes
80
+ #
81
+ # @param [String] job_id a sidekiq JID
82
+ #
83
+ # @return [void]
84
+ #
85
+ def queue(job_id)
86
+ redis do |conn|
87
+ conn.lpush(key.queued, job_id)
88
+ end
89
+ end
90
+
91
+ #
92
+ # Create the :PRIMED key
93
+ #
94
+ # @note intended only for testing purposes
95
+ #
96
+ # @param [String] job_id a sidekiq JID
97
+ #
98
+ # @return [void]
99
+ #
100
+ def prime(job_id)
101
+ redis do |conn|
102
+ conn.lpush(key.primed, job_id)
103
+ end
104
+ end
105
+
76
106
  #
77
107
  # Unlock a specific job_id
78
108
  #
@@ -74,19 +74,19 @@ if pttl and pttl > 0 then
74
74
  log_debug("PEXPIRE", digest, pttl)
75
75
  redis.call("PEXPIRE", digest, pttl)
76
76
 
77
- log_debug("PEXPIRE", queued, pttl)
78
- redis.call("PEXPIRE", queued, pttl)
79
-
80
- log_debug("PEXPIRE", primed, pttl)
81
- redis.call("PEXPIRE", primed, pttl)
82
-
83
77
  log_debug("PEXPIRE", locked, pttl)
84
78
  redis.call("PEXPIRE", locked, pttl)
85
-
86
- log_debug("PEXPIRE", info, pttl)
87
- redis.call("PEXPIRE", info, pttl)
88
79
  end
89
80
 
81
+ log_debug("PEXPIRE", queued, 1000)
82
+ redis.call("PEXPIRE", queued, 1000)
83
+
84
+ log_debug("PEXPIRE", primed, 1000)
85
+ redis.call("PEXPIRE", primed, 1000)
86
+
87
+ log_debug("PEXPIRE", info, 1000)
88
+ redis.call("PEXPIRE", info, 1000)
89
+
90
90
  log("Locked")
91
91
  log_debug("END lock digest:", digest, "job_id:", job_id)
92
92
  return job_id
@@ -27,14 +27,14 @@ local function find_digest_in_process_set(digest, threshold)
27
27
  else
28
28
  for i = 1, #jobs, 2 do
29
29
  local jobstr = jobs[i +1]
30
- if string.find(jobstr, digest) then
30
+ if string.find(string.gsub(jobstr, ':RUN', ''), string.gsub(digest, ':RUN', '')) then
31
31
  log_debug("Found digest", digest, "in:", workers_key)
32
32
  found = true
33
33
  break
34
34
  end
35
35
 
36
36
  local job = cjson.decode(jobstr)
37
- if job.created_at > threshold then
37
+ if job.payload.created_at > threshold then
38
38
  found = true
39
39
  break
40
40
  end
@@ -20,12 +20,14 @@ module SidekiqUniqueJobs
20
20
  # Starts a separate thread that periodically reaps orphans
21
21
  #
22
22
  #
23
- # @return [Concurrent::TimerTask] the task that was started
23
+ # @return [SidekiqUniqueJobs::TimerTask] the task that was started
24
24
  #
25
- def start # rubocop:disable
25
+ def start(test_task = nil) # rubocop:disable
26
26
  return if disabled?
27
27
  return if registered?
28
28
 
29
+ self.task = test_task || default_task
30
+
29
31
  with_logging_context do
30
32
  register_reaper_process
31
33
  log_info("Starting Reaper")
@@ -59,12 +61,11 @@ module SidekiqUniqueJobs
59
61
  # @return [<type>] <description>
60
62
  #
61
63
  def task
62
- @task ||= Concurrent::TimerTask.new(timer_task_options, &task_body)
64
+ @task ||= default_task
63
65
  end
64
66
 
65
- # @private
66
- def task_body
67
- @task_body ||= lambda do
67
+ def default_task
68
+ SidekiqUniqueJobs::TimerTask.new(timer_task_options) do
68
69
  with_logging_context do
69
70
  redis do |conn|
70
71
  refresh_reaper_mutex
@@ -74,6 +75,10 @@ module SidekiqUniqueJobs
74
75
  end
75
76
  end
76
77
 
78
+ def task=(task)
79
+ @task = task
80
+ end
81
+
77
82
  #
78
83
  # Arguments passed on to the timer task
79
84
  #
@@ -10,6 +10,7 @@ module SidekiqUniqueJobs
10
10
  # @author Mikael Henriksson <mikael@mhenrixon.com>
11
11
  #
12
12
  class RubyReaper < Reaper
13
+ RUN_SUFFIX = ":RUN"
13
14
  #
14
15
  # @!attribute [r] digests
15
16
  # @return [SidekiqUniqueJobs::Digests] digest collection
@@ -52,11 +53,11 @@ module SidekiqUniqueJobs
52
53
  # @return [Array<String>] an array of orphaned digests
53
54
  #
54
55
  def orphans
55
- conn.zrevrange(digests.key, 0, -1).each_with_object([]) do |digest, result|
56
+ conn.zrevrange(digests.key, 0, -1).each_with_object([]) do |digest, memo|
56
57
  next if belongs_to_job?(digest)
57
58
 
58
- result << digest
59
- break if result.size >= reaper_count
59
+ memo << digest
60
+ break if memo.size >= reaper_count
60
61
  end
61
62
  end
62
63
 
@@ -117,14 +118,19 @@ module SidekiqUniqueJobs
117
118
  end
118
119
  end
119
120
 
120
- def active?(digest) # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
121
+ def active?(digest) # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
121
122
  Sidekiq.redis do |conn|
122
123
  procs = conn.sscan_each("processes").to_a
123
124
  return false if procs.empty?
124
125
 
125
126
  procs.sort.each do |key|
126
127
  valid, workers = conn.pipelined do
127
- conn.exists(key)
128
+ # TODO: Remove the if statement in the future
129
+ if conn.respond_to?(:exists?)
130
+ conn.exists?(key)
131
+ else
132
+ conn.exists(key)
133
+ end
128
134
  conn.hgetall("#{key}:workers")
129
135
  end
130
136
 
@@ -132,10 +138,12 @@ module SidekiqUniqueJobs
132
138
  next unless workers.any?
133
139
 
134
140
  workers.each_pair do |_tid, job|
135
- item = load_json(job)
141
+ next unless (item = safe_load_json(job))
136
142
 
137
- return true if item.dig(PAYLOAD, LOCK_DIGEST) == digest
138
- return true if considered_active?(item[CREATED_AT])
143
+ payload = safe_load_json(item[PAYLOAD])
144
+
145
+ return true if match?(digest, payload[LOCK_DIGEST])
146
+ return true if considered_active?(payload[CREATED_AT])
139
147
  end
140
148
  end
141
149
 
@@ -143,6 +151,10 @@ module SidekiqUniqueJobs
143
151
  end
144
152
  end
145
153
 
154
+ def match?(key_one, key_two)
155
+ key_one.delete_suffix(RUN_SUFFIX) == key_two.delete_suffix(RUN_SUFFIX)
156
+ end
157
+
146
158
  def considered_active?(time_f)
147
159
  (Time.now - reaper_timeout).to_f < time_f
148
160
  end
@@ -47,7 +47,13 @@ module SidekiqUniqueJobs
47
47
  #
48
48
  def exist?
49
49
  redis do |conn|
50
- value = conn.exists(key)
50
+ # TODO: Remove the if statement in the future
51
+ value =
52
+ if conn.respond_to?(:exists?)
53
+ conn.exists?(key)
54
+ else
55
+ conn.exists(key)
56
+ end
51
57
 
52
58
  return value if boolean?(value)
53
59
 
@@ -23,6 +23,23 @@ module SidekiqUniqueJobs
23
23
  entrys.each_with_object({}) { |pair, hash| hash[pair[0]] = pair[1] }
24
24
  end
25
25
 
26
+ #
27
+ # Adds a value to the sorted set
28
+ #
29
+ # @param [Array<Float, String>, String] the values to add
30
+ #
31
+ # @return [Boolean, Integer] <description>
32
+ #
33
+ def add(values)
34
+ redis do |conn|
35
+ if values.is_a?(Array)
36
+ conn.zadd(key, values)
37
+ else
38
+ conn.zadd(key, now_f, values)
39
+ end
40
+ end
41
+ end
42
+
26
43
  #
27
44
  # Return the zrak of the member
28
45
  #
@@ -45,6 +62,16 @@ module SidekiqUniqueJobs
45
62
  redis { |conn| conn.zscore(key, member) }
46
63
  end
47
64
 
65
+ #
66
+ # Clears the sorted set from all entries
67
+ #
68
+ #
69
+ # @return [Integer] number of entries removed
70
+ #
71
+ def clear
72
+ redis { |conn| conn.zremrangebyrank(key, 0, count) }
73
+ end
74
+
48
75
  #
49
76
  # Returns the count for this sorted set
50
77
  #
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SidekiqUniqueJobs
4
+ # The unique sidekiq middleware for the server processor
5
+ #
6
+ # @author Mikael Henriksson <mikael@mhenrixon.com>
7
+ class Server
8
+ DEATH_HANDLER ||= (lambda do |job, _ex|
9
+ return unless (digest = job["lock_digest"])
10
+
11
+ SidekiqUniqueJobs::Digests.new.delete_by_digest(digest)
12
+ end).freeze
13
+ #
14
+ # Configure the server middleware
15
+ #
16
+ #
17
+ # @return [Sidekiq] the sidekiq configuration
18
+ #
19
+ def self.configure(config)
20
+ config.on(:startup) { start }
21
+ config.on(:shutdown) { stop }
22
+
23
+ return unless config.respond_to?(:death_handlers)
24
+
25
+ config.death_handlers << death_handler
26
+ end
27
+
28
+ def self.start
29
+ SidekiqUniqueJobs::UpdateVersion.call
30
+ SidekiqUniqueJobs::UpgradeLocks.call
31
+ SidekiqUniqueJobs::Orphans::Manager.start
32
+ end
33
+
34
+ def self.stop
35
+ SidekiqUniqueJobs::Orphans::Manager.stop
36
+ end
37
+
38
+ #
39
+ # A death handler for dead jobs
40
+ #
41
+ #
42
+ # @return [lambda]
43
+ #
44
+ def self.death_handler
45
+ DEATH_HANDLER
46
+ end
47
+ end
48
+ end
@@ -188,7 +188,7 @@ module SidekiqUniqueJobs
188
188
  # @return [String] a string like `5.0.2`
189
189
  #
190
190
  def fetch_redis_version
191
- redis { |conn| conn.info("server")["redis_version"] }
191
+ Sidekiq.redis_info["redis_version"]
192
192
  end
193
193
 
194
194
  #
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SidekiqUniqueJobs
4
+ # @see [Concurrent::TimerTask] https://www.rubydoc.info/gems/concurrent-ruby/Concurrent/TimerTask
5
+ #
6
+ class TimerTask < ::Concurrent::TimerTask
7
+ private
8
+
9
+ def ns_initialize(opts, &task)
10
+ set_deref_options(opts)
11
+
12
+ self.execution_interval = opts[:execution] || opts[:execution_interval] || EXECUTION_INTERVAL
13
+ self.timeout_interval = opts[:timeout] || opts[:timeout_interval] || TIMEOUT_INTERVAL
14
+ @run_now = opts[:now] || opts[:run_now]
15
+ @executor = Concurrent::RubySingleThreadExecutor.new
16
+ @running = Concurrent::AtomicBoolean.new(false)
17
+ @task = task
18
+ @value = nil
19
+
20
+ self.observers = Concurrent::Collection::CopyOnNotifyObserverSet.new
21
+ end
22
+
23
+ def schedule_next_task(interval = execution_interval)
24
+ exec_task = ->(completion) { execute_task(completion) }
25
+ Concurrent::ScheduledTask.execute(interval, args: [Concurrent::Event.new], &exec_task)
26
+ nil
27
+ end
28
+
29
+ # @!visibility private
30
+ def execute_task(completion) # rubocop:disable Metrics/MethodLength
31
+ return nil unless @running.true?
32
+
33
+ timeout_task = -> { timeout_task(completion) }
34
+
35
+ Concurrent::ScheduledTask.execute(
36
+ timeout_interval,
37
+ args: [completion],
38
+ &timeout_task
39
+ )
40
+ @thread_completed = Concurrent::Event.new
41
+
42
+ @value = @reason = nil
43
+ @executor.post do
44
+ @value = @task.call(self)
45
+ rescue Exception => ex # rubocop:disable Lint/RescueException
46
+ @reason = ex
47
+ ensure
48
+ @thread_completed.set
49
+ end
50
+
51
+ @thread_completed.wait
52
+
53
+ if completion.try?
54
+ schedule_next_task
55
+ time = Time.now
56
+ observers.notify_observers do
57
+ [time, value, @reason]
58
+ end
59
+ end
60
+ nil
61
+ end
62
+
63
+ # @!visibility private
64
+ def timeout_task(completion)
65
+ return unless @running.true?
66
+ return unless completion.try?
67
+
68
+ @executor.kill
69
+ @executor.wait_for_termination
70
+ @executor = Concurrent::RubySingleThreadExecutor.new
71
+
72
+ @thread_completed.set
73
+
74
+ schedule_next_task
75
+ observers.notify_observers(Time.now, nil, Concurrent::TimeoutError.new)
76
+ end
77
+ end
78
+ end
@@ -3,5 +3,5 @@
3
3
  module SidekiqUniqueJobs
4
4
  #
5
5
  # @return [String] the current SidekiqUniqueJobs version
6
- VERSION = "7.0.0"
6
+ VERSION = "7.0.5"
7
7
  end
@@ -13,6 +13,23 @@ module SidekiqUniqueJobs
13
13
  include Web::Helpers
14
14
  end
15
15
 
16
+ app.get "/changelogs" do
17
+ @filter = params[:filter] || "*"
18
+ @filter = "*" if @filter == ""
19
+ @count = (params[:count] || 100).to_i
20
+ @current_cursor = params[:cursor]
21
+ @prev_cursor = params[:prev_cursor]
22
+ @pagination = { pattern: @filter, cursor: @current_cursor, page_size: @count }
23
+ @total_size, @next_cursor, @changelogs = changelog.page(**@pagination)
24
+
25
+ erb(unique_template(:changelogs))
26
+ end
27
+
28
+ app.get "/changelogs/delete_all" do
29
+ changelog.clear
30
+ redirect_to :changelogs
31
+ end
32
+
16
33
  app.get "/locks" do
17
34
  @filter = params[:filter] || "*"
18
35
  @filter = "*" if @filter == ""
@@ -58,7 +75,8 @@ begin
58
75
  require "sidekiq/web" unless defined?(Sidekiq::Web)
59
76
 
60
77
  Sidekiq::Web.register(SidekiqUniqueJobs::Web)
61
- Sidekiq::Web.tabs["Locks"] = "locks"
78
+ Sidekiq::Web.tabs["Locks"] = "locks"
79
+ Sidekiq::Web.tabs["Changelogs"] = "changelogs"
62
80
  Sidekiq::Web.settings.locales << File.join(File.dirname(__FILE__), "locales")
63
81
  rescue NameError, LoadError => ex
64
82
  SidekiqUniqueJobs.logger.error(ex)
@@ -10,12 +10,12 @@ module SidekiqUniqueJobs
10
10
  module Helpers
11
11
  #
12
12
  # @return [String] the path to gem specific views
13
- VIEW_PATH = File.expand_path("../web/views", __dir__)
13
+ VIEW_PATH = File.expand_path("../web/views", __dir__).freeze
14
14
  #
15
15
  # @return [Array<String>] safe params
16
16
  SAFE_CPARAMS = %w[cursor prev_cursor].freeze
17
17
 
18
- module_function
18
+ extend self
19
19
 
20
20
  #
21
21
  # Opens a template file contained within this gem
@@ -25,7 +25,18 @@ module SidekiqUniqueJobs
25
25
  # @return [String] the file contents of the template
26
26
  #
27
27
  def unique_template(name)
28
- File.open(File.join(VIEW_PATH, "#{name}.erb")).read
28
+ File.open(unique_filename(name)).read
29
+ end
30
+
31
+ #
32
+ # Construct template file name
33
+ #
34
+ # @param [Symbol] name the name of the template
35
+ #
36
+ # @return [String] the full name of the file
37
+ #
38
+ def unique_filename(name)
39
+ File.join(VIEW_PATH, "#{name}.erb")
29
40
  end
30
41
 
31
42
  #
@@ -38,6 +49,16 @@ module SidekiqUniqueJobs
38
49
  @digests ||= SidekiqUniqueJobs::Digests.new
39
50
  end
40
51
 
52
+ #
53
+ # The collection of changelog entries
54
+ #
55
+ #
56
+ # @return [SidekiqUniqueJobs::Digests] the sorted set with digests
57
+ #
58
+ def changelog
59
+ @changelog ||= SidekiqUniqueJobs::Changelog.new
60
+ end
61
+
41
62
  #
42
63
  # Creates url safe parameters
43
64
  #
@@ -0,0 +1,54 @@
1
+ <header class="row">
2
+ <div class="col-sm-5">
3
+ <h3>
4
+ <%= t('Changelog Entries') %>
5
+ </h3>
6
+ </div>
7
+ <form action="<%= root_path %>changelogs" class="form form-inline" method="get">
8
+ <%= csrf_tag %>
9
+ <input name="filter" class="form-control" type="text" value="<%= @filter %>" />
10
+ <button class="btn btn-default" type="submit">
11
+ <%= t('Filter') %>
12
+ </button>
13
+ </form>
14
+ <% if @changelogs.any? && @total_size > @count.to_i %>
15
+ <div class="col-sm-4">
16
+ <%= erb unique_template(:_paging), locals: { url: "#{root_path}changelogs" } %>
17
+ </div>
18
+ <% end %>
19
+ </header>
20
+ <% if @changelogs.any? %>
21
+ <div class="table_container">
22
+ <form action="<%= root_path %>changelogs/delete_all" method="get">
23
+ <input class="btn btn-danger btn-xs" type="submit" name="delete_all" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSure') %>" />
24
+ </form>
25
+ <br/>
26
+ <table class="table table-striped table-bordered table-hover">
27
+ <thead>
28
+ <tr>
29
+ <th><%= t('Time') %></th>
30
+ <th><%= t('Digest') %></th>
31
+ <th><%= t('Script') %></th>
32
+ <th><%= t('JID') %></th>
33
+ <th><%= t('Prev JID') %></th>
34
+ <th><%= t('Message') %></th>
35
+ </tr>
36
+ </thead>
37
+ <tbody>
38
+ <% @changelogs.each do |changelog| %>
39
+ <tr>
40
+ <td><%= safe_relative_time(changelog["time"]) %></td>
41
+ <td><%= changelog["digest"] %></td>
42
+ <td><%= changelog["script"] %></td>
43
+ <td><%= changelog["job_id"] %></td>
44
+ <td><%= changelog["prev_jid"] %></td>
45
+ <td><%= changelog["message"] %></th>
46
+ </tr>
47
+ <% end %>
48
+ </tbody>
49
+ </table>
50
+ <form action="<%= root_path %>changelogs/delete_all" method="get">
51
+ <input class="btn btn-danger btn-xs" type="submit" name="delete_all" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSure') %>" />
52
+ </form>
53
+ </div>
54
+ <% end %>
@@ -32,7 +32,7 @@
32
32
  <% @locks.each do |lock| %>
33
33
  <tr>
34
34
  <td>
35
- <form action="<%= root_path %>locks/<%= lock.key %>" method="get">
35
+ <form action="<%= root_path %>locks/<%= lock.key %>/delete" method="get">
36
36
  <%= csrf_tag %>
37
37
  <input name="lock" value="<%= h lock.key %>" type="hidden" />
38
38
  <input class="btn btn-danger btn-xs" type="submit" name="delete" value="<%= t('Delete') %>" data-confirm="<%= t('AreYouSure') %>" />
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq-unique-jobs
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.0.0
4
+ version: 7.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mikael Henriksson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-20 00:00:00.000000000 Z
11
+ date: 2021-03-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: brpoplpush-redis_script
@@ -188,10 +188,12 @@ files:
188
188
  - lib/sidekiq_unique_jobs/rspec/matchers/have_valid_sidekiq_options.rb
189
189
  - lib/sidekiq_unique_jobs/script.rb
190
190
  - lib/sidekiq_unique_jobs/script/caller.rb
191
+ - lib/sidekiq_unique_jobs/server.rb
191
192
  - lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb
192
193
  - lib/sidekiq_unique_jobs/sidekiq_unique_jobs.rb
193
194
  - lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb
194
195
  - lib/sidekiq_unique_jobs/testing.rb
196
+ - lib/sidekiq_unique_jobs/timer_task.rb
195
197
  - lib/sidekiq_unique_jobs/timing.rb
196
198
  - lib/sidekiq_unique_jobs/unlockable.rb
197
199
  - lib/sidekiq_unique_jobs/update_version.rb
@@ -201,6 +203,7 @@ files:
201
203
  - lib/sidekiq_unique_jobs/web.rb
202
204
  - lib/sidekiq_unique_jobs/web/helpers.rb
203
205
  - lib/sidekiq_unique_jobs/web/views/_paging.erb
206
+ - lib/sidekiq_unique_jobs/web/views/changelogs.erb
204
207
  - lib/sidekiq_unique_jobs/web/views/lock.erb
205
208
  - lib/sidekiq_unique_jobs/web/views/locks.erb
206
209
  - lib/tasks/changelog.rake
@@ -254,7 +257,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
254
257
  - !ruby/object:Gem::Version
255
258
  version: '0'
256
259
  requirements: []
257
- rubygems_version: 3.2.4
260
+ rubygems_version: 3.2.6
258
261
  signing_key:
259
262
  specification_version: 4
260
263
  summary: Sidekiq middleware that prevents duplicates jobs