sidekiq-cron 1.10.1 → 1.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -2
- data/README.md +19 -4
- data/lib/sidekiq/cron/job.rb +12 -10
- data/lib/sidekiq/cron/schedule_loader.rb +2 -2
- data/lib/sidekiq/cron/version.rb +1 -1
- data/sidekiq-cron.gemspec +2 -2
- metadata +5 -17
- data/test/integration/performance_test.rb +0 -46
- data/test/models/person.rb +0 -21
- data/test/test_helper.rb +0 -93
- data/test/unit/fixtures/schedule_array.yml +0 -13
- data/test/unit/fixtures/schedule_erb.yml +0 -6
- data/test/unit/fixtures/schedule_hash.yml +0 -12
- data/test/unit/fixtures/schedule_string.yml +0 -1
- data/test/unit/job_test.rb +0 -1386
- data/test/unit/launcher_test.rb +0 -33
- data/test/unit/poller_test.rb +0 -144
- data/test/unit/schedule_loader_test.rb +0 -58
- data/test/unit/web_extension_test.rb +0 -155
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 38f49b844ee1ade391bc47b8acd2e98b02cb9d05041cad364fca427c51d3f65d
|
4
|
+
data.tar.gz: 6328039e5648a59057202fec118775e8e1ed7ffc2d5a38229c62e4c7af7ebfaf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 80d176888e61a86fabac69a160fc778965b7900b8971979158a7e192289874fea61c18072dd6a306f6a3b8e456e68ea74df57a6e9ede9cb5f64d721228757ce5
|
7
|
+
data.tar.gz: 27febbff9109ca10a5bfc7b6e4414f903e9021ca598ef94992b1445dd383f60d8d48f86f3bd0af93d60b6593a4e2adda26308c8cae42aabdcca0803be64005b1
|
data/CHANGELOG.md
CHANGED
@@ -2,9 +2,15 @@
|
|
2
2
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
|
5
|
+
## 1.11.0
|
6
|
+
|
7
|
+
- Differentiates b/w "schedule" vs "dynamic" jobs (https://github.com/sidekiq-cron/sidekiq-cron/pull/431)
|
8
|
+
- Clears scheduled jobs upon schedule load (https://github.com/sidekiq-cron/sidekiq-cron/pull/431)
|
9
|
+
- Reduce gem size by excluding test files (https://github.com/sidekiq-cron/sidekiq-cron/pull/414)
|
10
|
+
|
5
11
|
## 1.10.1
|
6
12
|
|
7
|
-
-
|
13
|
+
- Use `hset` instead of deprecated `hmset` (https://github.com/sidekiq-cron/sidekiq-cron/pull/410)
|
8
14
|
|
9
15
|
## 1.10.0
|
10
16
|
|
@@ -59,7 +65,7 @@ All notable changes to this project will be documented in this file.
|
|
59
65
|
## 1.4.0
|
60
66
|
|
61
67
|
- Fix buttons order in job show view (https://github.com/sidekiq-cron/sidekiq-cron/pull/302)
|
62
|
-
- Dark Mode support in UI (https://github.com/sidekiq-cron/sidekiq-cron/pull/
|
68
|
+
- Dark Mode support in UI (https://github.com/sidekiq-cron/sidekiq-cron/pull/282)
|
63
69
|
- Remove invocation of deprecated Redis functionality (https://github.com/sidekiq-cron/sidekiq-cron/pull/318)
|
64
70
|
- Internal code cleanup (https://github.com/sidekiq-cron/sidekiq-cron/pull/317)
|
65
71
|
- Optimize gem size (https://github.com/sidekiq-cron/sidekiq-cron/pull/322)
|
data/README.md
CHANGED
@@ -42,7 +42,7 @@ gem "sidekiq-cron"
|
|
42
42
|
|
43
43
|
## Getting Started
|
44
44
|
|
45
|
-
|
45
|
+
### Job properties
|
46
46
|
|
47
47
|
```ruby
|
48
48
|
{
|
@@ -51,12 +51,13 @@ gem "sidekiq-cron"
|
|
51
51
|
'cron' => '1 * * * *', # execute at 1 minute of every hour, ex: 12:01, 13:01, 14:01, ...
|
52
52
|
'class' => 'MyClass',
|
53
53
|
# OPTIONAL
|
54
|
+
'source' => 'dynamic', # source of the job, `schedule`/`dynamic` (default: `dynamic`)
|
54
55
|
'queue' => 'name of queue',
|
55
56
|
'args' => '[Array or Hash] of arguments which will be passed to perform method',
|
56
57
|
'date_as_argument' => true, # add the time of execution as last argument of the perform method
|
57
58
|
'active_job' => true, # enqueue job through Rails 4.2+ Active Job interface
|
58
59
|
'queue_name_prefix' => 'prefix', # Rails 4.2+ Active Job queue with prefix
|
59
|
-
'queue_name_delimiter' => '.', # Rails 4.2+ Active Job queue with custom delimiter
|
60
|
+
'queue_name_delimiter' => '.', # Rails 4.2+ Active Job queue with custom delimiter (default: '_')
|
60
61
|
'description' => 'A sentence describing what work this job performs'
|
61
62
|
'status' => 'disabled' # default: enabled
|
62
63
|
}
|
@@ -135,6 +136,8 @@ which will ensure that arguments you are passing to it will be symbolized when p
|
|
135
136
|
|
136
137
|
#### Adding Cron job
|
137
138
|
|
139
|
+
Refer to [Schedule vs Dynamic jobs](#schedule-vs-dynamic-jobs) to understand the difference.
|
140
|
+
|
138
141
|
```ruby
|
139
142
|
class HardWorker
|
140
143
|
include Sidekiq::Worker
|
@@ -223,7 +226,7 @@ array = [
|
|
223
226
|
Sidekiq::Cron::Job.load_from_array array
|
224
227
|
```
|
225
228
|
|
226
|
-
Bang-suffixed methods will remove jobs
|
229
|
+
Bang-suffixed methods will remove jobs where source is `schedule` and are not present in the given hash/array, update jobs that have the same names, and create new ones when the names are previously unknown.
|
227
230
|
|
228
231
|
```ruby
|
229
232
|
Sidekiq::Cron::Job.load_from_hash! hash
|
@@ -262,7 +265,9 @@ Sidekiq.configure_server do |config|
|
|
262
265
|
schedule_file = "config/users_schedule.yml"
|
263
266
|
|
264
267
|
if File.exist?(schedule_file)
|
265
|
-
|
268
|
+
schedule = YAML.load_file(schedule_file)
|
269
|
+
|
270
|
+
Sidekiq::Cron::Job.load_from_hash!(schedule, source: "schedule")
|
266
271
|
end
|
267
272
|
end
|
268
273
|
end
|
@@ -315,6 +320,16 @@ job.status
|
|
315
320
|
job.enque!
|
316
321
|
```
|
317
322
|
|
323
|
+
### Schedule vs Dynamic jobs
|
324
|
+
|
325
|
+
There are two potential job sources: `schedule` and `dynamic`.
|
326
|
+
Jobs associated with schedule files are labeled as `schedule` as their source,
|
327
|
+
whereas jobs created at runtime without the `source=schedule` argument are classified as `dynamic`.
|
328
|
+
|
329
|
+
The key distinction lies in how these jobs are managed.
|
330
|
+
When a schedule is loaded, any stale `schedule` jobs are automatically removed to ensure synchronization within the schedule.
|
331
|
+
The `dynamic` jobs remain unaffected by this process.
|
332
|
+
|
318
333
|
### How to start scheduling?
|
319
334
|
|
320
335
|
Just start Sidekiq workers by running:
|
data/lib/sidekiq/cron/job.rb
CHANGED
@@ -162,19 +162,19 @@ module Sidekiq
|
|
162
162
|
# }
|
163
163
|
# }
|
164
164
|
#
|
165
|
-
def self.load_from_hash
|
165
|
+
def self.load_from_hash(hash, options = {})
|
166
166
|
array = hash.map do |key, job|
|
167
167
|
job['name'] = key
|
168
168
|
job
|
169
169
|
end
|
170
|
-
load_from_array
|
170
|
+
load_from_array(array, options)
|
171
171
|
end
|
172
172
|
|
173
173
|
# Like #load_from_hash.
|
174
174
|
# If exists old jobs in Redis but removed from args, destroy old jobs.
|
175
|
-
def self.load_from_hash!
|
175
|
+
def self.load_from_hash!(hash, options = {})
|
176
176
|
destroy_removed_jobs(hash.keys)
|
177
|
-
load_from_hash(hash)
|
177
|
+
load_from_hash(hash, options)
|
178
178
|
end
|
179
179
|
|
180
180
|
# Load cron jobs from Array.
|
@@ -194,10 +194,10 @@ module Sidekiq
|
|
194
194
|
# }
|
195
195
|
# ]
|
196
196
|
#
|
197
|
-
def self.load_from_array
|
197
|
+
def self.load_from_array(array, options = {})
|
198
198
|
errors = {}
|
199
199
|
array.each do |job_data|
|
200
|
-
job = new(job_data)
|
200
|
+
job = new(job_data.merge(options))
|
201
201
|
errors[job.name] = job.errors unless job.save
|
202
202
|
end
|
203
203
|
errors
|
@@ -205,10 +205,10 @@ module Sidekiq
|
|
205
205
|
|
206
206
|
# Like #load_from_array.
|
207
207
|
# If exists old jobs in Redis but removed from args, destroy old jobs.
|
208
|
-
def self.load_from_array!
|
208
|
+
def self.load_from_array!(array, options = {})
|
209
209
|
job_names = array.map { |job| job["name"] }
|
210
210
|
destroy_removed_jobs(job_names)
|
211
|
-
load_from_array(array)
|
211
|
+
load_from_array(array, options)
|
212
212
|
end
|
213
213
|
|
214
214
|
# Get all cron jobs.
|
@@ -267,7 +267,7 @@ module Sidekiq
|
|
267
267
|
end
|
268
268
|
|
269
269
|
attr_accessor :name, :cron, :description, :klass, :args, :message
|
270
|
-
attr_reader :last_enqueue_time, :fetch_missing_args
|
270
|
+
attr_reader :last_enqueue_time, :fetch_missing_args, :source
|
271
271
|
|
272
272
|
def initialize input_args = {}
|
273
273
|
args = Hash[input_args.map{ |k, v| [k.to_s, v] }]
|
@@ -277,6 +277,7 @@ module Sidekiq
|
|
277
277
|
@name = args["name"]
|
278
278
|
@cron = args["cron"]
|
279
279
|
@description = args["description"] if args["description"]
|
280
|
+
@source = args["source"] == "schedule" ? "schedule" : "dynamic"
|
280
281
|
|
281
282
|
# Get class from klass or class.
|
282
283
|
@klass = args["klass"] || args["class"]
|
@@ -408,6 +409,7 @@ module Sidekiq
|
|
408
409
|
klass: @klass.to_s,
|
409
410
|
cron: @cron,
|
410
411
|
description: @description,
|
412
|
+
source: @source,
|
411
413
|
args: @args.is_a?(String) ? @args : Sidekiq.dump_json(@args || []),
|
412
414
|
message: @message.is_a?(String) ? @message : Sidekiq.dump_json(@message || {}),
|
413
415
|
status: @status,
|
@@ -529,7 +531,7 @@ module Sidekiq
|
|
529
531
|
|
530
532
|
# Remove "removed jobs" between current jobs and new jobs
|
531
533
|
def self.destroy_removed_jobs new_job_names
|
532
|
-
current_job_names = Sidekiq::Cron::Job.all.
|
534
|
+
current_job_names = Sidekiq::Cron::Job.all.filter_map { |j| j.name if j.source == "schedule" }
|
533
535
|
removed_job_names = current_job_names - new_job_names
|
534
536
|
removed_job_names.each { |j| Sidekiq::Cron::Job.destroy(j) }
|
535
537
|
removed_job_names
|
@@ -10,9 +10,9 @@ if Sidekiq.server?
|
|
10
10
|
config.on(:startup) do
|
11
11
|
schedule = Sidekiq::Cron::Support.load_yaml(ERB.new(IO.read(schedule_file)).result)
|
12
12
|
if schedule.kind_of?(Hash)
|
13
|
-
Sidekiq::Cron::Job.load_from_hash! schedule
|
13
|
+
Sidekiq::Cron::Job.load_from_hash!(schedule, source: "schedule")
|
14
14
|
elsif schedule.kind_of?(Array)
|
15
|
-
Sidekiq::Cron::Job.load_from_array! schedule
|
15
|
+
Sidekiq::Cron::Job.load_from_array!(schedule, source: "schedule")
|
16
16
|
else
|
17
17
|
raise "Not supported schedule format. Confirm your #{schedule_file}"
|
18
18
|
end
|
data/lib/sidekiq/cron/version.rb
CHANGED
data/sidekiq-cron.gemspec
CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
|
|
15
15
|
"LICENSE.txt",
|
16
16
|
"README.md"
|
17
17
|
]
|
18
|
-
s.files = Dir.glob('lib/**/*') +
|
18
|
+
s.files = Dir.glob('lib/**/*') + [
|
19
19
|
"CHANGELOG.md",
|
20
20
|
"Gemfile",
|
21
21
|
"LICENSE.txt",
|
@@ -31,7 +31,7 @@ Gem::Specification.new do |s|
|
|
31
31
|
s.add_dependency("globalid", ">= 1.0.1")
|
32
32
|
|
33
33
|
s.add_development_dependency("minitest", "~> 5.15")
|
34
|
-
s.add_development_dependency("mocha", "~> 1
|
34
|
+
s.add_development_dependency("mocha", "~> 2.1")
|
35
35
|
s.add_development_dependency("rack", "~> 2.2")
|
36
36
|
s.add_development_dependency("rack-test", "~> 1.1")
|
37
37
|
s.add_development_dependency("rake", "~> 13.0")
|
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: 1.
|
4
|
+
version: 1.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ondrej Bartas
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-11-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fugit
|
@@ -72,14 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '1
|
75
|
+
version: '2.1'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '1
|
82
|
+
version: '2.1'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rack
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -185,18 +185,6 @@ files:
|
|
185
185
|
- lib/sidekiq/cron/web_extension.rb
|
186
186
|
- lib/sidekiq/options.rb
|
187
187
|
- sidekiq-cron.gemspec
|
188
|
-
- test/integration/performance_test.rb
|
189
|
-
- test/models/person.rb
|
190
|
-
- test/test_helper.rb
|
191
|
-
- test/unit/fixtures/schedule_array.yml
|
192
|
-
- test/unit/fixtures/schedule_erb.yml
|
193
|
-
- test/unit/fixtures/schedule_hash.yml
|
194
|
-
- test/unit/fixtures/schedule_string.yml
|
195
|
-
- test/unit/job_test.rb
|
196
|
-
- test/unit/launcher_test.rb
|
197
|
-
- test/unit/poller_test.rb
|
198
|
-
- test/unit/schedule_loader_test.rb
|
199
|
-
- test/unit/web_extension_test.rb
|
200
188
|
homepage: https://github.com/sidekiq-cron/sidekiq-cron
|
201
189
|
licenses:
|
202
190
|
- MIT
|
@@ -216,7 +204,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
216
204
|
- !ruby/object:Gem::Version
|
217
205
|
version: '0'
|
218
206
|
requirements: []
|
219
|
-
rubygems_version: 3.4.
|
207
|
+
rubygems_version: 3.4.10
|
220
208
|
signing_key:
|
221
209
|
specification_version: 4
|
222
210
|
summary: Scheduler/Cron for Sidekiq jobs
|
@@ -1,46 +0,0 @@
|
|
1
|
-
require './test/test_helper'
|
2
|
-
require 'benchmark'
|
3
|
-
|
4
|
-
describe 'Performance Poller' do
|
5
|
-
JOBS_NUMBER = 10_000
|
6
|
-
MAX_SECONDS = 60
|
7
|
-
|
8
|
-
before do
|
9
|
-
# Clear all previous saved data from Redis.
|
10
|
-
Sidekiq.redis do |conn|
|
11
|
-
conn.flushdb
|
12
|
-
end
|
13
|
-
|
14
|
-
args = {
|
15
|
-
queue: "default",
|
16
|
-
cron: "*/2 * * * *",
|
17
|
-
klass: "CronTestClass"
|
18
|
-
}
|
19
|
-
|
20
|
-
JOBS_NUMBER.times do |i|
|
21
|
-
Sidekiq::Cron::Job.create(args.merge(name: "Test#{i}"))
|
22
|
-
end
|
23
|
-
|
24
|
-
@poller = Sidekiq::Cron::Poller.new(Sidekiq.const_defined?(:Config) ? Sidekiq::Config.new : {})
|
25
|
-
now = Time.now.utc + 3600
|
26
|
-
enqueued_time = Time.new(now.year, now.month, now.day, now.hour, 10, 5)
|
27
|
-
Time.stubs(:now).returns(enqueued_time)
|
28
|
-
end
|
29
|
-
|
30
|
-
it "should enqueue #{JOBS_NUMBER} jobs in less than #{MAX_SECONDS}s" do
|
31
|
-
Sidekiq.redis do |conn|
|
32
|
-
assert_equal 0, conn.llen("queue:default"), 'Queue should be empty'
|
33
|
-
end
|
34
|
-
|
35
|
-
bench = Benchmark.measure {
|
36
|
-
@poller.enqueue
|
37
|
-
}
|
38
|
-
|
39
|
-
Sidekiq.redis do |conn|
|
40
|
-
assert_equal JOBS_NUMBER, conn.llen("queue:default"), 'Queue should be full'
|
41
|
-
end
|
42
|
-
|
43
|
-
puts "Performance test finished in #{bench.real}"
|
44
|
-
assert_operator bench.real, :<, MAX_SECONDS
|
45
|
-
end
|
46
|
-
end
|
data/test/models/person.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
class Person
|
2
|
-
include GlobalID::Identification
|
3
|
-
|
4
|
-
attr_reader :id
|
5
|
-
|
6
|
-
def self.find(id)
|
7
|
-
new(id)
|
8
|
-
end
|
9
|
-
|
10
|
-
def initialize(id)
|
11
|
-
@id = id
|
12
|
-
end
|
13
|
-
|
14
|
-
def to_global_id(options = {})
|
15
|
-
super app: "app"
|
16
|
-
end
|
17
|
-
|
18
|
-
def ==(other_person)
|
19
|
-
other_person.is_a?(Person) && id.to_s == other_person.id.to_s
|
20
|
-
end
|
21
|
-
end
|
data/test/test_helper.rb
DELETED
@@ -1,93 +0,0 @@
|
|
1
|
-
$TESTING = true
|
2
|
-
ENV['RACK_ENV'] = 'test'
|
3
|
-
|
4
|
-
require 'simplecov'
|
5
|
-
|
6
|
-
if ENV['CI']
|
7
|
-
require 'simplecov-cobertura'
|
8
|
-
SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter
|
9
|
-
end
|
10
|
-
|
11
|
-
SimpleCov.start do
|
12
|
-
add_filter "test/"
|
13
|
-
add_group 'Sidekiq-Cron', 'lib/'
|
14
|
-
end
|
15
|
-
|
16
|
-
require "minitest/autorun"
|
17
|
-
require "rack/test"
|
18
|
-
require 'mocha/minitest'
|
19
|
-
require 'sidekiq'
|
20
|
-
require 'sidekiq/web'
|
21
|
-
require "sidekiq/cli"
|
22
|
-
require 'sidekiq-cron'
|
23
|
-
require 'sidekiq/cron/web'
|
24
|
-
|
25
|
-
Sidekiq.logger.level = Logger::ERROR
|
26
|
-
Sidekiq.configure_client do |config|
|
27
|
-
config.redis = { url: ENV['REDIS_URL'] || 'redis://0.0.0.0:6379' }
|
28
|
-
end
|
29
|
-
|
30
|
-
# For testing symbolize args
|
31
|
-
class Hash
|
32
|
-
def symbolize_keys
|
33
|
-
transform_keys { |key| key.to_sym rescue key }
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
class CronTestClass
|
38
|
-
include Sidekiq::Worker
|
39
|
-
sidekiq_options retry: true
|
40
|
-
|
41
|
-
def perform args = {}
|
42
|
-
puts "super croned job #{args}"
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
class CronTestClassWithQueue
|
47
|
-
include Sidekiq::Worker
|
48
|
-
sidekiq_options queue: :super, retry: false, backtrace: true
|
49
|
-
|
50
|
-
def perform args = {}
|
51
|
-
puts "super croned job #{args}"
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
module ActiveJob
|
56
|
-
class Base
|
57
|
-
attr_accessor *%i[job_class provider_job_id queue_name arguments]
|
58
|
-
|
59
|
-
def initialize
|
60
|
-
yield self if block_given?
|
61
|
-
self.provider_job_id ||= SecureRandom.hex(12)
|
62
|
-
end
|
63
|
-
|
64
|
-
def self.queue_name_prefix
|
65
|
-
@queue_name_prefix
|
66
|
-
end
|
67
|
-
|
68
|
-
def self.queue_name_prefix=(queue_name_prefix)
|
69
|
-
@queue_name_prefix = queue_name_prefix
|
70
|
-
end
|
71
|
-
|
72
|
-
def self.set(options)
|
73
|
-
@queue = options['queue']
|
74
|
-
|
75
|
-
self
|
76
|
-
end
|
77
|
-
|
78
|
-
def try(method, *args, &block)
|
79
|
-
send method, *args, &block if respond_to? method
|
80
|
-
end
|
81
|
-
|
82
|
-
def self.perform_later(*args)
|
83
|
-
new do |instance|
|
84
|
-
instance.job_class = self.class.name
|
85
|
-
instance.queue_name = @queue
|
86
|
-
instance.arguments = [*args]
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
class ActiveJobCronTestClass < ActiveJob::Base
|
93
|
-
end
|
@@ -1 +0,0 @@
|
|
1
|
-
--- string
|