tasks_scheduler 0.2.2 → 0.4.2
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 +4 -4
- data/Rakefile +3 -1
- data/app/controllers/scheduled_tasks_controller.rb +5 -4
- data/app/controllers/tasks_scheduler_daemon_controller.rb +8 -23
- data/app/controllers/tasks_scheduler_daemon_controller/_download_log.rb +42 -0
- data/app/helpers/scheduled_tasks_helper.rb +2 -0
- data/app/models/scheduled_task.rb +26 -9
- data/app/models/scheduled_task/checker.rb +14 -6
- data/app/models/scheduled_task/log.rb +8 -2
- data/app/models/scheduled_task/runner.rb +9 -5
- data/app/models/scheduled_task/status.rb +8 -4
- data/app/views/scheduled_tasks/status_content.html.erb +1 -0
- data/app/views/tasks_scheduler_daemon/_daemon.html.erb +11 -0
- data/app/views/tasks_scheduler_daemon/_logs.html.erb +12 -0
- data/app/views/tasks_scheduler_daemon/_results.html.erb +9 -0
- data/app/views/tasks_scheduler_daemon/_running_status.html.erb +0 -1
- data/app/views/tasks_scheduler_daemon/index.html.erb +3 -20
- data/config/initializers/assets.rb +3 -1
- data/config/routes.rb +4 -2
- data/db/migrate/20161122123828_create_scheduled_tasks.rb +5 -1
- data/db/migrate/20161123130153_add_status_attributes_to_scheduled_tasks.rb +5 -1
- data/db/migrate/20161124200712_add_pid_to_scheduled_tasks.rb +5 -1
- data/db/migrate/20161128163702_add_args_to_scheduled_tasks.rb +5 -1
- data/db/migrate/20180223155025_add_last_fail_status_to_scheduled_tasks.rb +5 -1
- data/db/migrate/20180302170138_add_enabled_to_scheduled_tasks.rb +5 -1
- data/exe/tasks_scheduler +7 -3
- data/exe/tasks_scheduler_run_task +3 -1
- data/lib/tasks_scheduler.rb +4 -8
- data/lib/tasks_scheduler/app_gem.rb +18 -0
- data/lib/tasks_scheduler/checker.rb +23 -4
- data/lib/tasks_scheduler/checker/log.rb +34 -0
- data/lib/tasks_scheduler/cron_parser_patch.rb +5 -1
- data/lib/tasks_scheduler/cron_scheduling_validator.rb +3 -0
- data/lib/tasks_scheduler/daemon.rb +20 -13
- data/lib/tasks_scheduler/engine.rb +5 -0
- data/lib/tasks_scheduler/version.rb +3 -1
- data/test/dummy/Rakefile +3 -1
- data/test/dummy/app/controllers/application_controller.rb +2 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/bin/bundle +3 -1
- data/test/dummy/bin/rails +3 -1
- data/test/dummy/bin/rake +2 -0
- data/test/dummy/bin/setup +3 -1
- data/test/dummy/config.ru +2 -0
- data/test/dummy/config/application.rb +3 -1
- data/test/dummy/config/boot.rb +4 -2
- data/test/dummy/config/environment.rb +3 -1
- data/test/dummy/config/environments/development.rb +2 -0
- data/test/dummy/config/environments/production.rb +2 -0
- data/test/dummy/config/environments/test.rb +2 -0
- data/test/dummy/config/initializers/assets.rb +2 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +1 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +2 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +2 -0
- data/test/dummy/config/initializers/inflections.rb +1 -0
- data/test/dummy/config/initializers/mime_types.rb +1 -0
- data/test/dummy/config/initializers/session_store.rb +2 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +2 -0
- data/test/dummy/config/routes.rb +2 -0
- data/test/models/scheduled_task_test.rb +6 -4
- data/test/test_helper.rb +6 -4
- metadata +52 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9a16067c62acba647e2e5d6b0ba72aefd8e394766242c7aa7222cdc26efa515d
|
4
|
+
data.tar.gz: 15605017849c697fe146a8ac1ad69981846c5ebb1aa4b54fc8d0695d555f498c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f850e1b47685482e850d93b61a49339fae6f508f25b042e960d8da8f9fb78f50b3d46f84acf8049db43b0a675de91485335f3f04df3575b9345f6fb58a652be0
|
7
|
+
data.tar.gz: d0d33e8ba43ca019a9f4ec70aeb614cfd53c3693f1f5b86c4cf705ef69a62e98ec9d90e11ec7654fc5573e8c61fbd2e943fc1571ec66d9877133823e7ff97022
|
data/Rakefile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
begin
|
2
4
|
require 'bundler/setup'
|
3
5
|
rescue LoadError
|
@@ -14,7 +16,7 @@ RDoc::Task.new(:rdoc) do |rdoc|
|
|
14
16
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
17
|
end
|
16
18
|
|
17
|
-
APP_RAKEFILE = File.expand_path('
|
19
|
+
APP_RAKEFILE = File.expand_path('test/dummy/Rakefile', __dir__)
|
18
20
|
load 'rails/tasks/engine.rake'
|
19
21
|
|
20
22
|
load 'rails/tasks/statistics.rake'
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class ScheduledTasksController < ApplicationController
|
2
4
|
class << self
|
3
5
|
private
|
@@ -8,7 +10,7 @@ class ScheduledTasksController < ApplicationController
|
|
8
10
|
end
|
9
11
|
|
10
12
|
active_scaffold :scheduled_task do |conf|
|
11
|
-
[
|
13
|
+
%i[create update list].each do |action|
|
12
14
|
conf.send(action).columns.exclude(:next_run, :last_fail_status, :last_run_start,
|
13
15
|
:last_run_successful_start, :last_run_unsuccessful_start,
|
14
16
|
:last_run_successful_end, :last_run_unsuccessful_end,
|
@@ -26,8 +28,7 @@ class ScheduledTasksController < ApplicationController
|
|
26
28
|
@log_file = record.log_file(params[:identifier])
|
27
29
|
end
|
28
30
|
|
29
|
-
def status
|
30
|
-
end
|
31
|
+
def status; end
|
31
32
|
|
32
33
|
def status_content
|
33
34
|
@scheduled_tasks = ::ScheduledTask.order(task: :asc, scheduling: :asc)
|
@@ -36,7 +37,7 @@ class ScheduledTasksController < ApplicationController
|
|
36
37
|
|
37
38
|
def run_now
|
38
39
|
process_action_link_action do |record|
|
39
|
-
record.
|
40
|
+
record.update!(next_run: Time.zone.now)
|
40
41
|
record.reload
|
41
42
|
flash[:info] = "Next run adjusted to #{record.next_run}"
|
42
43
|
end
|
@@ -1,6 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'tasks_scheduler/checker'
|
4
|
+
|
1
5
|
class TasksSchedulerDaemonController < ApplicationController
|
2
|
-
|
3
|
-
|
6
|
+
require_relative 'tasks_scheduler_daemon_controller/_download_log'
|
7
|
+
|
8
|
+
def index; end
|
4
9
|
|
5
10
|
def execute
|
6
11
|
@result = ::TasksScheduler::Daemon.execute(params[:tasks_scheduler_execute_action])
|
@@ -9,26 +14,6 @@ class TasksSchedulerDaemonController < ApplicationController
|
|
9
14
|
|
10
15
|
def status
|
11
16
|
render json: { daemon_running: ::TasksScheduler::Daemon.running?,
|
12
|
-
tasks_all_ok:
|
13
|
-
end
|
14
|
-
|
15
|
-
def download_log
|
16
|
-
if File.exist?(::TasksScheduler::Checker.instance.log_path)
|
17
|
-
send_log_file
|
18
|
-
else
|
19
|
-
redirect_to(tasks_scheduler_daemon_path,
|
20
|
-
notice: "Arquivo \"#{::TasksScheduler::Checker.instance.log_path}\" não existe")
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
def send_log_file
|
27
|
-
send_file(
|
28
|
-
::TasksScheduler::Checker.instance.log_path,
|
29
|
-
filename: "#{request.base_url.parameterize}_tasks-scheduler_checker-log_" \
|
30
|
-
"#{Time.zone.now.to_s.parameterize}.log",
|
31
|
-
type: 'text/plain'
|
32
|
-
)
|
17
|
+
tasks_all_ok: ::ScheduledTask.all.none?(&:failed?) }
|
33
18
|
end
|
34
19
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class TasksSchedulerDaemonController < ApplicationController
|
4
|
+
def download_log
|
5
|
+
return unless download_log_validate_log_key
|
6
|
+
|
7
|
+
log = ::TasksScheduler::Checker.instance.send("#{download_log_key}_log")
|
8
|
+
return unless download_log_validate_log_exist(log)
|
9
|
+
|
10
|
+
send_log_file(log)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def download_log_key
|
16
|
+
params[:log_key]
|
17
|
+
end
|
18
|
+
|
19
|
+
def download_log_validate_log_key
|
20
|
+
return true if ::TasksScheduler::Checker::LOGS_KEYS.include?(download_log_key)
|
21
|
+
|
22
|
+
redirect_to(tasks_scheduler_daemon_path,
|
23
|
+
notice: "Invalid log key: \"#{download_log_key}\"")
|
24
|
+
false
|
25
|
+
end
|
26
|
+
|
27
|
+
def download_log_validate_log_exist(log)
|
28
|
+
return true if log.exist?
|
29
|
+
|
30
|
+
redirect_to(tasks_scheduler_daemon_path, notice: "Log \"#{log.key}\" does not exist.")
|
31
|
+
false
|
32
|
+
end
|
33
|
+
|
34
|
+
def send_log_file(log)
|
35
|
+
send_file(
|
36
|
+
log.path,
|
37
|
+
filename: "#{request.base_url.parameterize}_tasks-scheduler_checker-log_" \
|
38
|
+
"#{Time.zone.now.to_s.parameterize}.log",
|
39
|
+
type: 'text/plain'
|
40
|
+
)
|
41
|
+
end
|
42
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rake'
|
2
4
|
|
3
5
|
class ScheduledTask < ActiveRecord::Base
|
@@ -6,7 +8,7 @@ class ScheduledTask < ActiveRecord::Base
|
|
6
8
|
include ::ScheduledTask::Runner
|
7
9
|
include ::ScheduledTask::Status
|
8
10
|
|
9
|
-
DEFAULT_TIMEOUT_ENVVAR_NAME = 'TASKS_SCHEDULER_TIMEOUT'
|
11
|
+
DEFAULT_TIMEOUT_ENVVAR_NAME = 'TASKS_SCHEDULER_TIMEOUT'
|
10
12
|
DEFAULT_TIMEOUT = 12.hours
|
11
13
|
|
12
14
|
class << self
|
@@ -20,9 +22,9 @@ class ScheduledTask < ActiveRecord::Base
|
|
20
22
|
def timeout
|
21
23
|
@timeout ||= begin
|
22
24
|
r = Integer(ENV[DEFAULT_TIMEOUT_ENVVAR_NAME])
|
23
|
-
r
|
24
|
-
|
25
|
-
|
25
|
+
r.positive? ? r.seconds : DEFAULT_TIMEOUT
|
26
|
+
rescue ArgumentError, TypeError
|
27
|
+
DEFAULT_TIMEOUT
|
26
28
|
end
|
27
29
|
end
|
28
30
|
end
|
@@ -34,12 +36,14 @@ class ScheduledTask < ActiveRecord::Base
|
|
34
36
|
STATUS_TIMEOUT = 'timeout'
|
35
37
|
STATUS_DISABLED = 'disabled'
|
36
38
|
|
37
|
-
LAST_FAIL_STATUSES = [STATUS_FAILED, STATUS_ABORTED, STATUS_TIMEOUT]
|
39
|
+
LAST_FAIL_STATUSES = [STATUS_FAILED, STATUS_ABORTED, STATUS_TIMEOUT].freeze
|
38
40
|
|
39
41
|
validates :scheduling, presence: true, 'tasks_scheduler/cron_scheduling': true
|
40
|
-
validates :task, presence: true
|
42
|
+
validates :task, presence: true
|
41
43
|
validates :last_fail_status, allow_blank: true, inclusion: { in: LAST_FAIL_STATUSES }
|
42
44
|
|
45
|
+
validate :validate_task
|
46
|
+
|
43
47
|
LOG_RUNNING = 'running'
|
44
48
|
LOG_SUCCESSFUL = 'successful'
|
45
49
|
LOG_UNSUCCESSFUL = 'unsuccessful'
|
@@ -67,13 +71,26 @@ class ScheduledTask < ActiveRecord::Base
|
|
67
71
|
|
68
72
|
def process_running?
|
69
73
|
return false if pid.nil?
|
74
|
+
|
70
75
|
Process.kill(0, pid)
|
71
|
-
|
76
|
+
true
|
72
77
|
rescue Errno::EPERM
|
73
78
|
raise "No permission to query #{pid}!"
|
74
79
|
rescue Errno::ESRCH
|
75
|
-
|
76
|
-
rescue
|
80
|
+
false
|
81
|
+
rescue StandardError
|
77
82
|
raise "Unable to determine status for #{pid}"
|
78
83
|
end
|
84
|
+
|
85
|
+
def task_exist?
|
86
|
+
self.class.rake_tasks.include?(task)
|
87
|
+
end
|
88
|
+
|
89
|
+
def validate_task
|
90
|
+
return if task.blank?
|
91
|
+
return unless task_changed?
|
92
|
+
return if self.class.rake_tasks.include?(task)
|
93
|
+
|
94
|
+
errors.add(:task, "Task \"#{task}\" not found")
|
95
|
+
end
|
79
96
|
end
|
@@ -1,4 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rake'
|
4
|
+
require 'eac_ruby_utils/ruby'
|
2
5
|
|
3
6
|
class ScheduledTask < ActiveRecord::Base
|
4
7
|
module Checker
|
@@ -34,6 +37,7 @@ class ScheduledTask < ActiveRecord::Base
|
|
34
37
|
|
35
38
|
def check_on_pid_not_present
|
36
39
|
return unless enabled?
|
40
|
+
|
37
41
|
if next_run.present?
|
38
42
|
check_task_with_next_run
|
39
43
|
else
|
@@ -55,12 +59,14 @@ class ScheduledTask < ActiveRecord::Base
|
|
55
59
|
|
56
60
|
def check_task_without_next_run
|
57
61
|
check_log('Next run blank')
|
58
|
-
|
62
|
+
update!(next_run: calculate_next_run)
|
59
63
|
check_log("Next run scheduled: #{next_run.in_time_zone}")
|
60
64
|
end
|
61
65
|
|
62
66
|
def check_task_with_next_run
|
63
|
-
if
|
67
|
+
if !task_exist?
|
68
|
+
check_log("Task does not exist: #{task}")
|
69
|
+
elsif next_run < Time.zone.now
|
64
70
|
check_log('Next run reached. Running...')
|
65
71
|
spawn_task
|
66
72
|
else
|
@@ -70,13 +76,15 @@ class ScheduledTask < ActiveRecord::Base
|
|
70
76
|
|
71
77
|
def spawn_task
|
72
78
|
params = ['bundle', 'exec', 'tasks_scheduler_run_task', id.to_s]
|
73
|
-
check_log("Spawn command: #{params}")
|
79
|
+
check_log("Spawn command: #{params} (Task: #{task})")
|
74
80
|
spawn_pid = nil
|
75
|
-
|
76
|
-
|
81
|
+
::EacRubyUtils::Ruby.on_clean_environment do
|
82
|
+
Dir.chdir(Rails.root) do
|
83
|
+
spawn_pid = ::Process.spawn(*params)
|
84
|
+
end
|
77
85
|
end
|
78
86
|
Process.detach(spawn_pid)
|
79
|
-
|
87
|
+
update!(pid: spawn_pid, last_fail_status: nil)
|
80
88
|
end
|
81
89
|
|
82
90
|
def timeout?
|
@@ -1,9 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class ScheduledTask < ActiveRecord::Base
|
2
4
|
module Log
|
3
5
|
def log_file(identifier)
|
4
6
|
unless log_identifiers.include?(identifier)
|
5
|
-
|
7
|
+
raise "Log identifier unknown: \"#{identifier}\" (Valid: #{log_identifiers})"
|
6
8
|
end
|
9
|
+
|
7
10
|
Rails.root.join('log', 'tasks_scheduler', "#{id}_#{identifier}.log")
|
8
11
|
end
|
9
12
|
|
@@ -23,9 +26,12 @@ class ScheduledTask < ActiveRecord::Base
|
|
23
26
|
end
|
24
27
|
|
25
28
|
def log_on_end(exception)
|
29
|
+
running_log = log_file(LOG_RUNNING)
|
30
|
+
return unless ::File.exist?(running_log)
|
31
|
+
|
26
32
|
target_log = exception ? log_file(LOG_UNSUCCESSFUL) : log_file(LOG_SUCCESSFUL)
|
27
33
|
File.unlink(target_log) if File.exist?(target_log)
|
28
|
-
File.rename(
|
34
|
+
File.rename(running_log, target_log)
|
29
35
|
end
|
30
36
|
end
|
31
37
|
end
|
@@ -1,9 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class ScheduledTask < ActiveRecord::Base
|
2
4
|
module Runner
|
3
5
|
def run
|
4
6
|
log_on_start
|
5
7
|
run_banner
|
6
8
|
return if process_running? && pid != Process.pid
|
9
|
+
|
7
10
|
status_on_start
|
8
11
|
exception = invoke_task
|
9
12
|
on_end_running(exception, STATUS_FAILED)
|
@@ -33,7 +36,7 @@ class ScheduledTask < ActiveRecord::Base
|
|
33
36
|
|
34
37
|
def run_banner
|
35
38
|
run_log("Task: #{self}")
|
36
|
-
run_log("PID: #{pid
|
39
|
+
run_log("PID: #{pid || '-'} (Current: #{Process.pid})")
|
37
40
|
run_log("Process running? #{process_running? ? 'Yes' : 'No'}")
|
38
41
|
run_log("Rails.env: #{Rails.env}")
|
39
42
|
end
|
@@ -44,15 +47,16 @@ class ScheduledTask < ActiveRecord::Base
|
|
44
47
|
Rake::Task.clear
|
45
48
|
Rails.application.load_tasks
|
46
49
|
Rake::Task[task].invoke(*invoke_args)
|
47
|
-
rescue StandardError =>
|
48
|
-
run_log(
|
49
|
-
exception =
|
50
|
+
rescue StandardError => e
|
51
|
+
run_log(e, :fatal)
|
52
|
+
exception = e
|
50
53
|
end
|
51
54
|
exception
|
52
55
|
end
|
53
56
|
|
54
57
|
def invoke_args
|
55
|
-
return []
|
58
|
+
return [] if args.blank?
|
59
|
+
|
56
60
|
args.split('|')
|
57
61
|
end
|
58
62
|
end
|
@@ -1,10 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class ScheduledTask < ActiveRecord::Base
|
2
4
|
module Status
|
3
5
|
def status
|
4
6
|
return STATUS_DISABLED unless enabled?
|
5
7
|
return STATUS_RUNNING if running?
|
6
8
|
return STATUS_WAITING if waiting?
|
7
|
-
|
9
|
+
|
10
|
+
last_fail_status.presence || STATUS_FAILED
|
8
11
|
end
|
9
12
|
|
10
13
|
def failed?
|
@@ -17,6 +20,7 @@ class ScheduledTask < ActiveRecord::Base
|
|
17
20
|
|
18
21
|
def waiting?
|
19
22
|
return true if ended?(last_run_successful_end, last_run_unsuccessful_end)
|
23
|
+
|
20
24
|
status_attributes.all? { |a| send(a).blank? }
|
21
25
|
end
|
22
26
|
|
@@ -27,11 +31,11 @@ class ScheduledTask < ActiveRecord::Base
|
|
27
31
|
end
|
28
32
|
|
29
33
|
def status_on_start
|
30
|
-
|
34
|
+
update!(last_run_start: Time.zone.now)
|
31
35
|
end
|
32
36
|
|
33
37
|
def status_on_end(exception, last_fail_status)
|
34
|
-
|
38
|
+
update!(
|
35
39
|
next_run: calculate_next_run,
|
36
40
|
(exception ? :last_run_unsuccessful_start : :last_run_successful_start) => last_run_start,
|
37
41
|
(exception ? :last_run_unsuccessful_end : :last_run_successful_end) => Time.zone.now,
|
@@ -42,7 +46,7 @@ class ScheduledTask < ActiveRecord::Base
|
|
42
46
|
end
|
43
47
|
|
44
48
|
def status_attributes
|
45
|
-
%w
|
49
|
+
%w[start successful_start successful_end unsuccessful_start unsuccessful_end].map do |a|
|
46
50
|
"last_run_#{a}"
|
47
51
|
end
|
48
52
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<h3>Daemon</h3>
|
2
|
+
<p>
|
3
|
+
<strong>Status: </strong>
|
4
|
+
<%= render partial: '/tasks_scheduler_daemon/running_status' %>
|
5
|
+
<br/>
|
6
|
+
<strong>Actions: </strong>
|
7
|
+
<%= safe_join(::TasksScheduler::Daemon::ACTIONS.map do |action|
|
8
|
+
link_to action, execute_tasks_scheduler_daemon_path(action), method: :post
|
9
|
+
end, ' | ') %>
|
10
|
+
<br/>
|
11
|
+
</p>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<h3>Logs</h3>
|
2
|
+
<ul>
|
3
|
+
<% ::TasksScheduler::Checker.instance.logs.each do |log| %>
|
4
|
+
<li>
|
5
|
+
<% if log.exist? %>
|
6
|
+
<%= link_to log.key, download_log_tasks_scheduler_daemon_path(log.key) %>
|
7
|
+
<% else %>
|
8
|
+
<span style="color: grey" title='Log "<%= log.key %>" does not exist.'><%= log.key %></span>
|
9
|
+
<% end %>
|
10
|
+
</li>
|
11
|
+
<% end %>
|
12
|
+
</ul>
|
@@ -1,22 +1,5 @@
|
|
1
1
|
<%= render partial: '/tasks_scheduler/navbar' %>
|
2
2
|
<h2><%= I18n.t(:tasks_scheduler_daemon) %></h2>
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
<strong>Actions: </strong>
|
7
|
-
<%= safe_join(::TasksScheduler::Daemon::ACTIONS.map do |action|
|
8
|
-
link_to action, execute_tasks_scheduler_daemon_path(action), method: :post
|
9
|
-
end, ' | ') %>
|
10
|
-
<br/>
|
11
|
-
<strong>Log: </strong>
|
12
|
-
<%= link_to 'download', download_log_tasks_scheduler_daemon_path %>
|
13
|
-
</p>
|
14
|
-
<% if @result %>
|
15
|
-
<h3>Results</h3>
|
16
|
-
<dl>
|
17
|
-
<% @result.each do |k, v| %>
|
18
|
-
<dt><%= k %></dt>
|
19
|
-
<dd><%= v.present? ? v : '-' %></dd>
|
20
|
-
<% end %>
|
21
|
-
</dl>
|
22
|
-
<% end %>
|
3
|
+
<%= render partial: 'daemon', locals: {status_label: 'Status:'} %>
|
4
|
+
<%= render partial: 'logs' %>
|
5
|
+
<%= render partial: 'results' %>
|
data/config/routes.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
Rails.application.routes.draw do
|
2
4
|
resources(:scheduled_tasks) do
|
3
5
|
as_routes
|
@@ -15,6 +17,6 @@ Rails.application.routes.draw do
|
|
15
17
|
to: 'tasks_scheduler_daemon#execute', as: :execute_tasks_scheduler_daemon
|
16
18
|
get '/tasks_scheduler_daemon/status', to: 'tasks_scheduler_daemon#status',
|
17
19
|
as: :status_tasks_scheduler_daemon
|
18
|
-
get '/tasks_scheduler_daemon/download_log', to: 'tasks_scheduler_daemon#download_log',
|
19
|
-
|
20
|
+
get '/tasks_scheduler_daemon/download_log/:log_key', to: 'tasks_scheduler_daemon#download_log',
|
21
|
+
as: :download_log_tasks_scheduler_daemon
|
20
22
|
end
|
@@ -1,4 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreateScheduledTasks < (
|
4
|
+
Rails.version < '5.2' ? ActiveRecord::Migration : ActiveRecord::Migration[4.2]
|
5
|
+
)
|
2
6
|
def change
|
3
7
|
create_table :scheduled_tasks do |t|
|
4
8
|
t.string :scheduling
|
@@ -1,4 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AddStatusAttributesToScheduledTasks < (
|
4
|
+
Rails.version < '5.2' ? ActiveRecord::Migration : ActiveRecord::Migration[4.2]
|
5
|
+
)
|
2
6
|
def change
|
3
7
|
add_column :scheduled_tasks, :last_run_start, :datetime
|
4
8
|
add_column :scheduled_tasks, :last_run_successful_start, :datetime
|
@@ -1,4 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AddPidToScheduledTasks < (
|
4
|
+
Rails.version < '5.2' ? ActiveRecord::Migration : ActiveRecord::Migration[4.2]
|
5
|
+
)
|
2
6
|
def change
|
3
7
|
add_column :scheduled_tasks, :pid, :integer
|
4
8
|
end
|
@@ -1,4 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AddArgsToScheduledTasks < (
|
4
|
+
Rails.version < '5.2' ? ActiveRecord::Migration : ActiveRecord::Migration[4.2]
|
5
|
+
)
|
2
6
|
def change
|
3
7
|
add_column :scheduled_tasks, :args, :string
|
4
8
|
end
|
@@ -1,4 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AddLastFailStatusToScheduledTasks < (
|
4
|
+
Rails.version < '5.2' ? ActiveRecord::Migration : ActiveRecord::Migration[4.2]
|
5
|
+
)
|
2
6
|
def change
|
3
7
|
add_column :scheduled_tasks, :last_fail_status, :string
|
4
8
|
end
|
@@ -1,4 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AddEnabledToScheduledTasks < (
|
4
|
+
Rails.version < '5.2' ? ActiveRecord::Migration : ActiveRecord::Migration[4.2]
|
5
|
+
)
|
2
6
|
def change
|
3
7
|
add_column :scheduled_tasks, :enabled, :boolean, null: false, default: true
|
4
8
|
end
|
data/exe/tasks_scheduler
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require 'rubygems'
|
4
5
|
require 'daemons'
|
5
6
|
require 'fileutils'
|
6
7
|
|
7
8
|
def find_rails_root(dir = Dir.pwd)
|
8
|
-
|
9
|
+
raise 'Rails root not found' if ['', '/', '.'].include?(dir)
|
9
10
|
return dir if File.exist?(File.expand_path('config/environment.rb', dir))
|
11
|
+
|
10
12
|
rails_root(File.dirname(dir))
|
11
13
|
end
|
12
14
|
|
@@ -14,6 +16,8 @@ rails_root = find_rails_root
|
|
14
16
|
dir = File.expand_path('tmp/pids', rails_root)
|
15
17
|
FileUtils.mkdir_p(dir)
|
16
18
|
Daemons.run_proc 'tasks_scheduler', dir_mode: :normal, dir: dir do
|
17
|
-
|
18
|
-
|
19
|
+
::Dir.chdir(rails_root) do
|
20
|
+
require File.join(rails_root, 'config', 'environment')
|
21
|
+
::TasksScheduler::Checker.instance.run
|
22
|
+
end
|
19
23
|
end
|
@@ -1,11 +1,13 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require 'rubygems'
|
4
5
|
require 'daemons'
|
5
6
|
|
6
7
|
def find_rails_root(dir = Dir.pwd)
|
7
|
-
|
8
|
+
raise 'Rails root not found' if ['', '/', '.'].include?(dir)
|
8
9
|
return dir if File.exist?(File.expand_path('config/environment.rb', dir))
|
10
|
+
|
9
11
|
rails_root(File.dirname(dir))
|
10
12
|
end
|
11
13
|
|
data/lib/tasks_scheduler.rb
CHANGED
@@ -1,11 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require '
|
4
|
-
require 'parse-cron'
|
5
|
-
require 'tasks_scheduler/cron_scheduling_validator'
|
6
|
-
require 'tasks_scheduler/cron_parser_patch'
|
7
|
-
require 'tasks_scheduler/checker'
|
8
|
-
require 'tasks_scheduler/daemon'
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'eac_ruby_utils/require_sub'
|
9
4
|
|
10
5
|
module TasksScheduler
|
6
|
+
::EacRubyUtils.require_sub __FILE__
|
11
7
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'eac_ruby_gems_utils/gem'
|
4
|
+
require 'singleton'
|
5
|
+
|
6
|
+
module TasksScheduler
|
7
|
+
class AppGem < ::SimpleDelegator
|
8
|
+
include ::Singleton
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
super(::EacRubyGemsUtils::Gem.new(::Rails.root))
|
12
|
+
end
|
13
|
+
|
14
|
+
def bundle(*args)
|
15
|
+
super(*args).chdir_root.envvar('RAILS_ENV', ::Rails.env)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,9 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'tasks_scheduler/checker/log'
|
4
|
+
|
1
5
|
module TasksScheduler
|
2
6
|
class Checker
|
3
7
|
include Singleton
|
4
8
|
|
5
9
|
CHECK_INTERVAL = 15
|
6
|
-
LOG_ON_FILE_ENV_KEY = 'TASKS_SCHEDULER_LOG_ON_FILE'
|
10
|
+
LOG_ON_FILE_ENV_KEY = 'TASKS_SCHEDULER_LOG_ON_FILE'
|
11
|
+
LOGS_KEYS = %w[rails stdout stderr].freeze
|
7
12
|
|
8
13
|
def run
|
9
14
|
check_log
|
@@ -18,15 +23,29 @@ module TasksScheduler
|
|
18
23
|
end
|
19
24
|
|
20
25
|
def log_path
|
21
|
-
|
26
|
+
rais_log.path
|
27
|
+
end
|
28
|
+
|
29
|
+
def logs
|
30
|
+
LOGS_KEYS.map { |key| send("#{key}_log") }
|
31
|
+
end
|
32
|
+
|
33
|
+
LOGS_KEYS.each do |log_key|
|
34
|
+
class_eval <<CODE, __FILE__, __LINE__ + 1
|
35
|
+
def #{log_key}_log
|
36
|
+
@#{log_key}_log ||= ::TasksScheduler::Checker::Log.new('#{log_key}')
|
37
|
+
end
|
38
|
+
CODE
|
22
39
|
end
|
23
40
|
|
24
41
|
private
|
25
42
|
|
26
43
|
def check_log
|
27
44
|
return unless log_on_file?
|
28
|
-
|
29
|
-
::Rails.logger = ::Logger.new(
|
45
|
+
|
46
|
+
::Rails.logger = ::Logger.new(rails_log.path)
|
47
|
+
$stdout.reopen(stdout_log.path, 'w')
|
48
|
+
$stderr.reopen(stderr_log.path, 'w')
|
30
49
|
end
|
31
50
|
|
32
51
|
def log_on_file?
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module TasksScheduler
|
6
|
+
class Checker
|
7
|
+
class Log
|
8
|
+
class << self
|
9
|
+
def logs_directory
|
10
|
+
@logs_directory ||= ::Rails.root.join('log', 'tasks_scheduler', 'checker')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :key
|
15
|
+
|
16
|
+
def initialize(key)
|
17
|
+
@key = key
|
18
|
+
::FileUtils.mkdir_p(dirname)
|
19
|
+
end
|
20
|
+
|
21
|
+
def dirname
|
22
|
+
::File.dirname(path)
|
23
|
+
end
|
24
|
+
|
25
|
+
def exist?
|
26
|
+
::File.exist?(path)
|
27
|
+
end
|
28
|
+
|
29
|
+
def path
|
30
|
+
self.class.logs_directory.join("#{key}.log")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -1,8 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'parse-cron'
|
4
|
+
|
1
5
|
module TasksScheduler
|
2
6
|
module CronParserPatch
|
3
7
|
class TasksSchedulerTimeSource
|
4
8
|
class << self
|
5
|
-
def local(year, month, day, hour, min, second)
|
9
|
+
def local(year, month, day, hour, min, second) # rubocop:disable Metrics/ParameterLists
|
6
10
|
Time.utc(year, month, day, hour, min, second)
|
7
11
|
end
|
8
12
|
|
@@ -1,7 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TasksScheduler
|
2
4
|
class CronSchedulingValidator < ActiveModel::EachValidator
|
3
5
|
def validate_each(record, attribute, value)
|
4
6
|
return if value_valid?(value)
|
7
|
+
|
5
8
|
record.errors[attribute] << (options[:message] ||
|
6
9
|
I18n.translate(:cron_scheduling_validator_error_message))
|
7
10
|
end
|
@@ -1,28 +1,35 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'tasks_scheduler/app_gem'
|
2
4
|
|
3
5
|
module TasksScheduler
|
4
6
|
class Daemon
|
5
|
-
ACTIONS = %w
|
7
|
+
ACTIONS = %w[status start stop restart].freeze
|
6
8
|
|
7
9
|
class << self
|
8
|
-
def
|
10
|
+
def daemon_command(action)
|
9
11
|
raise "Action not allowed: #{action} (Allowed: #{ACTIONS})" unless ACTIONS.include?(action)
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
|
13
|
+
::TasksScheduler::AppGem.instance.bundle('exec', 'tasks_scheduler', action)
|
14
|
+
.envvar(::TasksScheduler::Checker::LOG_ON_FILE_ENV_KEY, '1')
|
15
|
+
end
|
16
|
+
|
17
|
+
def execute(action)
|
18
|
+
command = daemon_command(action)
|
19
|
+
result = command.execute
|
20
|
+
{
|
21
|
+
action: action, env_args: env_args_to_s(command), command: command.to_s,
|
22
|
+
status: result.fetch(:exit_code), stdout: result.fetch(:stdout),
|
23
|
+
stderr: result.fetch(:stderr)
|
24
|
+
}
|
18
25
|
end
|
19
26
|
|
20
27
|
def running?
|
21
28
|
execute('status')[:status].zero?
|
22
29
|
end
|
23
30
|
|
24
|
-
def
|
25
|
-
{
|
31
|
+
def env_args_to_s(command)
|
32
|
+
command.send(:extra_options).fetch(:envvars).map { |k, v| "#{k}=#{v}" }.join(' | ')
|
26
33
|
end
|
27
34
|
end
|
28
35
|
end
|
data/test/dummy/Rakefile
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
2
4
|
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
3
5
|
|
4
|
-
require File.expand_path('
|
6
|
+
require File.expand_path('config/application', __dir__)
|
5
7
|
|
6
8
|
Rails.application.load_tasks
|
data/test/dummy/bin/bundle
CHANGED
data/test/dummy/bin/rails
CHANGED
data/test/dummy/bin/rake
CHANGED
data/test/dummy/bin/setup
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
2
4
|
require 'pathname'
|
3
5
|
|
4
6
|
# path to your application root.
|
5
|
-
APP_ROOT = Pathname.new File.expand_path('
|
7
|
+
APP_ROOT = Pathname.new File.expand_path('..', __dir__)
|
6
8
|
|
7
9
|
Dir.chdir APP_ROOT do
|
8
10
|
# This script is a starting point to setup your application.
|
data/test/dummy/config.ru
CHANGED
data/test/dummy/config/boot.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Set up gems listed in the Gemfile.
|
2
|
-
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('
|
4
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../Gemfile', __dir__)
|
3
5
|
|
4
6
|
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
|
5
|
-
$LOAD_PATH.unshift File.expand_path('
|
7
|
+
$LOAD_PATH.unshift File.expand_path('../../../lib', __dir__)
|
data/test/dummy/config/routes.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_helper'
|
2
4
|
|
3
5
|
class ScheduledTaskTest < ActiveSupport::TestCase
|
@@ -6,9 +8,9 @@ class ScheduledTaskTest < ActiveSupport::TestCase
|
|
6
8
|
'*/5 * * * *' => Time.utc(2016, 12, 22, 12, 5, 0, 0),
|
7
9
|
'* * 1 * *' => Time.utc(2017, 1, 1, 0, 0, 0, 0),
|
8
10
|
'* * * * *' => Time.utc(2016, 12, 22, 12, 1, 0, 0)
|
9
|
-
}
|
11
|
+
}.freeze
|
10
12
|
|
11
|
-
SCHEDULING_INVALID_VALUES = [' ', nil, '1', 'abc123', 456]
|
13
|
+
SCHEDULING_INVALID_VALUES = [' ', nil, '1', 'abc123', 456].freeze
|
12
14
|
|
13
15
|
setup do
|
14
16
|
@scheduled_task = scheduled_tasks(:test_scheduling)
|
@@ -57,7 +59,7 @@ class ScheduledTaskTest < ActiveSupport::TestCase
|
|
57
59
|
end
|
58
60
|
|
59
61
|
test 'status 1' do
|
60
|
-
@scheduled_task.
|
62
|
+
@scheduled_task.update!(
|
61
63
|
scheduling: '*/5 * * * *',
|
62
64
|
next_run: 'Wed, 28 Feb 2018 15:35:00 UTC +00:00',
|
63
65
|
created_at: 'Tue, 06 Dec 2016 20:30:01 UTC +00:00',
|
@@ -88,7 +90,7 @@ class ScheduledTaskTest < ActiveSupport::TestCase
|
|
88
90
|
assert_equal ['abc'], @scheduled_task.send('invoke_args')
|
89
91
|
|
90
92
|
@scheduled_task.args = 'abc|def|ghi'
|
91
|
-
assert_equal %w
|
93
|
+
assert_equal %w[abc def ghi], @scheduled_task.send('invoke_args')
|
92
94
|
|
93
95
|
@scheduled_task.args = 'abc||ghi'
|
94
96
|
assert_equal ['abc', '', 'ghi'], @scheduled_task.send('invoke_args')
|
data/test/test_helper.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Configure Rails Environment
|
2
4
|
ENV['RAILS_ENV'] = 'test'
|
3
5
|
|
4
|
-
require File.expand_path('
|
6
|
+
require File.expand_path('../test/dummy/config/environment.rb', __dir__)
|
5
7
|
ActiveRecord::Migrator.migrations_paths = [
|
6
|
-
File.expand_path('
|
8
|
+
File.expand_path('../test/dummy/db/migrate', __dir__)
|
7
9
|
]
|
8
10
|
require 'rails/test_help'
|
9
11
|
|
@@ -12,11 +14,11 @@ require 'rails/test_help'
|
|
12
14
|
Minitest.backtrace_filter = Minitest::BacktraceFilter.new
|
13
15
|
|
14
16
|
# Load support files
|
15
|
-
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
17
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].sort.each { |f| require f }
|
16
18
|
|
17
19
|
# Load fixtures from the engine
|
18
20
|
if ActiveSupport::TestCase.respond_to?(:fixture_path=)
|
19
|
-
ActiveSupport::TestCase.fixture_path = File.expand_path('
|
21
|
+
ActiveSupport::TestCase.fixture_path = File.expand_path('fixtures', __dir__)
|
20
22
|
ActiveSupport::TestCase.fixtures :all
|
21
23
|
end
|
22
24
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tasks_scheduler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eduardo H. Bogoni
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-07-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: active_scaffold
|
@@ -38,6 +38,26 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: eac_ruby_gems_utils
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.4'
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 0.4.1
|
51
|
+
type: :runtime
|
52
|
+
prerelease: false
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - "~>"
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0.4'
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 0.4.1
|
41
61
|
- !ruby/object:Gem::Dependency
|
42
62
|
name: js-routes
|
43
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -70,16 +90,36 @@ dependencies:
|
|
70
90
|
name: rails
|
71
91
|
requirement: !ruby/object:Gem::Requirement
|
72
92
|
requirements:
|
73
|
-
- - "
|
93
|
+
- - ">="
|
74
94
|
- !ruby/object:Gem::Version
|
75
|
-
version: 4.2.
|
95
|
+
version: 4.2.11.3
|
76
96
|
type: :runtime
|
77
97
|
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 4.2.11.3
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: eac_ruby_gem_support
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0.1'
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: 0.1.1
|
113
|
+
type: :development
|
114
|
+
prerelease: false
|
78
115
|
version_requirements: !ruby/object:Gem::Requirement
|
79
116
|
requirements:
|
80
117
|
- - "~>"
|
81
118
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
119
|
+
version: '0.1'
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: 0.1.1
|
83
123
|
- !ruby/object:Gem::Dependency
|
84
124
|
name: sqlite3
|
85
125
|
requirement: !ruby/object:Gem::Requirement
|
@@ -111,6 +151,7 @@ files:
|
|
111
151
|
- app/assets/stylesheets/tasks_scheduler/alert.scss
|
112
152
|
- app/controllers/scheduled_tasks_controller.rb
|
113
153
|
- app/controllers/tasks_scheduler_daemon_controller.rb
|
154
|
+
- app/controllers/tasks_scheduler_daemon_controller/_download_log.rb
|
114
155
|
- app/helpers/scheduled_tasks_helper.rb
|
115
156
|
- app/models/scheduled_task.rb
|
116
157
|
- app/models/scheduled_task/checker.rb
|
@@ -123,6 +164,9 @@ files:
|
|
123
164
|
- app/views/scheduled_tasks/status_content.html.erb
|
124
165
|
- app/views/tasks_scheduler/_alert.html.erb
|
125
166
|
- app/views/tasks_scheduler/_navbar.html.erb
|
167
|
+
- app/views/tasks_scheduler_daemon/_daemon.html.erb
|
168
|
+
- app/views/tasks_scheduler_daemon/_logs.html.erb
|
169
|
+
- app/views/tasks_scheduler_daemon/_results.html.erb
|
126
170
|
- app/views/tasks_scheduler_daemon/_running_status.html.erb
|
127
171
|
- app/views/tasks_scheduler_daemon/index.html.erb
|
128
172
|
- config/initializers/assets.rb
|
@@ -138,7 +182,9 @@ files:
|
|
138
182
|
- exe/tasks_scheduler
|
139
183
|
- exe/tasks_scheduler_run_task
|
140
184
|
- lib/tasks_scheduler.rb
|
185
|
+
- lib/tasks_scheduler/app_gem.rb
|
141
186
|
- lib/tasks_scheduler/checker.rb
|
187
|
+
- lib/tasks_scheduler/checker/log.rb
|
142
188
|
- lib/tasks_scheduler/cron_parser_patch.rb
|
143
189
|
- lib/tasks_scheduler/cron_scheduling_validator.rb
|
144
190
|
- lib/tasks_scheduler/daemon.rb
|
@@ -201,8 +247,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
201
247
|
- !ruby/object:Gem::Version
|
202
248
|
version: '0'
|
203
249
|
requirements: []
|
204
|
-
|
205
|
-
rubygems_version: 2.7.7
|
250
|
+
rubygems_version: 3.0.6
|
206
251
|
signing_key:
|
207
252
|
specification_version: 4
|
208
253
|
summary: Scheduler for Rake tasks.
|