sidekiq-cron 1.12.0 → 2.2.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.
@@ -1,68 +1,132 @@
1
1
  module Sidekiq
2
2
  module Cron
3
3
  module WebExtension
4
+ module Helpers
5
+ def cron_route_params(key)
6
+ if Gem::Version.new(Sidekiq::VERSION) >= Gem::Version.new("8.0.0")
7
+ route_params(key)
8
+ else
9
+ route_params[key]
10
+ end
11
+ end
12
+
13
+ # This method constructs the URL for the cron jobs page within the specified namespace.
14
+ def namespace_redirect_path
15
+ "#{root_path}cron/namespaces/#{cron_route_params(:namespace)}"
16
+ end
17
+
18
+ def redirect_to_previous_or_default
19
+ redirect params['redirect'] || namespace_redirect_path
20
+ end
21
+
22
+ def render_erb(view)
23
+ path = Gem::Version.new(Sidekiq::VERSION) >= Gem::Version.new("8.0.0") ? "views" : "views/legacy"
24
+ views_path = File.join(File.expand_path("..", __FILE__), path)
25
+ erb(File.read(File.join(views_path, "#{view}.erb")))
26
+ end
27
+ end
28
+
4
29
  def self.registered(app)
5
- app.settings.locales << File.join(File.expand_path("..", __FILE__), "locales")
30
+ locales = if Gem::Version.new(Sidekiq::VERSION) >= Gem::Version.new("8.0.0")
31
+ Sidekiq::Web.configure.locales
32
+ else
33
+ app.settings.locales
34
+ end
35
+
36
+ locales << File.join(File.expand_path("..", __FILE__), "locales")
6
37
 
7
- # Index page of cron jobs.
38
+ app.helpers(Helpers)
39
+
40
+ # Index page.
8
41
  app.get '/cron' do
9
- view_path = File.join(File.expand_path("..", __FILE__), "views")
42
+ @current_namespace = 'default'
43
+ @cron_jobs = Sidekiq::Cron::Job.all(@current_namespace)
44
+
45
+ render_erb(:cron)
46
+ end
10
47
 
11
- @cron_jobs = Sidekiq::Cron::Job.all
48
+ # Detail page for a specific namespace.
49
+ app.get '/cron/namespaces/:name' do
50
+ @current_namespace = cron_route_params(:name)
51
+ @cron_jobs = Sidekiq::Cron::Job.all(@current_namespace)
12
52
 
13
- render(:erb, File.read(File.join(view_path, "cron.erb")))
53
+ render_erb(:cron)
14
54
  end
15
55
 
16
56
  # Display job detail + jid history.
17
- app.get '/cron/:name' do
18
- view_path = File.join(File.expand_path("..", __FILE__), "views")
57
+ app.get '/cron/namespaces/:namespace/jobs/:name' do
58
+ @current_namespace = cron_route_params(:namespace)
59
+ @job = Sidekiq::Cron::Job.find(cron_route_params(:name), @current_namespace)
19
60
 
20
- @job = Sidekiq::Cron::Job.find(route_params[:name])
21
61
  if @job
22
- render(:erb, File.read(File.join(view_path, "cron_show.erb")))
62
+ render_erb(:cron_show)
23
63
  else
24
- redirect "#{root_path}cron"
64
+ redirect namespace_redirect_path
25
65
  end
26
66
  end
27
67
 
68
+ # Enqueue all cron jobs.
69
+ app.post '/cron/namespaces/:namespace/all/enqueue' do
70
+ Sidekiq::Cron::Job.all(cron_route_params(:namespace)).each(&:enqueue!)
71
+
72
+ redirect_to_previous_or_default
73
+ end
74
+
28
75
  # Enqueue cron job.
29
- app.post '/cron/:name/enque' do
30
- if route_params[:name] === '__all__'
31
- Sidekiq::Cron::Job.all.each(&:enque!)
32
- elsif job = Sidekiq::Cron::Job.find(route_params[:name])
33
- job.enque!
76
+ app.post '/cron/namespaces/:namespace/jobs/:name/enqueue' do
77
+ if job = Sidekiq::Cron::Job.find(cron_route_params(:name), cron_route_params(:namespace))
78
+ job.enqueue!
34
79
  end
