sidekiq-cron 1.10.1 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1413d9d3418c71f816ea65bb6656c3053535d181ce22fbbc82daa3dca223f524
4
- data.tar.gz: aecf5bb82af028c08f458a93aa8d96d6cc7c58ffe5b7a0380c33ecd5f02e42ae
3
+ metadata.gz: 38f49b844ee1ade391bc47b8acd2e98b02cb9d05041cad364fca427c51d3f65d
4
+ data.tar.gz: 6328039e5648a59057202fec118775e8e1ed7ffc2d5a38229c62e4c7af7ebfaf
5
5
  SHA512:
6
- metadata.gz: b135afb05139d833320da0efd60f76d1a55771f2bf3adfcf5fdcbe6f9e5bdd9c23ca3339bc354ee7ee9a5fe77da93eb73e2043ef1b37c7d78e7df1da9365a482
7
- data.tar.gz: a1cfe3438ebd8eaec2bce2eac18f7f42983bdc5ed93e8dbf5810cf6eb01942847582a2b50526dcb36854ab6385555f41983aaad9bd85a89699c745d4c5196bd6
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
- - use `hset` instead of deprecated `hmset` (https://github.com/sidekiq-cron/sidekiq-cron/pull/410)
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/317/282)
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
- ### Job properties
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 that 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.
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
- Sidekiq::Cron::Job.load_from_hash YAML.load_file(schedule_file)
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:
@@ -162,19 +162,19 @@ module Sidekiq
162
162
  # }
163
163
  # }
164
164
  #
165
- def self.load_from_hash 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 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! 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 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! 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.map(&:name)
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Sidekiq
4
4
  module Cron
5
- VERSION = "1.10.1"
5
+ VERSION = "1.11.0"
6
6
  end
7
7
  end
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/**/*') + Dir.glob('test/**/*') + [
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.14")
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.10.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-05-09 00:00:00.000000000 Z
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.14'
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.14'
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.6
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
@@ -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,13 +0,0 @@
1
- ---
2
- -
3
- name: "my_first_job"
4
- cron: "*/5 * * * *"
5
- class: "HardWorker"
6
- queue: "hard_worker"
7
- -
8
- name: "second_job"
9
- cron: "*/30 * * * *"
10
- class: "HardWorker"
11
- queue: "hard_worker_long"
12
- args:
13
- hard: "stuff"
@@ -1,6 +0,0 @@
1
- ---
2
- default: &default
3
- cron: <%= "every day at 5 pm" %>
4
- class: <%= "DailyJob" %>
5
-
6
- daily_job: *default
@@ -1,12 +0,0 @@
1
- ---
2
- my_first_job:
3
- cron: "*/5 * * * *"
4
- class: "HardWorker"
5
- queue: hard_worker
6
-
7
- second_job:
8
- cron: "*/30 * * * *"
9
- class: "HardWorker"
10
- queue: hard_worker_long
11
- args:
12
- hard: "stuff"
@@ -1 +0,0 @@
1
- --- string