sidekiq-cron 0.6.3 → 1.10.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 +5 -5
- data/CHANGELOG.md +145 -0
- data/Gemfile +3 -29
- data/README.md +175 -121
- data/Rakefile +3 -42
- data/lib/sidekiq/cron/job.rb +273 -144
- data/lib/sidekiq/cron/launcher.rb +39 -43
- data/lib/sidekiq/cron/locales/de.yml +2 -2
- data/lib/sidekiq/cron/locales/en.yml +6 -2
- data/lib/sidekiq/cron/locales/it.yml +23 -0
- data/lib/sidekiq/cron/locales/ja.yml +18 -0
- data/lib/sidekiq/cron/locales/pt.yml +22 -0
- data/lib/sidekiq/cron/locales/ru.yml +2 -2
- data/lib/sidekiq/cron/locales/zh-CN.yml +19 -0
- data/lib/sidekiq/cron/poller.rb +22 -12
- data/lib/sidekiq/cron/schedule_loader.rb +22 -0
- data/lib/sidekiq/cron/support.rb +8 -1
- data/lib/sidekiq/cron/version.rb +7 -0
- data/lib/sidekiq/cron/views/cron.erb +38 -28
- data/lib/sidekiq/cron/views/cron_show.erb +88 -0
- data/lib/sidekiq/cron/web.rb +1 -7
- data/lib/sidekiq/cron/web_extension.rb +19 -15
- data/lib/sidekiq/cron.rb +1 -0
- data/lib/sidekiq/options.rb +25 -0
- data/sidekiq-cron.gemspec +23 -108
- data/test/integration/performance_test.rb +13 -19
- data/test/models/person.rb +21 -0
- data/test/test_helper.rb +37 -38
- data/test/unit/fixtures/schedule_array.yml +13 -0
- data/test/unit/fixtures/schedule_erb.yml +6 -0
- data/test/unit/fixtures/schedule_hash.yml +12 -0
- data/test/unit/fixtures/schedule_string.yml +1 -0
- data/test/unit/job_test.rb +450 -35
- data/test/unit/launcher_test.rb +33 -0
- data/test/unit/poller_test.rb +28 -37
- data/test/unit/schedule_loader_test.rb +58 -0
- data/test/unit/web_extension_test.rb +59 -41
- metadata +72 -191
- data/.document +0 -5
- data/.travis.yml +0 -19
- data/Changes.md +0 -50
- data/Dockerfile +0 -32
- data/VERSION +0 -1
- data/config.ru +0 -14
- data/docker-compose.yml +0 -21
- data/examples/web-cron-ui.png +0 -0
- data/lib/sidekiq/cron/views/cron.slim +0 -69
@@ -1,53 +1,49 @@
|
|
1
|
-
# require Sidekiq original launcher
|
2
|
-
require 'sidekiq/launcher'
|
3
|
-
|
4
|
-
# require cron poller
|
5
1
|
require 'sidekiq/cron/poller'
|
6
2
|
|
7
3
|
# For Cron we need to add some methods to Launcher
|
8
4
|
# so look at the code bellow.
|
9
5
|
#
|
10
|
-
#
|
11
|
-
# adding start and stop commands to launcher
|
6
|
+
# We are creating new cron poller instance and
|
7
|
+
# adding start and stop commands to launcher.
|
12
8
|
module Sidekiq
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
9
|
+
module Cron
|
10
|
+
module Launcher
|
11
|
+
DEFAULT_POLL_INTERVAL = 30
|
12
|
+
|
13
|
+
# Add cron poller to launcher.
|
14
|
+
attr_reader :cron_poller
|
15
|
+
|
16
|
+
# Add cron poller and execute normal initialize of Sidekiq launcher.
|
17
|
+
def initialize(config, **kwargs)
|
18
|
+
config[:cron_poll_interval] = DEFAULT_POLL_INTERVAL if config[:cron_poll_interval].nil?
|
19
|
+
|
20
|
+
@cron_poller = Sidekiq::Cron::Poller.new(config) if config[:cron_poll_interval] > 0
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
# Execute normal run of launcher and run cron poller.
|
25
|
+
def run
|
26
|
+
super
|
27
|
+
cron_poller.start if @cron_poller
|
28
|
+
end
|
29
|
+
|
30
|
+
# Execute normal quiet of launcher and quiet cron poller.
|
31
|
+
def quiet
|
32
|
+
cron_poller.terminate if @cron_poller
|
33
|
+
super
|
34
|
+
end
|
35
|
+
|
36
|
+
# Execute normal stop of launcher and stop cron poller.
|
37
|
+
def stop
|
38
|
+
cron_poller.terminate if @cron_poller
|
39
|
+
super
|
40
|
+
end
|
42
41
|
end
|
42
|
+
end
|
43
|
+
end
|
43
44
|
|
44
|
-
|
45
|
-
|
45
|
+
Sidekiq.configure_server do
|
46
|
+
require 'sidekiq/launcher'
|
46
47
|
|
47
|
-
|
48
|
-
def stop
|
49
|
-
cron_poller.terminate
|
50
|
-
old_stop
|
51
|
-
end
|
52
|
-
end
|
48
|
+
::Sidekiq::Launcher.prepend(Sidekiq::Cron::Launcher)
|
53
49
|
end
|
@@ -5,9 +5,9 @@ de:
|
|
5
5
|
EnqueueNow: In Warteschlange
|
6
6
|
'Cron string': Cron
|
7
7
|
AreYouSureDeleteCronJob: Sind Sie sicher, dass sie den Cronjob %{job} löschen wollen?
|
8
|
-
|
8
|
+
NoCronJobsWereFound: Keine Cronjobs gefunden
|
9
9
|
Enable: Aktivieren
|
10
10
|
Disable: Deaktivieren
|
11
|
-
'Last
|
11
|
+
'Last enqueued': Eingereiht
|
12
12
|
disabled: deaktiviert
|
13
13
|
enabled: aktiviert
|
@@ -8,11 +8,15 @@ en:
|
|
8
8
|
EnqueueAll: Enqueue All
|
9
9
|
DeleteAll: Delete All
|
10
10
|
'Cron string': Cron
|
11
|
+
AreYouSureEnqueueCronJobs: Are you sure you want to enqueue ALL cron jobs?
|
12
|
+
AreYouSureEnqueueCronJob: Are you sure you want to enqueue the %{job} cron job?
|
11
13
|
AreYouSureDeleteCronJobs: Are you sure you want to delete ALL cron jobs?
|
12
14
|
AreYouSureDeleteCronJob: Are you sure you want to delete the %{job} cron job?
|
13
|
-
|
15
|
+
NoCronJobsWereFound: No cron jobs were found
|
14
16
|
Enable: Enable
|
15
17
|
Disable: Disable
|
16
|
-
'Last
|
18
|
+
'Last enqueued': Last enqueued
|
17
19
|
disabled: disabled
|
18
20
|
enabled: enabled
|
21
|
+
NoHistoryWereFound: No history were found
|
22
|
+
Description: Description
|
@@ -0,0 +1,23 @@
|
|
1
|
+
it:
|
2
|
+
Job: Job
|
3
|
+
Cron: Cron
|
4
|
+
CronJobs: Cron job
|
5
|
+
EnqueueNow: Accoda
|
6
|
+
EnableAll: Attiva tutto
|
7
|
+
DisableAll: Disattiva tutto
|
8
|
+
EnqueueAll: Accoda tutto
|
9
|
+
DeleteAll: Cancella tutto
|
10
|
+
"Cron string": Cron
|
11
|
+
AreYouSureEnqueueCronJobs: Vuoi accodare TUTTI i cron job?
|
12
|
+
AreYouSureEnqueueCronJob: "Vuoi accodare il cron job '%{job}'?"
|
13
|
+
AreYouSureDeleteCronJobs: Vuoi cancellare TUTTI i cron job?
|
14
|
+
AreYouSureDeleteCronJob: "Vuoi cancellare il cron job '%{job}'?"
|
15
|
+
NoCronJobsWereFound: Nessun cron job trovato
|
16
|
+
Enable: Attiva
|
17
|
+
Disable: Disattiva
|
18
|
+
"Last enqueued": Ultimo accodamento
|
19
|
+
disabled: disattivato
|
20
|
+
enabled: attivato
|
21
|
+
NoHistoryWereFound: Nessun evento in cronologia
|
22
|
+
Description: Descrizione
|
23
|
+
Message: Payload
|
@@ -0,0 +1,18 @@
|
|
1
|
+
ja:
|
2
|
+
Job: ジョブ
|
3
|
+
Cron: Cron
|
4
|
+
CronJobs: Cronジョブ
|
5
|
+
EnqueueNow: すぐにキューに入れる
|
6
|
+
EnableAll: すべて有効にする
|
7
|
+
DisableAll: すべて無効にする
|
8
|
+
EnqueueAll: すべてキューに入れる
|
9
|
+
DeleteAll: すべて削除
|
10
|
+
'Cron string': Cron
|
11
|
+
AreYouSureDeleteCronJobs: 本当にすべてのcronジョブを削除しますか?
|
12
|
+
AreYouSureDeleteCronJob: 本当に%{job}のcronジョブを削除しますか?
|
13
|
+
NoCronJobsWereFound: Cronジョブが見つかりませんでした
|
14
|
+
Enable: 有効にする
|
15
|
+
Disable: 無効にする
|
16
|
+
'Last enqueued': 最後のキュー
|
17
|
+
disabled: 無効
|
18
|
+
enabled: 有効
|
@@ -0,0 +1,22 @@
|
|
1
|
+
pt:
|
2
|
+
Job: Tarefa
|
3
|
+
Cron: Cron
|
4
|
+
CronJobs: Tarefas do Cron
|
5
|
+
EnqueueNow: Enfileirar agora
|
6
|
+
EnableAll: Habilitar todos
|
7
|
+
DisableAll: Desabilitar todos
|
8
|
+
EnqueueAll: Enfileirar todos
|
9
|
+
DeleteAll: Excluir todos
|
10
|
+
'Cron string': Cron
|
11
|
+
AreYouSureEnqueueCronJobs: Tem certeza de que deseja enfileirar TODOS as tarefas?
|
12
|
+
AreYouSureEnqueueCronJob: Tem certeza de que deseja enfileirar a tarefa %{job}?
|
13
|
+
AreYouSureDeleteCronJobs: Tem certeza de que deseja excluir TODOS as tarefas?
|
14
|
+
AreYouSureDeleteCronJob: Tem certeza de que deseja excluir a tarefa %{job}?
|
15
|
+
NoCronJobsWereFound: Nenhuma tarefa foi encontrada
|
16
|
+
Enable: Habilitar
|
17
|
+
Disable: Desabilitar
|
18
|
+
'Last enqueued': Último enfileirado
|
19
|
+
disabled: desabilitado
|
20
|
+
enabled: habilitado
|
21
|
+
NoHistoryWereFound: Nenhum histórico foi encontrado
|
22
|
+
Description: Descrição
|
@@ -6,9 +6,9 @@ ru:
|
|
6
6
|
'Cron string': Периодичность (синтаксис Cron)
|
7
7
|
EnqueueNow: Запустить
|
8
8
|
AreYouSureDeleteCronJob: Вы действительно хотите удалить задачу «%{job}»?
|
9
|
-
|
9
|
+
NoCronJobsWereFound: Не найдено периодических задач
|
10
10
|
Enable: Включить
|
11
11
|
Disable: Отключить
|
12
|
-
'Last
|
12
|
+
'Last enqueued': Последний запуск
|
13
13
|
disabled: отключено
|
14
14
|
enabled: включено
|
@@ -0,0 +1,19 @@
|
|
1
|
+
zh-CN:
|
2
|
+
Job: 任务
|
3
|
+
Cron: 定时任务
|
4
|
+
CronJobs: 定时任务列表
|
5
|
+
EnqueueNow: 立刻执行
|
6
|
+
EnableAll: 启用所有
|
7
|
+
DisableAll: 禁用所有
|
8
|
+
EnqueueAll: 执行所有
|
9
|
+
DeleteAll: 删除所有
|
10
|
+
'Cron string': 定时策略
|
11
|
+
AreYouSureDeleteCronJobs: 你确定删除所有的定时任务吗?
|
12
|
+
AreYouSureDeleteCronJob: 你确定删除定时任务(%{job})吗?
|
13
|
+
NoCronJobsWereFound: 没有定时任务
|
14
|
+
Enable: 启用
|
15
|
+
Disable: 禁用
|
16
|
+
'Last enqueued': 放入队列时间
|
17
|
+
disabled: 已禁用
|
18
|
+
enabled: 已启用
|
19
|
+
|
data/lib/sidekiq/cron/poller.rb
CHANGED
@@ -1,14 +1,22 @@
|
|
1
1
|
require 'sidekiq'
|
2
|
-
require 'sidekiq/util'
|
3
2
|
require 'sidekiq/cron'
|
4
3
|
require 'sidekiq/scheduled'
|
4
|
+
require 'sidekiq/options'
|
5
5
|
|
6
6
|
module Sidekiq
|
7
7
|
module Cron
|
8
|
-
|
9
|
-
|
10
|
-
# The Poller checks Redis every N seconds for sheduled cron jobs
|
8
|
+
# The Poller checks Redis every N seconds for sheduled cron jobs.
|
11
9
|
class Poller < Sidekiq::Scheduled::Poller
|
10
|
+
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
|
18
|
+
end
|
19
|
+
|
12
20
|
def enqueue
|
13
21
|
time = Time.now.utc
|
14
22
|
Sidekiq::Cron::Job.all.each do |job|
|
@@ -16,9 +24,10 @@ module Sidekiq
|
|
16
24
|
end
|
17
25
|
rescue => ex
|
18
26
|
# Most likely a problem with redis networking.
|
19
|
-
# Punt and try again at the next interval
|
20
|
-
logger.error ex.message
|
21
|
-
logger.error ex.backtrace.first
|
27
|
+
# Punt and try again at the next interval.
|
28
|
+
Sidekiq.logger.error ex.message
|
29
|
+
Sidekiq.logger.error ex.backtrace.first
|
30
|
+
handle_exception(ex) if respond_to?(:handle_exception)
|
22
31
|
end
|
23
32
|
|
24
33
|
private
|
@@ -26,13 +35,14 @@ module Sidekiq
|
|
26
35
|
def enqueue_job(job, time = Time.now.utc)
|
27
36
|
job.test_and_enque_for_time! time if job && job.valid?
|
28
37
|
rescue => ex
|
29
|
-
#
|
30
|
-
logger.error "CRON JOB: #{ex.message}"
|
31
|
-
logger.error "CRON JOB: #{ex.backtrace.first}"
|
38
|
+
# Problem somewhere in one job.
|
39
|
+
Sidekiq.logger.error "CRON JOB: #{ex.message}"
|
40
|
+
Sidekiq.logger.error "CRON JOB: #{ex.backtrace.first}"
|
41
|
+
handle_exception(ex) if respond_to?(:handle_exception)
|
32
42
|
end
|
33
43
|
|
34
|
-
def poll_interval_average
|
35
|
-
|
44
|
+
def poll_interval_average(process_count = 1)
|
45
|
+
@config[:cron_poll_interval]
|
36
46
|
end
|
37
47
|
end
|
38
48
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'sidekiq'
|
2
|
+
require 'sidekiq/cron/job'
|
3
|
+
require 'sidekiq/options'
|
4
|
+
|
5
|
+
if Sidekiq.server?
|
6
|
+
Sidekiq.configure_server do |config|
|
7
|
+
schedule_file = Sidekiq::Options[:cron_schedule_file] || 'config/schedule.yml'
|
8
|
+
|
9
|
+
if File.exist?(schedule_file)
|
10
|
+
config.on(:startup) do
|
11
|
+
schedule = Sidekiq::Cron::Support.load_yaml(ERB.new(IO.read(schedule_file)).result)
|
12
|
+
if schedule.kind_of?(Hash)
|
13
|
+
Sidekiq::Cron::Job.load_from_hash! schedule
|
14
|
+
elsif schedule.kind_of?(Array)
|
15
|
+
Sidekiq::Cron::Job.load_from_array! schedule
|
16
|
+
else
|
17
|
+
raise "Not supported schedule format. Confirm your #{schedule_file}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/sidekiq/cron/support.rb
CHANGED
@@ -28,11 +28,18 @@ module Sidekiq
|
|
28
28
|
const
|
29
29
|
end
|
30
30
|
|
31
|
-
# owner is in Object, so raise
|
32
31
|
constant.const_get(name, false)
|
33
32
|
end
|
34
33
|
end
|
35
34
|
end
|
35
|
+
|
36
|
+
def self.load_yaml(src)
|
37
|
+
if Psych::VERSION > "4.0"
|
38
|
+
YAML.safe_load(src, permitted_classes: [Symbol], aliases: true)
|
39
|
+
else
|
40
|
+
YAML.load(src)
|
41
|
+
end
|
42
|
+
end
|
36
43
|
end
|
37
44
|
end
|
38
45
|
end
|
@@ -1,24 +1,26 @@
|
|
1
1
|
<header class='row'>
|
2
2
|
<div class='col-sm-5 pull-left'>
|
3
|
-
<h3><%=t
|
3
|
+
<h3><%= t('CronJobs') %></h3>
|
4
4
|
</div>
|
5
5
|
<div class='col-sm-7 pull-right' style="margin-top: 20px; margin-bottom: 10px;">
|
6
|
-
|
7
|
-
<%=
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
<%=
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
<%=
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
<%=
|
20
|
-
|
21
|
-
|
6
|
+
<% if @cron_jobs.size > 0 %>
|
7
|
+
<form action="<%= root_path %>cron/__all__/delete" method="post" class="pull-right">
|
8
|
+
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
9
|
+
<input class="btn btn-danger" type="submit" name="delete" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSureDeleteCronJobs') %>" />
|
10
|
+
</form>
|
11
|
+
<form action="<%= root_path %>cron/__all__/disable" method="post" class="pull-right">
|
12
|
+
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
13
|
+
<input class="btn btn-warn" type="submit" name="enque" value="<%= t('DisableAll') %>" />
|
14
|
+
</form>
|
15
|
+
<form action="<%= root_path %>cron/__all__/enable" method="post" class="pull-right">
|
16
|
+
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
17
|
+
<input class="btn btn-warn" type="submit" name="enque" value="<%= t('EnableAll') %>" />
|
18
|
+
</form>
|
19
|
+
<form action="<%= root_path %>cron/__all__/enque" method="post" class="pull-right">
|
20
|
+
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
21
|
+
<input class="btn btn-warn" type="submit" name="enque" value="<%= t('EnqueueAll') %>" data-confirm="<%= t('AreYouSureEnqueueCronJobs') %>" />
|
22
|
+
</form>
|
23
|
+
<% end %>
|
22
24
|
</div>
|
23
25
|
</header>
|
24
26
|
|
@@ -29,23 +31,31 @@
|
|
29
31
|
<th><%= t('Status') %></th>
|
30
32
|
<th><%= t('Name') %></th>
|
31
33
|
<th><%= t('Cron string') %></th>
|
32
|
-
<th><%= t('Last
|
34
|
+
<th><%= t('Last enqueued') %></th>
|
33
35
|
<th width="180"><%= t('Actions')%></th>
|
34
36
|
</thead>
|
35
37
|
|
36
38
|
<tbody>
|
37
39
|
<% @cron_jobs.sort{|a,b| a.sort_name <=> b.sort_name }.each_with_index do |job, index| %>
|
38
|
-
<% style = "#{job.status == 'disabled' ? "background: #ecc": ""}" %>
|
40
|
+
<% style = "#{job.status == 'disabled' ? "background: #ecc; color: #585454;": ""}" %>
|
39
41
|
<tr>
|
40
42
|
<td style="<%= style %>"><%= t job.status %></td>
|
41
43
|
<td style="<%= style %>">
|
42
|
-
<
|
44
|
+
<a href="<%= root_path %>cron/<%= CGI.escape(job.name).gsub('+', '%20') %>">
|
45
|
+
<b style="<%= style %>"><%= job.name %></b>
|
46
|
+
</a>
|
43
47
|
<hr style="margin:3px;border:0;">
|
44
48
|
<small>
|
45
49
|
<% if job.message and job.message.to_s.size > 100 %>
|
46
|
-
|
47
|
-
|
48
|
-
|
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 %>
|
49
59
|
<% else %>
|
50
60
|
<%= job.message %>
|
51
61
|
<% end %>
|
@@ -57,20 +67,20 @@
|
|
57
67
|
<% if job.status == 'enabled' %>
|
58
68
|
<form action="<%= root_path %>cron/<%= CGI.escape(job.name).gsub('+', '%20') %>/enque" method="post">
|
59
69
|
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
60
|
-
<input class='btn btn-xs pull-left' type="submit" name="enque" value="<%= t('EnqueueNow') %>"/>
|
70
|
+
<input class='btn btn-warn btn-xs pull-left' type="submit" name="enque" value="<%= t('EnqueueNow') %>" data-confirm="<%= t('AreYouSureEnqueueCronJob', :job => job.name) %>"/>
|
61
71
|
</form>
|
62
72
|
<form action="<%= root_path %>cron/<%= CGI.escape(job.name).gsub('+', '%20') %>/disable" method="post">
|
63
73
|
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
64
|
-
<input class='btn btn-xs pull-left' type="submit" name="disable" value="<%= t('Disable') %>"/>
|
74
|
+
<input class='btn btn-warn btn-xs pull-left' type="submit" name="disable" value="<%= t('Disable') %>"/>
|
65
75
|
</form>
|
66
76
|
<% else %>
|
67
77
|
<form action="<%= root_path %>cron/<%= CGI.escape(job.name).gsub('+', '%20') %>/enque" method="post">
|
68
78
|
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
69
|
-
<input class='btn btn-xs pull-left' type="submit" name="enque" value="<%= t('EnqueueNow') %>"/>
|
79
|
+
<input class='btn btn-warn btn-xs pull-left' type="submit" name="enque" value="<%= t('EnqueueNow') %>"/>
|
70
80
|
</form>
|
71
81
|
<form action="<%= root_path %>cron/<%= CGI.escape(job.name).gsub('+', '%20') %>/enable" method="post">
|
72
82
|
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
73
|
-
<input class='btn btn-xs pull-left' type="submit" name="enable" value="<%= t('Enable') %>"/>
|
83
|
+
<input class='btn btn-warn btn-xs pull-left' type="submit" name="enable" value="<%= t('Enable') %>"/>
|
74
84
|
</form>
|
75
85
|
<form action="<%= root_path %>cron/<%= CGI.escape(job.name).gsub('+', '%20') %>/delete" method="post">
|
76
86
|
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
@@ -83,6 +93,6 @@
|
|
83
93
|
</tbody>
|
84
94
|
</table>
|
85
95
|
<% else %>
|
86
|
-
<
|
96
|
+
<div class='alert alert-success'><%= t('NoCronJobsWereFound') %></div>
|
87
97
|
<% end %>
|
88
98
|
|
@@ -0,0 +1,88 @@
|
|
1
|
+
<header class="row">
|
2
|
+
<div class="span col-sm-5 pull-left">
|
3
|
+
<h3>
|
4
|
+
<%= "#{t('Cron')} #{t('Job')}" %>
|
5
|
+
<small><%= @job.name %></small>
|
6
|
+
</h3>
|
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">
|
11
|
+
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
12
|
+
<input class="btn btn-warn pull-left" name="enque" type="submit" value="<%= t('EnqueueNow') %>" data-confirm="<%= t('AreYouSureEnqueueCronJob', :job => @job.name) %>" />
|
13
|
+
</form>
|
14
|
+
<% if @job.status == 'enabled' %>
|
15
|
+
<form action="<%= cron_job_path %>/disable?redirect=<%= cron_job_path %>" method="post">
|
16
|
+
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
17
|
+
<input class="btn btn-warn pull-left" name="disable" type="submit" value="<%= t('Disable') %>" />
|
18
|
+
</form>
|
19
|
+
<% else %>
|
20
|
+
<form action="<%= cron_job_path %>/enable?redirect=<%= cron_job_path %>" method="post">
|
21
|
+
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
22
|
+
<input class="btn btn-warn pull-left" name="enable" type="submit" value="<%= t('Enable') %>" />
|
23
|
+
</form>
|
24
|
+
<form action="<%= cron_job_path %>/delete" method="post">
|
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') %>" />
|
27
|
+
</form>
|
28
|
+
<% end %>
|
29
|
+
</div>
|
30
|
+
</header>
|
31
|
+
|
32
|
+
<table class="table table-bordered table-striped">
|
33
|
+
<tbody>
|
34
|
+
<tr>
|
35
|
+
<th><%= t 'Status' %></th>
|
36
|
+
<td><%= @job.status %></td>
|
37
|
+
</tr>
|
38
|
+
<tr>
|
39
|
+
<th><%= t 'Name' %></th>
|
40
|
+
<td><%= @job.name %></td>
|
41
|
+
</tr>
|
42
|
+
<tr>
|
43
|
+
<th><%= t 'Description' %></th>
|
44
|
+
<td><%= @job.description %></td>
|
45
|
+
</tr>
|
46
|
+
<tr>
|
47
|
+
<th><%= t 'Message' %></th>
|
48
|
+
<td><pre><%= @job.pretty_message %></pre></td>
|
49
|
+
</tr>
|
50
|
+
<tr>
|
51
|
+
<th><%= t 'Cron' %></th>
|
52
|
+
<td><%= @job.cron.gsub(" ", " ") %></td>
|
53
|
+
</tr>
|
54
|
+
<tr>
|
55
|
+
<th><%= t 'Last enqueued' %></th>
|
56
|
+
<td><%= @job.last_enqueue_time ? relative_time(@job.last_enqueue_time) : "-" %></td>
|
57
|
+
</tr>
|
58
|
+
</tbody>
|
59
|
+
</table>
|
60
|
+
|
61
|
+
<header class="row">
|
62
|
+
<div class="col-sm-12">
|
63
|
+
<h4>
|
64
|
+
<%= t 'History' %>
|
65
|
+
</h4>
|
66
|
+
</div>
|
67
|
+
</header>
|
68
|
+
|
69
|
+
<% if @job.jid_history_from_redis.size > 0 %>
|
70
|
+
<table class="table table-hover table-bordered table-striped">
|
71
|
+
<thead>
|
72
|
+
<tr>
|
73
|
+
<th><%= t 'Enqueued' %></th>
|
74
|
+
<th><%= t 'JID' %></th>
|
75
|
+
</tr>
|
76
|
+
</thead>
|
77
|
+
<tbody>
|
78
|
+
<% @job.jid_history_from_redis.each do |jid_history| %>
|
79
|
+
<tr>
|
80
|
+
<td><%= jid_history['enqueued'] %></td>
|
81
|
+
<td><%= jid_history['jid'] %></td>
|
82
|
+
</tr>
|
83
|
+
<% end %>
|
84
|
+
</tbody>
|
85
|
+
</table>
|
86
|
+
<% else %>
|
87
|
+
<div class='alert alert-success'><%= t 'NoHistoryWereFound' %></div>
|
88
|
+
<% end %>
|
data/lib/sidekiq/cron/web.rb
CHANGED
@@ -3,11 +3,5 @@ require "sidekiq/cron/job"
|
|
3
3
|
|
4
4
|
if defined?(Sidekiq::Web)
|
5
5
|
Sidekiq::Web.register Sidekiq::Cron::WebExtension
|
6
|
-
|
7
|
-
if Sidekiq::Web.tabs.is_a?(Array)
|
8
|
-
# For sidekiq < 2.5
|
9
|
-
Sidekiq::Web.tabs << "cron"
|
10
|
-
else
|
11
|
-
Sidekiq::Web.tabs["Cron"] = "cron"
|
12
|
-
end
|
6
|
+
Sidekiq::Web.tabs["Cron"] = "cron"
|
13
7
|
end
|
@@ -1,36 +1,41 @@
|
|
1
1
|
module Sidekiq
|
2
2
|
module Cron
|
3
3
|
module WebExtension
|
4
|
-
|
5
4
|
def self.registered(app)
|
6
|
-
|
7
5
|
app.settings.locales << File.join(File.expand_path("..", __FILE__), "locales")
|
8
6
|
|
9
|
-
#
|
7
|
+
# Index page of cron jobs.
|
10
8
|
app.get '/cron' do
|
11
9
|
view_path = File.join(File.expand_path("..", __FILE__), "views")
|
12
10
|
|
13
11
|
@cron_jobs = Sidekiq::Cron::Job.all
|
14
12
|
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
render(:erb, File.read(File.join(view_path, "cron.erb")))
|
14
|
+
end
|
15
|
+
|
16
|
+
# Display job detail + jid history.
|
17
|
+
app.get '/cron/:name' do
|
18
|
+
view_path = File.join(File.expand_path("..", __FILE__), "views")
|
19
|
+
|
20
|
+
@job = Sidekiq::Cron::Job.find(route_params[:name])
|
21
|
+
if @job
|
22
|
+
render(:erb, File.read(File.join(view_path, "cron_show.erb")))
|
18
23
|
else
|
19
|
-
|
24
|
+
redirect "#{root_path}cron"
|
20
25
|
end
|
21
26
|
end
|
22
27
|
|
23
|
-
#
|
28
|
+
# Enqueue cron job.
|
24
29
|
app.post '/cron/:name/enque' do
|
25
30
|
if route_params[:name] === '__all__'
|
26
31
|
Sidekiq::Cron::Job.all.each(&:enque!)
|
27
32
|
elsif job = Sidekiq::Cron::Job.find(route_params[:name])
|
28
33
|
job.enque!
|
29
34
|
end
|
30
|
-
redirect "#{root_path}cron"
|
35
|
+
redirect params['redirect'] || "#{root_path}cron"
|
31
36
|
end
|
32
37
|
|
33
|
-
#
|
38
|
+
# Delete schedule.
|
34
39
|
app.post '/cron/:name/delete' do
|
35
40
|
if route_params[:name] === '__all__'
|
36
41
|
Sidekiq::Cron::Job.all.each(&:destroy)
|
@@ -40,26 +45,25 @@ module Sidekiq
|
|
40
45
|
redirect "#{root_path}cron"
|
41
46
|
end
|
42
47
|
|
43
|
-
#
|
48
|
+
# Enable job.
|
44
49
|
app.post '/cron/:name/enable' do
|
45
50
|
if route_params[:name] === '__all__'
|
46
51
|
Sidekiq::Cron::Job.all.each(&:enable!)
|
47
52
|
elsif job = Sidekiq::Cron::Job.find(route_params[:name])
|
48
53
|
job.enable!
|
49
54
|
end
|
50
|
-
redirect "#{root_path}cron"
|
55
|
+
redirect params['redirect'] || "#{root_path}cron"
|
51
56
|
end
|
52
57
|
|
53
|
-
#
|
58
|
+
# Disable job.
|
54
59
|
app.post '/cron/:name/disable' do
|
55
60
|
if route_params[:name] === '__all__'
|
56
61
|
Sidekiq::Cron::Job.all.each(&:disable!)
|
57
62
|
elsif job = Sidekiq::Cron::Job.find(route_params[:name])
|
58
63
|
job.disable!
|
59
64
|
end
|
60
|
-
redirect "#{root_path}cron"
|
65
|
+
redirect params['redirect'] || "#{root_path}cron"
|
61
66
|
end
|
62
|
-
|
63
67
|
end
|
64
68
|
end
|
65
69
|
end
|