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 +4 -4
- data/CHANGELOG.md +114 -32
- data/README.md +44 -29
- data/lib/sidekiq_unique_jobs.rb +4 -1
- data/lib/sidekiq_unique_jobs/batch_delete.rb +1 -1
- data/lib/sidekiq_unique_jobs/changelog.rb +10 -3
- data/lib/sidekiq_unique_jobs/json.rb +7 -1
- data/lib/sidekiq_unique_jobs/lock.rb +31 -1
- data/lib/sidekiq_unique_jobs/lua/lock.lua +9 -9
- data/lib/sidekiq_unique_jobs/lua/shared/_find_digest_in_process_set.lua +2 -2
- data/lib/sidekiq_unique_jobs/orphans/manager.rb +11 -6
- data/lib/sidekiq_unique_jobs/orphans/ruby_reaper.rb +20 -8
- data/lib/sidekiq_unique_jobs/redis/entity.rb +7 -1
- data/lib/sidekiq_unique_jobs/redis/sorted_set.rb +27 -0
- data/lib/sidekiq_unique_jobs/server.rb +48 -0
- data/lib/sidekiq_unique_jobs/sidekiq_unique_jobs.rb +1 -1
- data/lib/sidekiq_unique_jobs/timer_task.rb +78 -0
- data/lib/sidekiq_unique_jobs/version.rb +1 -1
- data/lib/sidekiq_unique_jobs/web.rb +19 -1
- data/lib/sidekiq_unique_jobs/web/helpers.rb +24 -3
- data/lib/sidekiq_unique_jobs/web/views/changelogs.erb +54 -0
- data/lib/sidekiq_unique_jobs/web/views/locks.erb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 35af721bd8342dc7bbfcc204b12869ee3e78bb0c644db358c479d6ab2de5bba3
|
4
|
+
data.tar.gz: ca936a331cd5d2c591de1d74c000f4e62be908076d188dc7d2e8995965c69b5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
-
|
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
|
-
-
|
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
|
-
|
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
|
-
|
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 `>=
|
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.
|
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.
|
187
|
-
config.
|
188
|
-
config.
|
189
|
-
config.
|
190
|
-
config.
|
191
|
-
config.max_history =
|
192
|
-
config.reaper = :lua
|
193
|
-
config.reaper_count =
|
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
|
-
|
767
|
-
|
768
|
-
|
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
|
-
|
772
|
-
|
773
|
-
|
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
|
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)
|
data/lib/sidekiq_unique_jobs.rb
CHANGED
@@ -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"
|
@@ -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:
|
44
|
+
def entries(pattern: SCAN_PATTERN, count: DEFAULT_COUNT)
|
38
45
|
options = {}
|
39
46
|
options[:match] = pattern
|
40
|
-
options[:count] = 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
|
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
|
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 [
|
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 ||=
|
64
|
+
@task ||= default_task
|
63
65
|
end
|
64
66
|
|
65
|
-
|
66
|
-
|
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,
|
56
|
+
conn.zrevrange(digests.key, 0, -1).each_with_object([]) do |digest, memo|
|
56
57
|
next if belongs_to_job?(digest)
|
57
58
|
|
58
|
-
|
59
|
-
break if
|
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
|
-
|
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 =
|
141
|
+
next unless (item = safe_load_json(job))
|
136
142
|
|
137
|
-
|
138
|
-
|
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
|
-
|
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
|
@@ -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
|
@@ -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"]
|
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
|
-
|
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(
|
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
|
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.
|
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-
|
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.
|
260
|
+
rubygems_version: 3.2.6
|
258
261
|
signing_key:
|
259
262
|
specification_version: 4
|
260
263
|
summary: Sidekiq middleware that prevents duplicates jobs
|