sidekiq-cron 1.12.0 → 2.0.0.rc2

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.
@@ -0,0 +1,43 @@
1
+ module Sidekiq
2
+ module Cron
3
+ class Namespace
4
+ def self.all
5
+ namespaces = nil
6
+
7
+ Sidekiq.redis do |conn|
8
+ namespaces = conn.keys('cron_jobs:*').collect do |key|
9
+ key.split(':').last
10
+ end
11
+ end
12
+
13
+ # Adds the default namespace if not present
14
+ has_default = namespaces.detect do |name|
15
+ name == Sidekiq::Cron.configuration.default_namespace
16
+ end
17
+
18
+ unless has_default
19
+ namespaces << Sidekiq::Cron.configuration.default_namespace
20
+ end
21
+
22
+ namespaces
23
+ end
24
+
25
+ def self.all_with_count
26
+ all.map do |namespace_name|
27
+ {
28
+ count: count(namespace_name),
29
+ name: namespace_name
30
+ }
31
+ end
32
+ end
33
+
34
+ def self.count(name = Sidekiq::Cron.configuration.default_namespace)
35
+ out = 0
36
+ Sidekiq.redis do |conn|
37
+ out = conn.scard("cron_jobs:#{name}")
38
+ end
39
+ out
40
+ end
41
+ end
42
+ end
43
+ end
@@ -1,25 +1,24 @@
1
- require 'sidekiq'
2
- require 'sidekiq/cron'
1
+ # frozen_string_literal: true
2
+
3
3
  require 'sidekiq/scheduled'
4
- require 'sidekiq/options'
5
4
 
6
5
  module Sidekiq
7
6
  module Cron
8
- # The Poller checks Redis every N seconds for sheduled cron jobs.
7
+ # The Poller checks Redis every N seconds for scheduled cron jobs.
9
8
  class Poller < Sidekiq::Scheduled::Poller
10
9
  def initialize(config = nil)
11
- if Gem::Version.new(Sidekiq::VERSION) >= Gem::Version.new('6.5.0')
12
- super
13
- else
14
- # Old version of Sidekiq does not accept a config argument.
15
- @config = config
16
- super()
17
- end
10
+ super
11
+ end
12
+
13
+ def start
14
+ Sidekiq::Cron::Job.migrate_old_jobs_if_needed!
15
+
16
+ super
18
17
  end
19
18
 
20
19
  def enqueue
21
20
  time = Time.now.utc
22
- Sidekiq::Cron::Job.all.each do |job|
21
+ Sidekiq::Cron::Job.all('*').each do |job|
23
22
  enqueue_job(job, time)
24
23
  end
25
24
  rescue => ex
@@ -33,7 +32,7 @@ module Sidekiq
33
32
  private
34
33
 
35
34
  def enqueue_job(job, time = Time.now.utc)
36
- job.test_and_enque_for_time! time if job && job.valid?
35
+ job.test_and_enqueue_for_time! time if job && job.valid?
37
36
  rescue => ex
38
37
  # Problem somewhere in one job.
39
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::Options[:cron_schedule_file] || 'config/schedule.yml'
2
+ schedule_file = Sidekiq::Cron.configuration.cron_schedule_file
7
3
 
8
4
  if File.exist?(schedule_file)
9
5
  config.on(:startup) do
@@ -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
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Sidekiq
4
4
  module Cron
5
- VERSION = "1.12.0"
5
+ VERSION = "2.0.0.rc2"
6
6
  end
7
7
  end
@@ -1,22 +1,25 @@
1
1
  <header class='row'>
2
2
  <div class='col-sm-5 pull-left'>
3
- <h3><%= t('CronJobs') %></h3>
3
+ <h3>
4
+ <%= t('CronJobs') %>
5
+ <small><%= @current_namespace %></small>
6
+ </h3>
4
7
  </div>
5
- <div class='col-sm-7 pull-right' style="margin-top: 20px; margin-bottom: 10px;">
8
+ <div class='col-sm-7 pull-right h2'>
6
9
  <% if @cron_jobs.size > 0 %>