35
- redirect params['redirect'] || "#{root_path}cron"
80
+
81
+ redirect_to_previous_or_default
82
+ end
83
+
84
+ # Delete all schedules.
85
+ app.post '/cron/namespaces/:namespace/all/delete' do
86
+ Sidekiq::Cron::Job.all(cron_route_params(:namespace)).each(&:destroy)
87
+
88
+ redirect_to_previous_or_default
36
89
  end
37
90
 
38
91
  # Delete schedule.
39
- app.post '/cron/:name/delete' do
40
- if route_params[:name] === '__all__'
41
- Sidekiq::Cron::Job.all.each(&:destroy)
42
- elsif job = Sidekiq::Cron::Job.find(route_params[:name])
92
+ app.post '/cron/namespaces/:namespace/jobs/:name/delete' do
93
+ if job = Sidekiq::Cron::Job.find(cron_route_params(:name), cron_route_params(:namespace))
43
94
  job.destroy
44
95
  end
45
- redirect "#{root_path}cron"
96
+
97
+ redirect_to_previous_or_default
98
+ end
99
+
100
+ # Enable all jobs.
101
+ app.post '/cron/namespaces/:namespace/all/enable' do
102
+ Sidekiq::Cron::Job.all(cron_route_params(:namespace)).each(&:enable!)
103
+
104
+ redirect_to_previous_or_default
46
105
  end
47
106
 
48
107
  # Enable job.
49
- app.post '/cron/:name/enable' do
50
- if route_params[:name] === '__all__'
51
- Sidekiq::Cron::Job.all.each(&:enable!)
52
- elsif job = Sidekiq::Cron::Job.find(route_params[:name])
108
+ app.post '/cron/namespaces/:namespace/jobs/:name/enable' do
109
+ if job = Sidekiq::Cron::Job.find(cron_route_params(:name), cron_route_params(:namespace))
53
110
  job.enable!
54
111
  end
55
- redirect params['redirect'] || "#{root_path}cron"
112
+
113
+ redirect_to_previous_or_default
114
+ end
115
+
116
+ # Disable all jobs.
117
+ app.post '/cron/namespaces/:namespace/all/disable' do
118
+ Sidekiq::Cron::Job.all(cron_route_params(:namespace)).each(&:disable!)
119
+
120
+ redirect_to_previous_or_default
56
121
  end
57
122
 
58
123
  # Disable job.
59
- app.post '/cron/:name/disable' do
60
- if route_params[:name] === '__all__'
61
- Sidekiq::Cron::Job.all.each(&:disable!)
62
- elsif job = Sidekiq::Cron::Job.find(route_params[:name])
124
+ app.post '/cron/namespaces/:namespace/jobs/:name/disable' do
125
+ if job = Sidekiq::Cron::Job.find(cron_route_params(:name), cron_route_params(:namespace))
63
126
  job.disable!
64
127
  end
65
- redirect params['redirect'] || "#{root_path}cron"
128
+
129
+ redirect_to_previous_or_default
66
130
  end
67
131
  end
68
132
  end
data/lib/sidekiq/cron.rb CHANGED
@@ -1,9 +1,77 @@
1
- require "sidekiq/cron/job"
2
- require "sidekiq/cron/poller"
3
- require "sidekiq/cron/launcher"
4
- require "sidekiq/cron/schedule_loader"
5
-
6
1
  module Sidekiq
7
2
  module Cron
