sidekiq-cron 2.0.0.rc1 → 2.0.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +66 -40
- data/lib/sidekiq/cron/job.rb +22 -26
- data/lib/sidekiq/cron/launcher.rb +1 -4
- data/lib/sidekiq/cron/namespace.rb +0 -2
- data/lib/sidekiq/cron/poller.rb +1 -9
- data/lib/sidekiq/cron/schedule_loader.rb +1 -5
- data/lib/sidekiq/cron/support.rb +1 -2
- data/lib/sidekiq/cron/version.rb +1 -1
- data/lib/sidekiq/cron/views/cron.erb +29 -33
- data/lib/sidekiq/cron/views/cron_show.erb +5 -5
- data/lib/sidekiq/cron/web.rb +12 -2
- data/lib/sidekiq/cron/web_extension.rb +19 -12
- data/lib/sidekiq/cron.rb +18 -6
- data/lib/sidekiq/options.rb +3 -5
- data/lib/sidekiq-cron.rb +6 -0
- data/sidekiq-cron.gemspec +2 -2
- metadata +13 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2fa6abcb1076d5e510764b33d0cfdd18d18fd1e585d79c63d300e37a1e0e6db
|
4
|
+
data.tar.gz: 4a04a46b7444879c6291a52e783ece82fa3488fe042106eef525ac81cd6a2d72
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bfd60ceaa0999e67bcc3a123ea767c8ed222a70621f688b0456f189386065570160e53cae1810dcc045b33b03101af5d3f9255b3c8afe6d963255ea9004ead06
|
7
|
+
data.tar.gz: b08f12f1ce7ca1495013c9eae44b4469371b2d3aeb6e81675c044133391ce411c6f1f4e71206776632a37b58d7594842ea38a0e2cb94ee18f32a70409b20249a
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,17 @@
|
|
2
2
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
|
5
|
+
## 2.0.0.rc2
|
6
|
+
|
7
|
+
- Remove support for Sidekiq < 6.5 (https://github.com/sidekiq-cron/sidekiq-cron/pull/480)
|
8
|
+
- Require at least Fugit >= 1.11.1 (https://github.com/sidekiq-cron/sidekiq-cron/pull/475)
|
9
|
+
- Update how Redis values are stored on save (https://github.com/sidekiq-cron/sidekiq-cron/pull/479)
|
10
|
+
- Web extension: Add compatibility with Sidekiq 7.3+ and remove inline styles (https://github.com/sidekiq-cron/sidekiq-cron/pull/480)
|
11
|
+
- Remove support for old Redis (< 4.2) (https://github.com/sidekiq-cron/sidekiq-cron/pull/490)
|
12
|
+
- Ensure date_as_argument option can be set from true to false in Sidekiq Cron jobs (https://github.com/sidekiq-cron/sidekiq-cron/pull/485)
|
13
|
+
- Rename `enque!` to `enqueue!` (https://github.com/sidekiq-cron/sidekiq-cron/pull/494)
|
14
|
+
- Refactor gem configuration module (https://github.com/sidekiq-cron/sidekiq-cron/pull/495)
|
15
|
+
|
5
16
|
## 2.0.0.rc1
|
6
17
|
|
7
18
|
- Introduce `Namespacing` (https://github.com/sidekiq-cron/sidekiq-cron/pull/268)
|
data/README.md
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
|
9
9
|
🎬 [Introduction video about Sidekiq-Cron by Drifting Ruby](https://www.driftingruby.com/episodes/periodic-tasks-with-sidekiq-cron)
|
10
10
|
|
11
|
-
Sidekiq-Cron runs a thread alongside Sidekiq workers to schedule jobs at specified times (using cron notation `* * * * *`
|
11
|
+
Sidekiq-Cron runs a thread alongside Sidekiq workers to schedule jobs at specified times (using cron notation `* * * * *` or natural language, powered by [Fugit](https://github.com/floraison/fugit)).
|
12
12
|
|
13
13
|
Checks for new jobs to schedule every 30 seconds and doesn't schedule the same job multiple times when more than one Sidekiq process is running.
|
14
14
|
|
@@ -16,10 +16,6 @@ Scheduling jobs are added only when at least one Sidekiq process is running, but
|
|
16
16
|
|
17
17
|
If you want to know how scheduling work, check out [under the hood](#under-the-hood).
|
18
18
|
|
19
|
-
Works with ActiveJob (Rails 4.2+).
|
20
|
-
|
21
|
-
You don't need Sidekiq PRO, you can use this gem with plain Sidekiq.
|
22
|
-
|
23
19
|
## Changelog
|
24
20
|
|
25
21
|
Before upgrading to a new version, please read our [Changelog](CHANGELOG.md).
|
@@ -56,9 +52,9 @@ gem "sidekiq-cron"
|
|
56
52
|
'queue' => 'name of queue',
|
57
53
|
'args' => '[Array or Hash] of arguments which will be passed to perform method',
|
58
54
|
'date_as_argument' => true, # add the time of execution as last argument of the perform method
|
59
|
-
'active_job' => true, # enqueue job through
|
60
|
-
'queue_name_prefix' => 'prefix', #
|
61
|
-
'queue_name_delimiter' => '.', #
|
55
|
+
'active_job' => true, # enqueue job through Active Job interface
|
56
|
+
'queue_name_prefix' => 'prefix', # Active Job queue with prefix
|
57
|
+
'queue_name_delimiter' => '.', # Active Job queue with custom delimiter (default: '_')
|
62
58
|
'description' => 'A sentence describing what work this job performs'
|
63
59
|
'status' => 'disabled' # default: enabled
|
64
60
|
}
|
@@ -66,6 +62,23 @@ gem "sidekiq-cron"
|
|
66
62
|
|
67
63
|
**NOTE** The `status` of a job does not get changed in Redis when a job gets reloaded unless the `status` property is explicitly set.
|
68
64
|
|
65
|
+
### Configuration
|
66
|
+
|
67
|
+
All configuration options:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
Sidekiq::Cron.configure do |config|
|
71
|
+
config.cron_poll_interval = 10
|
72
|
+
config.cron_schedule_file = 'config/my_schedule.yml'
|
73
|
+
config.default_namespace = 'statistics'
|
74
|
+
config.natural_cron_parsing_mode = :single
|
75
|
+
config.reschedule_grace_period = 100
|
76
|
+
config.cron_history_size = 50
|
77
|
+
end
|
78
|
+
```
|
79
|
+
|
80
|
+
If you are using Rails, add them inside an initializer (`config/initializers/sidekiq-cron.rb`).
|
81
|
+
|
69
82
|
### Time, cron and Sidekiq-Cron
|
70
83
|
|
71
84
|
For testing your cron notation you can use [crontab.guru](https://crontab.guru).
|
@@ -79,9 +92,9 @@ like this `'0 22 * * 1-5 America/Chicago'`.
|
|
79
92
|
|
80
93
|
#### Natural-language formats
|
81
94
|
|
82
|
-
Since
|
95
|
+
Since Sidekiq-Cron `v1.7.0`, you can use the natural-language formats supported by Fugit, such as:
|
83
96
|
|
84
|
-
```
|
97
|
+
```ruby
|
85
98
|
"every day at five" # => '0 5 * * *'
|
86
99
|
"every 3 hours" # => '0 */3 * * *'
|
87
100
|
```
|
@@ -122,7 +135,7 @@ Ex. `every day at 3:15 and 4:30`
|
|
122
135
|
|
123
136
|
#### Second-precision (sub-minute) cronlines
|
124
137
|
|
125
|
-
In addition to the standard 5-parameter cronline format,
|
138
|
+
In addition to the standard 5-parameter cronline format, Sidekiq-Cron supports scheduling jobs with second-precision using a modified 6-parameter cronline format:
|
126
139
|
|
127
140
|
`Seconds Minutes Hours Days Months DayOfWeek`
|
128
141
|
|
@@ -131,7 +144,9 @@ For example: `"*/30 * * * * *"` would schedule a job to run every 30 seconds.
|
|
131
144
|
Note that if you plan to schedule jobs with second precision you may need to override the default schedule poll interval so it is lower than the interval of your jobs:
|
132
145
|
|
133
146
|
```ruby
|
134
|
-
Sidekiq::
|
147
|
+
Sidekiq::Cron.configure do |config|
|
148
|
+
config.cron_poll_interval = 10
|
149
|
+
end
|
135
150
|
```
|
136
151
|
|
137
152
|
The default value at time of writing is 30 seconds. See [under the hood](#under-the-hood) for more details.
|
@@ -142,9 +157,7 @@ The default value at time of writing is 30 seconds. See [under the hood](#under-
|
|
142
157
|
|
143
158
|
When not giving a namespace, the `default` one will be used.
|
144
159
|
|
145
|
-
In the case you'd like to change this value,
|
146
|
-
|
147
|
-
`config/initializers/sidekiq-cron.rb`:
|
160
|
+
In the case you'd like to change this value, you can change it via the following configuration flag:
|
148
161
|
|
149
162
|
```ruby
|
150
163
|
Sidekiq::Cron.configure do |config|
|
@@ -222,7 +235,7 @@ class ExampleJob < ActiveJob::Base
|
|
222
235
|
end
|
223
236
|
```
|
224
237
|
|
225
|
-
For Active
|
238
|
+
For Active Job you can use `symbolize_args: true` in `Sidekiq::Cron::Job.create` or in Hash configuration,
|
226
239
|
which will ensure that arguments you are passing to it will be symbolized when passed back to `perform` method in worker.
|
227
240
|
|
228
241
|
### Adding Cron jobs
|
@@ -261,7 +274,7 @@ end
|
|
261
274
|
|
262
275
|
Use ActiveRecord models as arguments:
|
263
276
|
|
264
|
-
```
|
277
|
+
```ruby
|
265
278
|
class Person < ApplicationRecord
|
266
279
|
end
|
267
280
|
|
@@ -325,7 +338,7 @@ Sidekiq::Cron::Job.load_from_array! array
|
|
325
338
|
|
326
339
|
### Loading jobs from schedule file
|
327
340
|
|
328
|
-
You can also load multiple jobs from a YAML
|
341
|
+
You can also load multiple jobs from a YAML file:
|
329
342
|
|
330
343
|
```yaml
|
331
344
|
# config/schedule.yml
|
@@ -346,24 +359,31 @@ second_job:
|
|
346
359
|
There are multiple ways to load the jobs from a YAML file
|
347
360
|
|
348
361
|
1. The gem will automatically load the jobs mentioned in `config/schedule.yml` file (it supports ERB)
|
349
|
-
2. When you want to load jobs from a different filename, mention the filename in
|
362
|
+
2. When you want to load jobs from a different filename, mention the filename in Sidekiq configuration as follows:
|
363
|
+
|
364
|
+
```ruby
|
365
|
+
Sidekiq::Cron.configure do |config|
|
366
|
+
config.cron_schedule_file = "config/users_schedule.yml"
|
367
|
+
end
|
368
|
+
```
|
369
|
+
|
350
370
|
3. Load the file manually as follows:
|
351
371
|
|
352
|
-
```ruby
|
353
|
-
# config/initializers/sidekiq.rb
|
372
|
+
```ruby
|
373
|
+
# config/initializers/sidekiq.rb
|
354
374
|
|
355
|
-
Sidekiq.configure_server do |config|
|
356
|
-
|
357
|
-
|
375
|
+
Sidekiq.configure_server do |config|
|
376
|
+
config.on(:startup) do
|
377
|
+
schedule_file = "config/users_schedule.yml"
|
358
378
|
|
359
|
-
|
360
|
-
|
379
|
+
if File.exist?(schedule_file)
|
380
|
+
schedule = YAML.load_file(schedule_file)
|
361
381
|
|
362
|
-
|
382
|
+
Sidekiq::Cron::Job.load_from_hash!(schedule, source: "schedule")
|
383
|
+
end
|
384
|
+
end
|
363
385
|
end
|
364
|
-
|
365
|
-
end
|
366
|
-
```
|
386
|
+
```
|
367
387
|
|
368
388
|
### Finding jobs
|
369
389
|
|
@@ -409,7 +429,7 @@ job.status
|
|
409
429
|
# => enabled/disabled
|
410
430
|
|
411
431
|
# enqueue job right now!
|
412
|
-
job.
|
432
|
+
job.enqueue!
|
413
433
|
```
|
414
434
|
|
415
435
|
### Schedule vs Dynamic jobs
|
@@ -448,14 +468,14 @@ Sidekiq-Cron adds itself into this start procedure and starts another thread wit
|
|
448
468
|
Sidekiq-Cron is checking jobs to be enqueued every 30s by default, you can change it by setting:
|
449
469
|
|
450
470
|
```ruby
|
451
|
-
Sidekiq::
|
471
|
+
Sidekiq::Cron.configure do |config|
|
472
|
+
config.cron_poll_interval = 10
|
473
|
+
end
|
452
474
|
```
|
453
475
|
|
454
|
-
When
|
476
|
+
When Sidekiq (and Sidekiq-Cron) is not used in zero-downtime deployments, after the deployment is done Sidekiq-Cron starts to catch up. It will consider older jobs that missed their schedules during that time. By default, only jobs that should have started less than 1 minute ago are considered. This is problematic for some jobs, e.g., jobs that run once a day. If on average Sidekiq is shut down for 10 minutes during deployments, you can configure Sidekiq-Cron to consider jobs that were about to be scheduled during that time:
|
455
477
|
|
456
478
|
```ruby
|
457
|
-
# config/initializers/sidekiq-cron.rb
|
458
|
-
|
459
479
|
Sidekiq::Cron.configure do |config|
|
460
480
|
config.reschedule_grace_period = 600 # 10 minutes in seconds
|
461
481
|
end
|
@@ -463,7 +483,13 @@ end
|
|
463
483
|
|
464
484
|
Sidekiq-Cron is safe to use with multiple Sidekiq processes or nodes. It uses a Redis sorted set to determine that only the first process who asks can enqueue scheduled jobs into the queue.
|
465
485
|
|
466
|
-
When running with many Sidekiq processes, the polling can add significant load to Redis. You can disable polling on some processes by setting
|
486
|
+
When running with many Sidekiq processes, the polling can add significant load to Redis. You can disable polling on some processes by setting:
|
487
|
+
|
488
|
+
```ruby
|
489
|
+
Sidekiq::Cron.configure do |config|
|
490
|
+
config.cron_poll_interval = 0
|
491
|
+
end
|
492
|
+
```
|
467
493
|
|
468
494
|
## Contributing
|
469
495
|
|
@@ -487,21 +513,21 @@ $ bundle exec rake test
|
|
487
513
|
|
488
514
|
### Using Docker
|
489
515
|
|
490
|
-
[Docker](https://www.docker.com) allows you to run things in containers easing the development process.
|
491
|
-
|
492
516
|
This project uses [Docker Compose](https://docs.docker.com/compose/) in order to orchestrate containers and get the test suite running on you local machine, and here you find the commands to run in order to get a complete environment to build and test this gem:
|
493
517
|
|
494
518
|
1. Build the Docker image (only the first time):
|
495
519
|
```
|
496
520
|
docker compose -f docker/docker-compose.yml build
|
497
521
|
```
|
522
|
+
|
498
523
|
2. Run the test suite:
|
499
524
|
```
|
500
525
|
docker compose -f docker/docker-compose.yml run --rm tests
|
501
526
|
```
|
527
|
+
|
502
528
|
_This command will download the first time the project's dependencies (Redis so far), create the containers and run the default command to run the tests._
|
503
529
|
|
504
|
-
|
530
|
+
**Running other commands**
|
505
531
|
|
506
532
|
In the case you need to run a command in the gem's container, you would do it like so:
|
507
533
|
|
@@ -510,7 +536,7 @@ docker compose -f docker/docker-compose.yml run --rm tests <HERE IS YOUR COMMAND
|
|
510
536
|
```
|
511
537
|
_Note that `tests` is the Docker Compose service name defined in the `docker/docker-compose.yml` file._
|
512
538
|
|
513
|
-
|
539
|
+
**Running a single test file**
|
514
540
|
|
515
541
|
Given you only want to run the tests from the `test/unit/web_extension_test.rb` file, you need to pass its path with the `TEST` env variable, so here is the command:
|
516
542
|
|
data/lib/sidekiq/cron/job.rb
CHANGED
@@ -3,9 +3,7 @@
|
|
3
3
|
require 'fugit'
|
4
4
|
require 'cronex'
|
5
5
|
require 'globalid'
|
6
|
-
require 'sidekiq'
|
7
6
|
require 'sidekiq/cron/support'
|
8
|
-
require 'sidekiq/options'
|
9
7
|
|
10
8
|
module Sidekiq
|
11
9
|
module Cron
|
@@ -16,9 +14,6 @@ module Sidekiq
|
|
16
14
|
# Time format for enqueued jobs.
|
17
15
|
LAST_ENQUEUE_TIME_FORMAT = '%Y-%m-%d %H:%M:%S %z'
|
18
16
|
|
19
|
-
# Use the exists? method if we're on a newer version of Redis.
|
20
|
-
REDIS_EXISTS_METHOD = Gem::Version.new(Sidekiq::VERSION) >= Gem::Version.new("7.0.0") || Gem.loaded_specs['redis'].version < Gem::Version.new('4.2') ? :exists : :exists?
|
21
|
-
|
22
17
|
# Use serialize/deserialize key of GlobalID.
|
23
18
|
GLOBALID_KEY = "_sc_globalid"
|
24
19
|
|
@@ -92,7 +87,7 @@ module Sidekiq
|
|
92
87
|
end
|
93
88
|
|
94
89
|
# Crucial part of whole enqueuing job.
|
95
|
-
def
|
90
|
+
def should_enqueue? time
|
96
91
|
return false unless status == "enabled"
|
97
92
|
return false if past_scheduled_time?(time)
|
98
93
|
return false if enqueued_after?(time)
|
@@ -105,23 +100,23 @@ module Sidekiq
|
|
105
100
|
|
106
101
|
# Remove previous information about run times,
|
107
102
|
# this will clear Redis and make sure that Redis will not overflow with memory.
|
108
|
-
def
|
103
|
+
def remove_previous_enqueues time
|
109
104
|
Sidekiq.redis do |conn|
|
110
105
|
conn.zremrangebyscore(job_enqueued_key, 0, "(#{(time.to_f - REMEMBER_THRESHOLD).to_s}")
|
111
106
|
end
|
112
107
|
end
|
113
108
|
|
114
109
|
# Test if job should be enqueued.
|
115
|
-
def
|
116
|
-
if
|
117
|
-
|
110
|
+
def test_and_enqueue_for_time! time
|
111
|
+
if should_enqueue?(time)
|
112
|
+
enqueue!
|
118
113
|
|
119
|
-
|
114
|
+
remove_previous_enqueues(time)
|
120
115
|
end
|
121
116
|
end
|
122
117
|
|
123
118
|
# Enqueue cron job to queue.
|
124
|
-
def
|
119
|
+
def enqueue! time = Time.now.utc
|
125
120
|
@last_enqueue_time = time
|
126
121
|
|
127
122
|
klass_const =
|
@@ -413,7 +408,7 @@ module Sidekiq
|
|
413
408
|
|
414
409
|
# Export job data to hash.
|
415
410
|
def to_hash
|
416
|
-
|
411
|
+
{
|
417
412
|
name: @name,
|
418
413
|
namespace: @namespace,
|
419
414
|
klass: @klass.to_s,
|
@@ -421,6 +416,7 @@ module Sidekiq
|
|
421
416
|
description: @description,
|
422
417
|
source: @source,
|
423
418
|
args: @args.is_a?(String) ? @args : Sidekiq.dump_json(@args || []),
|
419
|
+
date_as_argument: date_as_argument? ? "1" : "0",
|
424
420
|
message: @message.is_a?(String) ? @message : Sidekiq.dump_json(@message || {}),
|
425
421
|
status: @status,
|
426
422
|
active_job: @active_job ? "1" : "0",
|
@@ -429,12 +425,6 @@ module Sidekiq
|
|
429
425
|
last_enqueue_time: serialized_last_enqueue_time,
|
430
426
|
symbolize_args: symbolize_args? ? "1" : "0",
|
431
427
|
}
|
432
|
-
|
433
|
-
if date_as_argument?
|
434
|
-
hash.merge!(date_as_argument: "1")
|
435
|
-
end
|
436
|
-
|
437
|
-
hash
|
438
428
|
end
|
439
429
|
|
440
430
|
def errors
|
@@ -447,6 +437,7 @@ module Sidekiq
|
|
447
437
|
|
448
438
|
errors << "'name' must be set" if @name.nil? || @name.size == 0
|
449
439
|
errors << "'namespace' must be set" if @namespace.nil? || @namespace.size == 0
|
440
|
+
errors << "'namespace' cannot be '*'" if @namespace == "*"
|
450
441
|
|
451
442
|
if @cron.nil? || @cron.size == 0
|
452
443
|
errors << "'cron' must be set"
|
@@ -482,14 +473,19 @@ module Sidekiq
|
|
482
473
|
conn.sadd self.class.jobs_key(@namespace), [redis_key]
|
483
474
|
|
484
475
|
# Add information for this job!
|
485
|
-
conn.hset redis_key, to_hash.transform_values! { |v| v || '' }
|
476
|
+
conn.hset redis_key, to_hash.transform_values! { |v| v || '' }.flatten
|
486
477
|
|
487
|
-
# Add information about last time! - don't
|
478
|
+
# Add information about last time! - don't enqueue right after scheduler poller starts!
|
488
479
|
time = Time.now.utc
|
489
|
-
exists = conn.
|
490
|
-
|
480
|
+
exists = conn.exists(job_enqueued_key)
|
481
|
+
|
482
|
+
unless exists == true || exists == 1
|
483
|
+
conn.zadd(job_enqueued_key, time.to_f.to_s, formatted_last_time(time).to_s)
|
484
|
+
Sidekiq.logger.info { "Cron Jobs - added job with name #{@name} in the namespace #{@namespace}" }
|
485
|
+
end
|
491
486
|
end
|
492
|
-
|
487
|
+
|
488
|
+
true
|
493
489
|
end
|
494
490
|
|
495
491
|
def save_last_enqueue_time
|
@@ -505,7 +501,7 @@ module Sidekiq
|
|
505
501
|
enqueued: @last_enqueue_time
|
506
502
|
}
|
507
503
|
|
508
|
-
@history_size ||=
|
504
|
+
@history_size ||= Sidekiq::Cron.configuration.cron_history_size.to_i - 1
|
509
505
|
Sidekiq.redis do |conn|
|
510
506
|
conn.lpush jid_history_key,
|
511
507
|
Sidekiq.dump_json(jid_history)
|
@@ -572,7 +568,7 @@ module Sidekiq
|
|
572
568
|
|
573
569
|
def self.exists?(name, namespace = Sidekiq::Cron.configuration.default_namespace)
|
574
570
|
out = Sidekiq.redis do |conn|
|
575
|
-
conn.
|
571
|
+
conn.exists(redis_key(name, namespace))
|
576
572
|
end
|
577
573
|
|
578
574
|
[true, 1].include?(out)
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'sidekiq/cron/poller'
|
2
|
-
|
3
1
|
# For Cron we need to add some methods to Launcher
|
4
2
|
# so look at the code below.
|
5
3
|
#
|
@@ -8,14 +6,13 @@ require 'sidekiq/cron/poller'
|
|
8
6
|
module Sidekiq
|
9
7
|
module Cron
|
10
8
|
module Launcher
|
11
|
-
DEFAULT_POLL_INTERVAL = 30
|
12
9
|
|
13
10
|
# Add cron poller to launcher.
|
14
11
|
attr_reader :cron_poller
|
15
12
|
|
16
13
|
# Add cron poller and execute normal initialize of Sidekiq launcher.
|
17
14
|
def initialize(config, **kwargs)
|
18
|
-
config[:cron_poll_interval] =
|
15
|
+
config[:cron_poll_interval] = Sidekiq::Cron.configuration.cron_poll_interval.to_i
|
19
16
|
|
20
17
|
@cron_poller = Sidekiq::Cron::Poller.new(config) if config[:cron_poll_interval] > 0
|
21
18
|
super
|
data/lib/sidekiq/cron/poller.rb
CHANGED
@@ -1,20 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'sidekiq'
|
4
|
-
require 'sidekiq/cron'
|
5
3
|
require 'sidekiq/scheduled'
|
6
|
-
require 'sidekiq/options'
|
7
4
|
|
8
5
|
module Sidekiq
|
9
6
|
module Cron
|
10
7
|
# The Poller checks Redis every N seconds for scheduled cron jobs.
|
11
8
|
class Poller < Sidekiq::Scheduled::Poller
|
12
9
|
def initialize(config = nil)
|
13
|
-
if Gem::Version.new(Sidekiq::VERSION) < Gem::Version.new('6.5.0')
|
14
|
-
# Old version of Sidekiq does not accept a config argument.
|
15
|
-
@config = config
|
16
|
-
end
|
17
|
-
|
18
10
|
super
|
19
11
|
end
|
20
12
|
|
@@ -40,7 +32,7 @@ module Sidekiq
|
|
40
32
|
private
|
41
33
|
|
42
34
|
def enqueue_job(job, time = Time.now.utc)
|
43
|
-
job.
|
35
|
+
job.test_and_enqueue_for_time! time if job && job.valid?
|
44
36
|
rescue => ex
|
45
37
|
# Problem somewhere in one job.
|
46
38
|
Sidekiq.logger.error "CRON JOB: #{ex.message}"
|
@@ -1,9 +1,5 @@
|
|
1
|
-
require 'sidekiq'
|
2
|
-
require 'sidekiq/cron/job'
|
3
|
-
require 'sidekiq/options'
|
4
|
-
|
5
1
|
Sidekiq.configure_server do |config|
|
6
|
-
schedule_file = Sidekiq::
|
2
|
+
schedule_file = Sidekiq::Cron.configuration.cron_schedule_file
|
7
3
|
|
8
4
|
if File.exist?(schedule_file)
|
9
5
|
config.on(:startup) do
|
data/lib/sidekiq/cron/support.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
|
-
# https://github.com/rails/rails/blob/352865d0f835c24daa9a2e9863dcc9dde9e5371a/activesupport/lib/active_support/inflector/methods.rb#L270
|
2
|
-
|
3
1
|
module Sidekiq
|
4
2
|
module Cron
|
5
3
|
module Support
|
4
|
+
# Inspired by Active Support Inflector
|
6
5
|
def self.constantize(camel_cased_word)
|
7
6
|
names = camel_cased_word.split("::".freeze)
|
8
7
|
|
data/lib/sidekiq/cron/version.rb
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
<small><%= @current_namespace %></small>
|
6
6
|
</h3>
|
7
7
|
</div>
|
8
|
-
<div class='col-sm-7 pull-right'
|
8
|
+
<div class='col-sm-7 pull-right h2'>
|
9
9
|
<% if @cron_jobs.size > 0 %>
|
10
10
|
<form action="<%= root_path %>cron/namespaces/<%= @current_namespace %>/all/delete" method="post" class="pull-right">
|
11
11
|
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
@@ -31,7 +31,7 @@
|
|
31
31
|
<div class='row'>
|
32
32
|
<div class="col-sm-12 summary_bar">
|
33
33
|
<ul class="list-unstyled summary row">
|
34
|
-
<% @namespaces.sort_by { |namespace| namespace[:name] }
|
34
|
+
<% @namespaces.sort_by { |namespace| namespace[:name] }.each do |namespace| %>
|
35
35
|
<li class="col-sm-1">
|
36
36
|
<a href="<%= root_path %>cron/namespaces/<%= namespace[:name] %>">
|
37
37
|
<span class="count"><%= namespace[:count] %></span>
|
@@ -47,63 +47,59 @@
|
|
47
47
|
<% if @cron_jobs.size > 0 %>
|
48
48
|
<table class="table table-hover table-bordered table-striped table-white">
|
49
49
|
<thead>
|
50
|
+
<tr>
|
50
51
|
<th><%= t('Status') %></th>
|
51
|
-
<th><%= t('Name') %></th>
|
52
|
+
<th width="50%"><%= t('Name') %></th>
|
52
53
|
<th><%= t('Cron string') %></th>
|
53
54
|
<th><%= t('Last enqueued') %></th>
|
54
|
-
<th width="180"><%= t('Actions')%></th>
|
55
|
+
<th width="180"><%= t('Actions') %></th>
|
56
|
+
</tr>
|
55
57
|
</thead>
|
56
58
|
|
57
59
|
<tbody>
|
58
|
-
<% @cron_jobs.sort{|a,b| a.sort_name <=> b.sort_name }.
|
59
|
-
<%
|
60
|
+
<% @cron_jobs.sort{ |a,b| a.sort_name <=> b.sort_name }.each do |job| %>
|
61
|
+
<% klass = (job.status == 'disabled') ? 'bg-danger text-muted' : '' %>
|
62
|
+
<% escaped_job_name = CGI.escape(job.name).gsub('+', '%20') %>
|
60
63
|
<tr>
|
61
|
-
<td
|
62
|
-
<td
|
63
|
-
<a href="<%= root_path %>cron/namespaces/<%=
|
64
|
-
<b
|
64
|
+
<td class="<%= klass %>"><%= t job.status %></td>
|
65
|
+
<td class="<%= klass %>">
|
66
|
+
<a href="<%= root_path %>cron/namespaces/<%= job.namespace %>/jobs/<%= escaped_job_name %>" title="<%= job.description %>">
|
67
|
+
<b class="<%= klass %>"><%= job.name %></b>
|
65
68
|
</a>
|
66
|
-
<
|
67
|
-
<small>
|
69
|
+
<br/>
|
68
70
|
<% if job.message and job.message.to_s.size > 100 %>
|
69
|
-
|
70
|
-
<
|
71
|
-
<
|
72
|
-
|
73
|
-
<% else %>
|
74
|
-
<button data-toggle="collapse" data-target=".worker_<%= index %>" class="btn btn-warn btn-xs"><%= t('ShowAll')%></button>
|
75
|
-
<div class="toggle worker_<%= index %>" style="display: inline;"><%= job.message[0..100] + "... " %></div>
|
76
|
-
<div class="toggle worker_<%= index %>" style="display: none;"><%= job.message %></div>
|
77
|
-
<% end %>
|
71
|
+
<details>
|
72
|
+
<summary class="btn btn-warn btn-xs">Show message</summary>
|
73
|
+
<p><small><%= job.message %></small></p>
|
74
|
+
</details>
|
78
75
|
<% else %>
|
79
|
-
|
76
|
+
<small><%= job.message %></small>
|
80
77
|
<% end %>
|
81
|
-
</small>
|
82
78
|
</td>
|
83
|
-
<td
|
84
|
-
<td
|
85
|
-
<td
|
79
|
+
<td class="<%= klass %>"><b><%= job.human_cron %><br/><small><%= job.cron.gsub(" ", " ") %></small></b></td>
|
80
|
+
<td class="<%= klass %>"><%= job.last_enqueue_time ? relative_time(job.last_enqueue_time) : "-" %></td>
|
81
|
+
<td class="<%= klass %>">
|
86
82
|
<% if job.status == 'enabled' %>
|
87
|
-
<form action="<%= root_path %>cron/namespaces/<%=
|
83
|
+
<form action="<%= root_path %>cron/namespaces/<%= job.namespace %>/jobs/<%= escaped_job_name %>/enque" method="post">
|
88
84
|
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
89
85
|
<input class='btn btn-warn btn-xs pull-left' type="submit" name="enque" value="<%= t('EnqueueNow') %>" data-confirm="<%= t('AreYouSureEnqueueCronJob', :job => job.name) %>"/>
|
90
86
|
</form>
|
91
|
-
<form action="<%= root_path %>cron/namespaces/<%=
|
87
|
+
<form action="<%= root_path %>cron/namespaces/<%= job.namespace %>/jobs/<%= escaped_job_name %>/disable" method="post">
|
92
88
|
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
93
89
|
<input class='btn btn-warn btn-xs pull-left' type="submit" name="disable" value="<%= t('Disable') %>"/>
|
94
90
|
</form>
|
95
91
|
<% else %>
|
96
|
-
<form action="<%= root_path %>cron/namespaces/<%=
|
92
|
+
<form action="<%= root_path %>cron/namespaces/<%= job.namespace %>/jobs/<%= escaped_job_name %>/enque" method="post">
|
97
93
|
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
98
|
-
<input class='btn btn-warn btn-xs pull-left' type="submit" name="enque" value="<%= t('EnqueueNow') %>"/>
|
94
|
+
<input class='btn btn-warn btn-xs pull-left' type="submit" name="enque" value="<%= t('EnqueueNow') %>" data-confirm="<%= t('AreYouSureEnqueueCronJob', :job => job.name) %>"/>
|
99
95
|
</form>
|
100
|
-
<form action="<%= root_path %>cron/namespaces/<%=
|
96
|
+
<form action="<%= root_path %>cron/namespaces/<%= job.namespace %>/jobs/<%= escaped_job_name %>/enable" method="post">
|
101
97
|
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
102
98
|
<input class='btn btn-warn btn-xs pull-left' type="submit" name="enable" value="<%= t('Enable') %>"/>
|
103
99
|
</form>
|
104
|
-
<form action="<%= root_path %>cron/namespaces/<%=
|
100
|
+
<form action="<%= root_path %>cron/namespaces/<%= job.namespace %>/jobs/<%= escaped_job_name %>/delete" method="post">
|
105
101
|
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
106
|
-
<input class='btn btn-xs btn-danger pull-left' type="submit" name="delete" value="<%= t('Delete') %>" data-confirm="<%= t('AreYouSureDeleteCronJob', :job => job.name) %>"/>
|
102
|
+
<input class='btn btn-xs btn-danger pull-left help-block' type="submit" name="delete" value="<%= t('Delete') %>" data-confirm="<%= t('AreYouSureDeleteCronJob', :job => job.name) %>"/>
|
107
103
|
</form>
|
108
104
|
<% end %>
|
109
105
|
</td>
|
@@ -5,25 +5,25 @@
|
|
5
5
|
<small><%= @job.name %></small>
|
6
6
|
</h3>
|
7
7
|
</div>
|
8
|
-
<div class="span col-sm-7 pull-right
|
8
|
+
<div class="span col-sm-7 pull-right h2">
|
9
9
|
<% cron_job_path = "#{root_path}cron/namespaces/#{@current_namespace}/jobs/#{CGI.escape(@job.name).gsub('+', '%20')}" %>
|
10
10
|
<form action="<%= cron_job_path %>/enque?redirect=<%= cron_job_path %>" class="pull-right" method="post">
|
11
11
|
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
12
12
|
<input class="btn btn-warn pull-left" name="enque" type="submit" value="<%= t('EnqueueNow') %>" data-confirm="<%= t('AreYouSureEnqueueCronJob', :job => @job.name) %>" />
|
13
13
|
</form>
|
14
14
|
<% if @job.status == 'enabled' %>
|
15
|
-
<form action="<%= cron_job_path %>/disable?redirect=<%= cron_job_path %>" method="post">
|
15
|
+
<form action="<%= cron_job_path %>/disable?redirect=<%= cron_job_path %>" class="pull-right" method="post">
|
16
16
|
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
17
17
|
<input class="btn btn-warn pull-left" name="disable" type="submit" value="<%= t('Disable') %>" />
|
18
18
|
</form>
|
19
19
|
<% else %>
|
20
|
-
<form action="<%= cron_job_path %>/enable?redirect=<%= cron_job_path %>" method="post">
|
20
|
+
<form action="<%= cron_job_path %>/enable?redirect=<%= cron_job_path %>" class="pull-right" method="post">
|
21
21
|
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
22
22
|
<input class="btn btn-warn pull-left" name="enable" type="submit" value="<%= t('Enable') %>" />
|
23
23
|
</form>
|
24
|
-
<form action="<%= cron_job_path %>/delete" method="post">
|
24
|
+
<form action="<%= cron_job_path %>/delete" class="pull-right" method="post">
|
25
25
|
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
26
|
-
<input class="btn btn-danger" data-confirm="<%= t('AreYouSureDeleteCronJob', :job => @job.name) %>" name="delete" type="submit" value="<%= t('Delete') %>" />
|
26
|
+
<input class="btn btn-danger pull-left" data-confirm="<%= t('AreYouSureDeleteCronJob', :job => @job.name) %>" name="delete" type="submit" value="<%= t('Delete') %>" />
|
27
27
|
</form>
|
28
28
|
<% end %>
|
29
29
|
</div>
|
data/lib/sidekiq/cron/web.rb
CHANGED
@@ -1,7 +1,17 @@
|
|
1
1
|
require "sidekiq/cron/web_extension"
|
2
2
|
require "sidekiq/cron/job"
|
3
|
+
require "sidekiq/cron/namespace"
|
3
4
|
|
4
5
|
if defined?(Sidekiq::Web)
|
5
|
-
|
6
|
-
|
6
|
+
if Gem::Version.new(Sidekiq::VERSION) >= Gem::Version.new('7.3.0')
|
7
|
+
Sidekiq::Web.register(
|
8
|
+
Sidekiq::Cron::WebExtension, # Class which contains the HTTP actions, required
|
9
|
+
name: "cron", # the name of the extension, used to namespace assets
|
10
|
+
tab: "Cron", # labels(s) of the UI tabs
|
11
|
+
index: "cron", # index route(s) for each tab
|
12
|
+
)
|
13
|
+
else
|
14
|
+
Sidekiq::Web.register Sidekiq::Cron::WebExtension
|
15
|
+
Sidekiq::Web.tabs["Cron"] = "cron"
|
16
|
+
end
|
7
17
|
end
|
@@ -4,6 +4,13 @@ module Sidekiq
|
|
4
4
|
def self.registered(app)
|
5
5
|
app.settings.locales << File.join(File.expand_path("..", __FILE__), "locales")
|
6
6
|
|
7
|
+
app.helpers do
|
8
|
+
# This method constructs the URL for the cron jobs page within the specified namespace.
|
9
|
+
def namespace_redirect_path
|
10
|
+
"#{root_path}cron/namespaces/#{route_params[:namespace]}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
7
14
|
# Index page of cron jobs.
|
8
15
|
app.get '/cron' do
|
9
16
|
view_path = File.join(File.expand_path("..", __FILE__), "views")
|
@@ -44,28 +51,28 @@ module Sidekiq
|
|
44
51
|
if @job
|
45
52
|
render(:erb, File.read(File.join(view_path, "cron_show.erb")))
|
46
53
|
else
|
47
|
-
redirect
|
54
|
+
redirect namespace_redirect_path
|
48
55
|
end
|
49
56
|
end
|
50
57
|
|
51
|
-
#
|
58
|
+
# Enqueue all cron jobs.
|
52
59
|
app.post '/cron/namespaces/:namespace/all/enque' do
|
53
|
-
Sidekiq::Cron::Job.all(route_params[:namespace]).each(&:
|
54
|
-
redirect params['redirect'] ||
|
60
|
+
Sidekiq::Cron::Job.all(route_params[:namespace]).each(&:enqueue!)
|
61
|
+
redirect params['redirect'] || namespace_redirect_path
|
55
62
|
end
|
56
63
|
|
57
64
|
# Enqueue cron job.
|
58
65
|
app.post '/cron/namespaces/:namespace/jobs/:name/enque' do
|
59
66
|
if job = Sidekiq::Cron::Job.find(route_params[:name], route_params[:namespace])
|
60
|
-
job.
|
67
|
+
job.enqueue!
|
61
68
|
end
|
62
|
-
redirect params['redirect'] ||
|
69
|
+
redirect params['redirect'] || namespace_redirect_path
|
63
70
|
end
|
64
71
|
|
65
72
|
# Delete all schedules.
|
66
73
|
app.post '/cron/namespaces/:namespace/all/delete' do
|
67
74
|
Sidekiq::Cron::Job.all(route_params[:namespace]).each(&:destroy)
|
68
|
-
redirect
|
75
|
+
redirect params['redirect'] || namespace_redirect_path
|
69
76
|
end
|
70
77
|
|
71
78
|
# Delete schedule.
|
@@ -73,13 +80,13 @@ module Sidekiq
|
|
73
80
|
if job = Sidekiq::Cron::Job.find(route_params[:name], route_params[:namespace])
|
74
81
|
job.destroy
|
75
82
|
end
|
76
|
-
redirect
|
83
|
+
redirect params['redirect'] || namespace_redirect_path
|
77
84
|
end
|
78
85
|
|
79
86
|
# Enable all jobs.
|
80
87
|
app.post '/cron/namespaces/:namespace/all/enable' do
|
81
88
|
Sidekiq::Cron::Job.all(route_params[:namespace]).each(&:enable!)
|
82
|
-
redirect params['redirect'] ||
|
89
|
+
redirect params['redirect'] || namespace_redirect_path
|
83
90
|
end
|
84
91
|
|
85
92
|
# Enable job.
|
@@ -87,13 +94,13 @@ module Sidekiq
|
|
87
94
|
if job = Sidekiq::Cron::Job.find(route_params[:name], route_params[:namespace])
|
88
95
|
job.enable!
|
89
96
|
end
|
90
|
-
redirect params['redirect'] ||
|
97
|
+
redirect params['redirect'] || namespace_redirect_path
|
91
98
|
end
|
92
99
|
|
93
100
|
# Disable all jobs.
|
94
101
|
app.post '/cron/namespaces/:namespace/all/disable' do
|
95
102
|
Sidekiq::Cron::Job.all(route_params[:namespace]).each(&:disable!)
|
96
|
-
redirect params['redirect'] ||
|
103
|
+
redirect params['redirect'] || namespace_redirect_path
|
97
104
|
end
|
98
105
|
|
99
106
|
# Disable job.
|
@@ -101,7 +108,7 @@ module Sidekiq
|
|
101
108
|
if job = Sidekiq::Cron::Job.find(route_params[:name], route_params[:namespace])
|
102
109
|
job.disable!
|
103
110
|
end
|
104
|
-
redirect params['redirect'] ||
|
111
|
+
redirect params['redirect'] || namespace_redirect_path
|
105
112
|
end
|
106
113
|
end
|
107
114
|
end
|
data/lib/sidekiq/cron.rb
CHANGED
@@ -1,9 +1,3 @@
|
|
1
|
-
require "sidekiq/cron/job"
|
2
|
-
require "sidekiq/cron/namespace"
|
3
|
-
require "sidekiq/cron/poller"
|
4
|
-
require "sidekiq/cron/launcher"
|
5
|
-
require "sidekiq/cron/schedule_loader"
|
6
|
-
|
7
1
|
module Sidekiq
|
8
2
|
module Cron
|
9
3
|
class << self
|
@@ -15,6 +9,10 @@ module Sidekiq
|
|
15
9
|
yield(configuration) if block_given?
|
16
10
|
end
|
17
11
|
|
12
|
+
def self.reset!
|
13
|
+
self.configuration = Configuration.new
|
14
|
+
end
|
15
|
+
|
18
16
|
class Configuration
|
19
17
|
# The default namespace is used when no namespace is specified.
|
20
18
|
attr_accessor :default_namespace
|
@@ -33,10 +31,24 @@ module Sidekiq
|
|
33
31
|
# jobs that missed their schedules during the deployment. E.g., jobs that run once a day.
|
34
32
|
attr_accessor :reschedule_grace_period
|
35
33
|
|
34
|
+
# The maximum number of recent cron job execution histories to retain.
|
35
|
+
# This value controls how many past job executions are stored.
|
36
|
+
attr_accessor :cron_history_size
|
37
|
+
|
38
|
+
# The interval, in seconds, at which to poll for scheduled cron jobs.
|
39
|
+
# This determines how frequently the scheduler checks for jobs to enqueue.
|
40
|
+
attr_accessor :cron_poll_interval
|
41
|
+
|
42
|
+
# The path to a YAML file containing multiple cron job schedules.
|
43
|
+
attr_accessor :cron_schedule_file
|
44
|
+
|
36
45
|
def initialize
|
37
46
|
@default_namespace = 'default'
|
38
47
|
@natural_cron_parsing_mode = :single
|
39
48
|
@reschedule_grace_period = 60
|
49
|
+
@cron_history_size = 10
|
50
|
+
@cron_poll_interval = 30
|
51
|
+
@cron_schedule_file = 'config/schedule.yml'
|
40
52
|
end
|
41
53
|
|
42
54
|
def natural_cron_parsing_mode=(mode)
|
data/lib/sidekiq/options.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# Module to access Sidekiq config
|
3
2
|
module Sidekiq
|
4
3
|
module Options
|
5
4
|
def self.[](key)
|
@@ -16,13 +15,12 @@ module Sidekiq
|
|
16
15
|
|
17
16
|
def self.options_field
|
18
17
|
return @options_field unless @options_field.nil?
|
18
|
+
|
19
19
|
sidekiq_version = Gem::Version.new(Sidekiq::VERSION)
|
20
20
|
@options_field = if sidekiq_version >= Gem::Version.new('7.0')
|
21
21
|
:default_configuration
|
22
|
-
elsif sidekiq_version >= Gem::Version.new('6.5')
|
23
|
-
false
|
24
22
|
else
|
25
|
-
|
23
|
+
false
|
26
24
|
end
|
27
25
|
end
|
28
26
|
end
|
data/lib/sidekiq-cron.rb
CHANGED
data/sidekiq-cron.gemspec
CHANGED
@@ -27,9 +27,9 @@ Gem::Specification.new do |s|
|
|
27
27
|
s.required_ruby_version = ">= 2.7"
|
28
28
|
|
29
29
|
s.add_dependency("cronex", ">= 0.13.0")
|
30
|
-
s.add_dependency("fugit", "~> 1.8")
|
30
|
+
s.add_dependency("fugit", "~> 1.8", ">= 1.11.1")
|
31
31
|
s.add_dependency("globalid", ">= 1.0.1")
|
32
|
-
s.add_dependency("sidekiq", ">= 6")
|
32
|
+
s.add_dependency("sidekiq", ">= 6.5.0")
|
33
33
|
|
34
34
|
s.add_development_dependency("minitest", "~> 5.15")
|
35
35
|
s.add_development_dependency("mocha", "~> 2.1")
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq-cron
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.
|
4
|
+
version: 2.0.0.rc2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ondrej Bartas
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-10-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cronex
|
@@ -31,6 +31,9 @@ dependencies:
|
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '1.8'
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 1.11.1
|
34
37
|
type: :runtime
|
35
38
|
prerelease: false
|
36
39
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -38,6 +41,9 @@ dependencies:
|
|
38
41
|
- - "~>"
|
39
42
|
- !ruby/object:Gem::Version
|
40
43
|
version: '1.8'
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 1.11.1
|
41
47
|
- !ruby/object:Gem::Dependency
|
42
48
|
name: globalid
|
43
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,14 +64,14 @@ dependencies:
|
|
58
64
|
requirements:
|
59
65
|
- - ">="
|
60
66
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
67
|
+
version: 6.5.0
|
62
68
|
type: :runtime
|
63
69
|
prerelease: false
|
64
70
|
version_requirements: !ruby/object:Gem::Requirement
|
65
71
|
requirements:
|
66
72
|
- - ">="
|
67
73
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
74
|
+
version: 6.5.0
|
69
75
|
- !ruby/object:Gem::Dependency
|
70
76
|
name: minitest
|
71
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -216,11 +222,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
216
222
|
version: '2.7'
|
217
223
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
218
224
|
requirements:
|
219
|
-
- - "
|
225
|
+
- - ">="
|
220
226
|
- !ruby/object:Gem::Version
|
221
|
-
version:
|
227
|
+
version: '0'
|
222
228
|
requirements: []
|
223
|
-
rubygems_version: 3.
|
229
|
+
rubygems_version: 3.5.16
|
224
230
|
signing_key:
|
225
231
|
specification_version: 4
|
226
232
|
summary: Scheduler/Cron for Sidekiq jobs
|