7
- <form action="<%= root_path %>cron/__all__/delete" method="post" class="pull-right">
10
+ <form action="<%= root_path %>cron/namespaces/<%= @current_namespace %>/all/delete" method="post" class="pull-right">
8
11
  <%= csrf_tag if respond_to?(:csrf_tag) %>
9
12
  <input class="btn btn-danger" type="submit" name="delete" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSureDeleteCronJobs') %>" />
10
13
  </form>
11
- <form action="<%= root_path %>cron/__all__/disable" method="post" class="pull-right">
14
+ <form action="<%= root_path %>cron/namespaces/<%= @current_namespace %>/all/disable" method="post" class="pull-right">
12
15
  <%= csrf_tag if respond_to?(:csrf_tag) %>
13
16
  <input class="btn btn-warn" type="submit" name="enque" value="<%= t('DisableAll') %>" />
14
17
  </form>
15
- <form action="<%= root_path %>cron/__all__/enable" method="post" class="pull-right">
18
+ <form action="<%= root_path %>cron/namespaces/<%= @current_namespace %>/all/enable" method="post" class="pull-right">
16
19
  <%= csrf_tag if respond_to?(:csrf_tag) %>
17
20
  <input class="btn btn-warn" type="submit" name="enque" value="<%= t('EnableAll') %>" />
18
21
  </form>
19
- <form action="<%= root_path %>cron/__all__/enque" method="post" class="pull-right">
22
+ <form action="<%= root_path %>cron/namespaces/<%= @current_namespace %>/all/enque" method="post" class="pull-right">
20
23
  <%= csrf_tag if respond_to?(:csrf_tag) %>
21
24
  <input class="btn btn-warn" type="submit" name="enque" value="<%= t('EnqueueAll') %>" data-confirm="<%= t('AreYouSureEnqueueCronJobs') %>" />
22
25
  </form>
@@ -24,67 +27,79 @@
24
27
  </div>
25
28
  </header>
26
29
 
27
- <% if @cron_jobs.size > 0 %>
30
+ <!-- Namespaces -->
31
+ <div class='row'>
32
+ <div class="col-sm-12 summary_bar">
33
+ <ul class="list-unstyled summary row">
34
+ <% @namespaces.sort_by { |namespace| namespace[:name] }.each do |namespace| %>
35
+ <li class="col-sm-1">
36
+ <a href="<%= root_path %>cron/namespaces/<%= namespace[:name] %>">
37
+ <span class="count"><%= namespace[:count] %></span>
38
+ <span class="desc"><%= namespace[:name] %></span>
39
+ </a>
40
+ </li>
41
+ <% end %>
42
+ </ul>
43
+ </div>
44
+ </div>
45
+ <!-- Namespaces -->
28
46
 
47
+ <% if @cron_jobs.size > 0 %>
29
48
  <table class="table table-hover table-bordered table-striped table-white">
30
49
  <thead>
50
+ <tr>
31
51
  <th><%= t('Status') %></th>
32
- <th><%= t('Name') %></th>
52
+ <th width="50%"><%= t('Name') %></th>
33
53
  <th><%= t('Cron string') %></th>
34
54
  <th><%= t('Last enqueued') %></th>
35
- <th width="180"><%= t('Actions')%></th>
55
+ <th width="180"><%= t('Actions') %></th>
56
+ </tr>
36
57
  </thead>
37
58
 
38
59
  <tbody>
39
- <% @cron_jobs.sort{|a,b| a.sort_name <=> b.sort_name }.each_with_index do |job, index| %>
40
- <% style = "#{job.status == 'disabled' ? "background: #ecc; color: #585454;": ""}" %>
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') %>
41
63
  <tr>
42
- <td style="<%= style %>"><%= t job.status %></td>
43
- <td style="<%= style %>">
44
- <a href="<%= root_path %>cron/<%= CGI.escape(job.name).gsub('+', '%20') %>">
45
- <b style="<%= style %>"><%= job.name %></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>
46
68
  </a>
47
- <hr style="margin:3px;border:0;">
48
- <small>
69
+ <br/>
49
70
  <% if job.message and job.message.to_s.size > 100 %>