3
+ class << self
4
+ attr_accessor :configuration
5
+ end
6
+
7
+ def self.configure
8
+ self.configuration ||= Configuration.new
9
+ yield(configuration) if block_given?
10
+ end
11
+
12
+ def self.reset!
13
+ self.configuration = Configuration.new
14
+ end
15
+
16
+ class Configuration
17
+ # The interval, in seconds, at which to poll for scheduled cron jobs.
18
+ # This determines how frequently the scheduler checks for jobs to enqueue.
19
+ attr_accessor :cron_poll_interval
20
+
21
+ # The path to a YAML file containing multiple cron job schedules.
22
+ attr_accessor :cron_schedule_file
23
+
24
+ # The maximum number of recent cron job execution histories to retain.
25
+ # This value controls how many past job executions are stored.
26
+ attr_accessor :cron_history_size
27
+
28
+ # The default namespace is used when no namespace is specified.
29
+ attr_accessor :default_namespace
30
+
31
+ # List of available namespaces
32
+ #
33
+ # If not set, Sidekiq Cron will dynamically fetch available namespaces
34
+ # by retrieving existing jobs from Redis.
35
+ #
36
+ # This dynamic fetching can negatively impact performance in certain cases.
37
+ # To mitigate this, you can provide the list of namespaces explicitly.
38
+ # If a job specifies a namespace that is not included in the provided list,
39
+ # a warning will be logged, and the job will be assigned to the default namespace.
40
+ attr_accessor :available_namespaces
41
+
42
+ # The parsing mode when using the natural language cron syntax from the `fugit` gem.
43
+ #
44
+ # :single -- use the first parsed cron line and ignore the rest (default)
45
+ # :strict -- raise an error if multiple cron lines are parsed from one string
46
+ attr_reader :natural_cron_parsing_mode
47
+
48
+ # The poller will not enqueue jobs that are late by more than this amount of seconds.
49
+ # Defaults to 60 seconds.
50
+ #
51
+ # This is useful when Sidekiq (and Sidekiq-Cron) is not used in zero downtime deployments and
52
+ # when the deployment is done and Sidekiq-Cron starts to catch up, it will consider older
53
+ # jobs that missed their schedules during the deployment. E.g., jobs that run once a day.
54
+ attr_accessor :reschedule_grace_period
55
+
56
+ def initialize
57
+ @cron_poll_interval = 30
58
+ @cron_schedule_file = 'config/schedule.yml'
59
+ @cron_history_size = 10
60
+ @default_namespace = 'default'
61
+ @available_namespaces = nil
62
+ @natural_cron_parsing_mode = :single
63
+ @reschedule_grace_period = 60
64
+ end
65
+
66
+ def natural_cron_parsing_mode=(mode)
67
+ unless %i[single strict].include?(mode)
68
+ raise ArgumentError, "Unknown natural cron parsing mode: #{mode.inspect}"
69
+ end
70
+
71
+ @natural_cron_parsing_mode = mode
72
+ end
73
+ end
8
74
  end
9
75
  end
76
+
77
+ Sidekiq::Cron.configure
@@ -1,5 +1,4 @@
1
- require 'sidekiq'
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
- :options
23
+ false
26
24
  end
27
25
  end
28
26
  end
data/lib/sidekiq-cron.rb CHANGED
@@ -1,2 +1,8 @@
1
1
  require "sidekiq"
2
2
  require "sidekiq/cron"
3
+ require "sidekiq/options"
4
+ require "sidekiq/cron/job"
5
+ require "sidekiq/cron/namespace"
6
+ require "sidekiq/cron/poller"
7
+ require "sidekiq/cron/launcher"
8
+ require "sidekiq/cron/schedule_loader"
data/sidekiq-cron.gemspec CHANGED
@@ -26,14 +26,15 @@ Gem::Specification.new do |s|
26
26
 
27
27
  s.required_ruby_version = ">= 2.7"
28
28
 
29
- s.add_dependency("fugit", "~> 1.8")
30
- s.add_dependency("sidekiq", ">= 6")
29
+ s.add_dependency("cronex", ">= 0.13.0")
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.5.0")
32
33
 
33
34
  s.add_development_dependency("minitest", "~> 5.15")
34
35
  s.add_development_dependency("mocha", "~> 2.1")
35
- s.add_development_dependency("rack", "~> 2.2")
36
- s.add_development_dependency("rack-test", "~> 1.1")
36
+ s.add_development_dependency("rack", ">= 2.2")
37
+ s.add_development_dependency("rack-test", ">= 1.1")
37
38
  s.add_development_dependency("rake", "~> 13.0")
38
39
  s.add_development_dependency("simplecov", "~> 0.21")
39
40
  s.add_development_dependency("simplecov-cobertura", "~> 2.1")
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq-cron
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.12.0
4
+ version: 2.2.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-12-08 00:00:00.000000000 Z
11
+ date: 2025-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: cronex
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.13.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.13.0
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: fugit
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -17,6 +31,9 @@ dependencies:
17
31
  - - "~>"
18
32
  - !ruby/object:Gem::Version
19
33
  version: '1.8'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 1.11.1
20
37
  type: :runtime
21
38
  prerelease: false
22
39
  version_requirements: !ruby/object:Gem::Requirement
@@ -24,34 +41,37 @@ dependencies:
24
41
  - - "~>"
25
42
  - !ruby/object:Gem::Version
26
43
  version: '1.8'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 1.11.1
27
47
  - !ruby/object:Gem::Dependency