50
- <% if Gem::Version.new(Sidekiq::VERSION) >= Gem::Version.new("6.3.0") %>
51
- <button data-toggle="job_<%= index %>" class="btn btn-warn btn-xs"><%= t('ShowAll')%></button>
52
- <div class="toggle" id="job_<%= index %>" style="display: inline;"><%= job.message[0..100] + "... " %></div>
53
- <div class="toggle" id="job_<%= index %>_full" style="display: none;"><%= job.message %></div>
54
- <% else %>
55
- <button data-toggle="collapse" data-target=".worker_<%= index %>" class="btn btn-warn btn-xs"><%= t('ShowAll')%></button>
56
- <div class="toggle worker_<%= index %>" style="display: inline;"><%= job.message[0..100] + "... " %></div>
57
- <div class="toggle worker_<%= index %>" style="display: none;"><%= job.message %></div>
58
- <% end %>
71
+ <details>
72
+ <summary class="btn btn-warn btn-xs">Show message</summary>
73
+ <p><small><%= job.message %></small></p>
74
+ </details>
59
75
  <% else %>
60
- <%= job.message %>
76
+ <small><%= job.message %></small>
61
77
  <% end %>
62
- </small>
63
78
  </td>
64
- <td style="<%= style %>"><b><%= job.cron.gsub(" ", "&nbsp;") %></b></td>
65
- <td style="<%= style %>"><%= job.last_enqueue_time ? relative_time(job.last_enqueue_time) : "-" %></td>
66
- <td style="<%= style %>">
79
+ <td class="<%= klass %>"><b><%= job.human_cron %><br/><small><%= job.cron.gsub(" ", "&nbsp;") %></small></b></td>
80
+ <td class="<%= klass %>"><%= job.last_enqueue_time ? relative_time(job.last_enqueue_time) : "-" %></td>
81
+ <td class="<%= klass %>">
67
82
  <% if job.status == 'enabled' %>
68
- <form action="<%= root_path %>cron/<%= CGI.escape(job.name).gsub('+', '%20') %>/enque" method="post">
83
+ <form action="<%= root_path %>cron/namespaces/<%= job.namespace %>/jobs/<%= escaped_job_name %>/enque" method="post">
69
84
  <%= csrf_tag if respond_to?(:csrf_tag) %>
70
85
  <input class='btn btn-warn btn-xs pull-left' type="submit" name="enque" value="<%= t('EnqueueNow') %>" data-confirm="<%= t('AreYouSureEnqueueCronJob', :job => job.name) %>"/>
71
86
  </form>
72
- <form action="<%= root_path %>cron/<%= CGI.escape(job.name).gsub('+', '%20') %>/disable" method="post">
87
+ <form action="<%= root_path %>cron/namespaces/<%= job.namespace %>/jobs/<%= escaped_job_name %>/disable" method="post">
73
88
  <%= csrf_tag if respond_to?(:csrf_tag) %>
74
89
  <input class='btn btn-warn btn-xs pull-left' type="submit" name="disable" value="<%= t('Disable') %>"/>
75
90
  </form>
76
91
  <% else %>
77
- <form action="<%= root_path %>cron/<%= CGI.escape(job.name).gsub('+', '%20') %>/enque" method="post">
92
+ <form action="<%= root_path %>cron/namespaces/<%= job.namespace %>/jobs/<%= escaped_job_name %>/enque" method="post">
78
93
  <%= csrf_tag if respond_to?(:csrf_tag) %>
79
- <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) %>"/>
80
95
  </form>
81
- <form action="<%= root_path %>cron/<%= CGI.escape(job.name).gsub('+', '%20') %>/enable" method="post">
96
+ <form action="<%= root_path %>cron/namespaces/<%= job.namespace %>/jobs/<%= escaped_job_name %>/enable" method="post">
82
97
  <%= csrf_tag if respond_to?(:csrf_tag) %>
83
98
  <input class='btn btn-warn btn-xs pull-left' type="submit" name="enable" value="<%= t('Enable') %>"/>
84
99
  </form>
85
- <form action="<%= root_path %>cron/<%= CGI.escape(job.name).gsub('+', '%20') %>/delete" method="post">
100
+ <form action="<%= root_path %>cron/namespaces/<%= job.namespace %>/jobs/<%= escaped_job_name %>/delete" method="post">
86
101
  <%= csrf_tag if respond_to?(:csrf_tag) %>
87
- <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) %>"/>
88
103
  </form>
89
104
  <% end %>
90
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" style="margin-top: 20px; margin-bottom: 10px;">
9
- <% cron_job_path = "#{root_path}cron/#{CGI.escape(@job.name).gsub('+', '%20')}" %>
10
- <form action="<%= cron_job_path %>/enque?redirect=<%= cron_job_path %>" method="post">
8
+ <div class="span col-sm-7 pull-right h2">
9
+ <% cron_job_path = "#{root_path}cron/namespaces/#{@current_namespace}/jobs/#{CGI.escape(@job.name).gsub('+', '%20')}" %>
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>
@@ -39,6 +39,10 @@
39
39
  <th><%= t 'Name' %></th>
40
40
  <td><%= @job.name %></td>
41
41
  </tr>
42
+ <tr>
43
+ <th><%= t 'Namespace' %></th>
44
+ <td><%= @job.namespace %></td>
45
+ </tr>
42
46
  <tr>
43
47
  <th><%= t 'Description' %></th>
44
48
  <td><%= @job.description %></td>
@@ -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
- Sidekiq::Web.register Sidekiq::Cron::WebExtension
6
- Sidekiq::Web.tabs["Cron"] = "cron"
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,65 +4,111 @@ 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
- view_path = File.join(File.expand_path("..", __FILE__), "views")
16
+ view_path = File.join(File.expand_path("..", __FILE__), "views")
10
17
 
18
+ @current_namespace = 'default'
19
+
20
+ @namespaces = Sidekiq::Cron::Namespace.all_with_count
21
+
22
+ # Not passing namespace takes all the jobs from the default one.
11
23
  @cron_jobs = Sidekiq::Cron::Job.all
12
24
 
13
25
  render(:erb, File.read(File.join(view_path, "cron.erb")))
14
26
  end
15
27
 
28
+ app.get '/cron/namespaces/:name' do
29
+ view_path = File.join(File.expand_path("..", __FILE__), "views")
30
+
31
+ @current_namespace = route_params[:name]
32
+
33
+ @namespaces = Sidekiq::Cron::Namespace.all_with_count
34
+
35
+ @cron_jobs = Sidekiq::Cron::Job.all(@current_namespace)
36
+
37
+ render(:erb, File.read(File.join(view_path, "cron.erb")))
38
+ end
39
+
16
40
  # Display job detail + jid history.
17
- app.get '/cron/:name' do
41
+ app.get '/cron/namespaces/:namespace/jobs/:name' do
18
42
  view_path = File.join(File.expand_path("..", __FILE__), "views")
19
43
 
20
- @job = Sidekiq::Cron::Job.find(route_params[:name])
44
+ @current_namespace = route_params[:namespace]
45
+ @job_name = route_params[:name]
46
+
47
+ @namespaces = Sidekiq::Cron::Namespace.all_with_count
48
+
49
+ @job = Sidekiq::Cron::Job.find(@job_name, @current_namespace)
50
+
21
51
  if @job
22
52
  render(:erb, File.read(File.join(view_path, "cron_show.erb")))
23
53
  else
24
- redirect "#{root_path}cron"
54
+ redirect namespace_redirect_path
25
55
  end
26
56
  end
27
57
 
58
+ # Enqueue all cron jobs.
59
+ app.post '/cron/namespaces/:namespace/all/enque' do
60
+ Sidekiq::Cron::Job.all(route_params[:namespace]).each(&:enqueue!)
61
+ redirect params['redirect'] || namespace_redirect_path
62
+ end
63
+
28
64
  # 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!
65
+ app.post '/cron/namespaces/:namespace/jobs/:name/enque' do
66
+ if job = Sidekiq::Cron::Job.find(route_params[:name], route_params[:namespace])
67
+ job.enqueue!
34
68
  end