28
- name: sidekiq
48
+ name: globalid
29
49
  requirement: !ruby/object:Gem::Requirement
30
50
  requirements:
31
51
  - - ">="
32
52
  - !ruby/object:Gem::Version
33
- version: '6'
53
+ version: 1.0.1
34
54
  type: :runtime
35
55
  prerelease: false
36
56
  version_requirements: !ruby/object:Gem::Requirement
37
57
  requirements:
38
58
  - - ">="
39
59
  - !ruby/object:Gem::Version
40
- version: '6'
60
+ version: 1.0.1
41
61
  - !ruby/object:Gem::Dependency
42
- name: globalid
62
+ name: sidekiq
43
63
  requirement: !ruby/object:Gem::Requirement
44
64
  requirements:
45
65
  - - ">="
46
66
  - !ruby/object:Gem::Version
47
- version: 1.0.1
67
+ version: 6.5.0
48
68
  type: :runtime
49
69
  prerelease: false
50
70
  version_requirements: !ruby/object:Gem::Requirement
51
71
  requirements:
52
72
  - - ">="
53
73
  - !ruby/object:Gem::Version
54
- version: 1.0.1
74
+ version: 6.5.0
55
75
  - !ruby/object:Gem::Dependency
56
76
  name: minitest
57
77
  requirement: !ruby/object:Gem::Requirement
@@ -84,28 +104,28 @@ dependencies:
84
104
  name: rack
85
105
  requirement: !ruby/object:Gem::Requirement
86
106
  requirements:
87
- - - "~>"
107
+ - - ">="
88
108
  - !ruby/object:Gem::Version
89
109
  version: '2.2'
90
110
  type: :development
91
111
  prerelease: false
92
112
  version_requirements: !ruby/object:Gem::Requirement
93
113
  requirements:
94
- - - "~>"
114
+ - - ">="
95
115
  - !ruby/object:Gem::Version
96
116
  version: '2.2'
97
117
  - !ruby/object:Gem::Dependency
98
118
  name: rack-test
99
119
  requirement: !ruby/object:Gem::Requirement
100
120
  requirements:
101
- - - "~>"
121
+ - - ">="
102
122
  - !ruby/object:Gem::Version
103
123
  version: '1.1'
104
124
  type: :development
105
125
  prerelease: false
106
126
  version_requirements: !ruby/object:Gem::Requirement
107
127
  requirements:
108
- - - "~>"
128
+ - - ">="
109
129
  - !ruby/object:Gem::Version
110
130
  version: '1.1'
111
131
  - !ruby/object:Gem::Dependency
@@ -170,17 +190,22 @@ files:
170
190
  - lib/sidekiq/cron/launcher.rb
171
191
  - lib/sidekiq/cron/locales/de.yml
172
192
  - lib/sidekiq/cron/locales/en.yml
193
+ - lib/sidekiq/cron/locales/es.yml
194
+ - lib/sidekiq/cron/locales/id.yml
173
195
  - lib/sidekiq/cron/locales/it.yml
174
196
  - lib/sidekiq/cron/locales/ja.yml
175
197
  - lib/sidekiq/cron/locales/pt.yml
176
198
  - lib/sidekiq/cron/locales/ru.yml
177
199
  - lib/sidekiq/cron/locales/zh-CN.yml
200
+ - lib/sidekiq/cron/namespace.rb
178
201
  - lib/sidekiq/cron/poller.rb
179
202
  - lib/sidekiq/cron/schedule_loader.rb
180
203
  - lib/sidekiq/cron/support.rb
181
204
  - lib/sidekiq/cron/version.rb
182
205
  - lib/sidekiq/cron/views/cron.erb
183
206
  - lib/sidekiq/cron/views/cron_show.erb
207
+ - lib/sidekiq/cron/views/legacy/cron.erb
208
+ - lib/sidekiq/cron/views/legacy/cron_show.erb
184
209
  - lib/sidekiq/cron/web.rb
185
210
  - lib/sidekiq/cron/web_extension.rb
186
211
  - lib/sidekiq/options.rb
@@ -204,7 +229,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
204
229
  - !ruby/object:Gem::Version
205
230
  version: '0'
206
231
  requirements: []
207
- rubygems_version: 3.4.10
232
+ rubygems_version: 3.5.16
208
233
  signing_key:
209
234
  specification_version: 4
210
235
  summary: Scheduler/Cron for Sidekiq jobs