35
- redirect params['redirect'] || "#{root_path}cron"
69
+ redirect params['redirect'] || namespace_redirect_path
70
+ end
71
+
72
+ # Delete all schedules.
73
+ app.post '/cron/namespaces/:namespace/all/delete' do
74
+ Sidekiq::Cron::Job.all(route_params[:namespace]).each(&:destroy)
75
+ redirect params['redirect'] || namespace_redirect_path
36
76
  end
37
77
 
38
78
  # 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])
79
+ app.post '/cron/namespaces/:namespace/jobs/:name/delete' do
80
+ if job = Sidekiq::Cron::Job.find(route_params[:name], route_params[:namespace])
43
81
  job.destroy
44
82
  end
45
- redirect "#{root_path}cron"
83
+ redirect params['redirect'] || namespace_redirect_path
84
+ end
85
+
86
+ # Enable all jobs.
87
+ app.post '/cron/namespaces/:namespace/all/enable' do
88
+ Sidekiq::Cron::Job.all(route_params[:namespace]).each(&:enable!)
89
+ redirect params['redirect'] || namespace_redirect_path
46
90
  end
47
91
 
48
92
  # 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])
93
+ app.post '/cron/namespaces/:namespace/jobs/:name/enable' do
94
+ if job = Sidekiq::Cron::Job.find(route_params[:name], route_params[:namespace])
53
95
  job.enable!
54
96
  end
55
- redirect params['redirect'] || "#{root_path}cron"
97
+ redirect params['redirect'] || namespace_redirect_path
98
+ end
99
+
100
+ # Disable all jobs.
101
+ app.post '/cron/namespaces/:namespace/all/disable' do
102
+ Sidekiq::Cron::Job.all(route_params[:namespace]).each(&:disable!)
103
+ redirect params['redirect'] || namespace_redirect_path
56
104
  end
57
105
 
58
106
  # 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])
107
+ app.post '/cron/namespaces/:namespace/jobs/:name/disable' do
108
+ if job = Sidekiq::Cron::Job.find(route_params[:name], route_params[:namespace])
63
109
  job.disable!
64
110
  end
65
- redirect params['redirect'] || "#{root_path}cron"
111
+ redirect params['redirect'] || namespace_redirect_path
66
112
  end
67
113
  end
68
114
  end
data/lib/sidekiq/cron.rb CHANGED
@@ -1,9 +1,65 @@
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 default namespace is used when no namespace is specified.
18
+ attr_accessor :default_namespace
19
+
20
+ # The parsing mode when using the natural language cron syntax from the `fugit` gem.
21
+ #
22
+ # :single -- use the first parsed cron line and ignore the rest (default)
23
+ # :strict -- raise an error if multiple cron lines are parsed from one string
24
+ attr_reader :natural_cron_parsing_mode
25
+
26
+ # The poller will not enqueue jobs that are late by more than this amount of seconds.
27
+ # Defaults to 60 seconds.
28
+ #
29
+ # This is useful when sidekiq (and sidekiq-cron) is not used in zero downtime deployments and
30
+ # when the deployment is done and sidekiq-cron starts to catch up, it will consider older
31
+ # jobs that missed their schedules during the deployment. E.g., jobs that run once a day.
32
+ attr_accessor :reschedule_grace_period
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
+
45
+ def initialize
46
+ @default_namespace = 'default'
47
+ @natural_cron_parsing_mode = :single
48
+ @reschedule_grace_period = 60
49
+ @cron_history_size = 10
50
+ @cron_poll_interval = 30
51
+ @cron_schedule_file = 'config/schedule.yml'
52
+ end
53
+
54
+ def natural_cron_parsing_mode=(mode)
55
+ unless %i[single strict].include?(mode)
56
+ raise ArgumentError, "Unknown natural cron parsing mode: #{mode.inspect}"
57
+ end
58
+
59
+ @natural_cron_parsing_mode = mode
60
+ end
61
+ end
8
62
  end
9
63
  end
64
+
65
+ 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,9 +26,10 @@ 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")