tasks_scheduler 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7ffe5fd69eab67510ab378506158799d08b21d4577ed368ddbadf12cfb0a6957
4
- data.tar.gz: e471eaeb074d10557c8c3bd55dff0d8bbd0a9e1b83723d28f6255b2b2907fe29
3
+ metadata.gz: 89877b670ebd68e63175333d60bce49d90de7c4e04737189f5c73a6a277f0595
4
+ data.tar.gz: 18d4d5224dcabd9dd2238d0cc8a5dea03689d58323de808b5bb4622664a2cc01
5
5
  SHA512:
6
- metadata.gz: 435c0e3aa4e1c7a721933b6a47bd3b72f33ab51d5a5c67323cee7a179c2aef731bc6a39119763fa169c064670883a50728703c1ad37614c9d7996ba7b7993336
7
- data.tar.gz: 9112b3ad93fd00dfc3d10d8487befc0c698461d046a8fdeead98611c86ecdd0d4f44dcb929864fa53e95fcf409fedd9eefcd85abe7ccf0817269f44d50b2b3df
6
+ metadata.gz: 6bb72a00e15bd394f6baa9cbae395e8737295ff72f1177315fd15937b2b60189901b7db0cfe3c2b7b9daf08599023c694558231539d1f6e2b92ea4f6fd0bd2a4
7
+ data.tar.gz: 766a81812effee371317d38ee615e0e5b57400abac7d6a376a6a5971bc98fc301bdca3e03dbfa3c8f1d3f1c7903ddbdf479fc7b89451292880c386c813311b69
@@ -1,4 +1,8 @@
1
+ require 'tasks_scheduler/checker'
2
+
1
3
  class TasksSchedulerDaemonController < ApplicationController
4
+ require_relative 'tasks_scheduler_daemon_controller/_download_log'
5
+
2
6
  def index
3
7
  end
4
8
 
@@ -11,24 +15,4 @@ class TasksSchedulerDaemonController < ApplicationController
11
15
  render json: { daemon_running: ::TasksScheduler::Daemon.running?,
12
16
  tasks_all_ok: !::ScheduledTask.all.any?(&:failed?) }
13
17
  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
- )
33
- end
34
18
  end
@@ -0,0 +1,36 @@
1
+ class TasksSchedulerDaemonController < ApplicationController
2
+ def download_log
3
+ return unless download_log_validate_log_key
4
+ log = ::TasksScheduler::Checker.instance.send("#{download_log_key}_log")
5
+ return unless download_log_validate_log_exist(log)
6
+ send_log_file(log)
7
+ end
8
+
9
+ private
10
+
11
+ def download_log_key
12
+ params[:log_key]
13
+ end
14
+
15
+ def download_log_validate_log_key
16
+ return true if ::TasksScheduler::Checker::LOGS_KEYS.include?(download_log_key)
17
+ redirect_to(tasks_scheduler_daemon_path,
18
+ notice: "Invalid log key: \"#{download_log_key}\"")
19
+ false
20
+ end
21
+
22
+ def download_log_validate_log_exist(log)
23
+ return true if log.exist?
24
+ redirect_to(tasks_scheduler_daemon_path, notice: "Log \"#{log.key}\" does not exist.")
25
+ false
26
+ end
27
+
28
+ def send_log_file(log)
29
+ send_file(
30
+ log.path,
31
+ filename: "#{request.base_url.parameterize}_tasks-scheduler_checker-log_" \
32
+ "#{Time.zone.now.to_s.parameterize}.log",
33
+ type: 'text/plain'
34
+ )
35
+ end
36
+ end
@@ -37,9 +37,11 @@ class ScheduledTask < ActiveRecord::Base
37
37
  LAST_FAIL_STATUSES = [STATUS_FAILED, STATUS_ABORTED, STATUS_TIMEOUT]
38
38
 
39
39
  validates :scheduling, presence: true, 'tasks_scheduler/cron_scheduling': true
40
- validates :task, presence: true, inclusion: { in: rake_tasks }
40
+ validates :task, presence: true
41
41
  validates :last_fail_status, allow_blank: true, inclusion: { in: LAST_FAIL_STATUSES }
42
42
 
43
+ validate :validate_task
44
+
43
45
  LOG_RUNNING = 'running'
44
46
  LOG_SUCCESSFUL = 'successful'
45
47
  LOG_UNSUCCESSFUL = 'unsuccessful'
@@ -76,4 +78,15 @@ class ScheduledTask < ActiveRecord::Base
76
78
  rescue
77
79
  raise "Unable to determine status for #{pid}"
78
80
  end
81
+
82
+ def task_exist?
83
+ self.class.rake_tasks.include?(task)
84
+ end
85
+
86
+ def validate_task
87
+ return if task.blank?
88
+ return unless task_changed?
89
+ return if self.class.rake_tasks.include?(task)
90
+ errors.add(:task, "Task \"#{task}\" not found")
91
+ end
79
92
  end
@@ -60,7 +60,9 @@ class ScheduledTask < ActiveRecord::Base
60
60
  end
61
61
 
62
62
  def check_task_with_next_run
63
- if next_run < Time.zone.now
63
+ if !task_exist?
64
+ check_log("Task does not exist: #{task}")
65
+ elsif next_run < Time.zone.now
64
66
  check_log('Next run reached. Running...')
65
67
  spawn_task
66
68
  else
@@ -70,7 +72,7 @@ class ScheduledTask < ActiveRecord::Base
70
72
 
71
73
  def spawn_task
72
74
  params = ['bundle', 'exec', 'tasks_scheduler_run_task', id.to_s]
73
- check_log("Spawn command: #{params}")
75
+ check_log("Spawn command: #{params} (Task: #{task})")
74
76
  spawn_pid = nil
75
77
  Dir.chdir(Rails.root) do
76
78
  spawn_pid = Process.spawn(*params)
@@ -23,9 +23,12 @@ class ScheduledTask < ActiveRecord::Base
23
23
  end
24
24
 
25
25
  def log_on_end(exception)
26
- target_log = exception ? log_file(LOG_UNSUCCESSFUL) : log_file(LOG_SUCCESSFUL)
27
- File.unlink(target_log) if File.exist?(target_log)
28
- File.rename(log_file(LOG_RUNNING), target_log)
26
+ running_log = log_file(LOG_RUNNING)
27
+ if ::File.exist?(running_log)
28
+ target_log = exception ? log_file(LOG_UNSUCCESSFUL) : log_file(LOG_SUCCESSFUL)
29
+ File.unlink(target_log) if File.exist?(target_log)
30
+ File.rename(running_log, target_log)
31
+ end
29
32
  end
30
33
  end
31
34
  end
@@ -2,6 +2,7 @@
2
2
  <strong>Last update: </strong>
3
3
  <%= I18n.l(Time.zone.now, format: :short) %>
4
4
  <br/>
5
+ <strong>Daemon status: </strong>
5
6
  <%= render partial: '/tasks_scheduler_daemon/running_status' %>
6
7
  </p>
7
8
  <table>
@@ -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>
@@ -0,0 +1,9 @@
1
+ <% if @result %>
2
+ <h3>Results</h3>
3
+ <dl>
4
+ <% @result.each do |k, v| %>
5
+ <dt><%= k %></dt>
6
+ <dd><%= v.present? ? v : '-' %></dd>
7
+ <% end %>
8
+ </dl>
9
+ <% end %>
@@ -1,4 +1,3 @@
1
- <strong>Daemon status: </strong>
2
1
  <% if TasksScheduler::Daemon.running? %>
3
2
  <span class="tasks_scheduler_daemon_status_up">UP</span>
4
3
  <% else %>
@@ -1,22 +1,5 @@
1
1
  <%= render partial: '/tasks_scheduler/navbar' %>
2
2
  <h2><%= I18n.t(:tasks_scheduler_daemon) %></h2>
3
- <p>
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
- <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' %>
@@ -15,6 +15,6 @@ Rails.application.routes.draw do
15
15
  to: 'tasks_scheduler_daemon#execute', as: :execute_tasks_scheduler_daemon
16
16
  get '/tasks_scheduler_daemon/status', to: 'tasks_scheduler_daemon#status',
17
17
  as: :status_tasks_scheduler_daemon
18
- get '/tasks_scheduler_daemon/download_log', to: 'tasks_scheduler_daemon#download_log',
19
- as: :download_log_tasks_scheduler_daemon
18
+ get '/tasks_scheduler_daemon/download_log/:log_key', to: 'tasks_scheduler_daemon#download_log',
19
+ as: :download_log_tasks_scheduler_daemon
20
20
  end
@@ -1,9 +1,12 @@
1
+ require 'tasks_scheduler/checker/log'
2
+
1
3
  module TasksScheduler
2
4
  class Checker
3
5
  include Singleton
4
6
 
5
7
  CHECK_INTERVAL = 15
6
8
  LOG_ON_FILE_ENV_KEY = 'TASKS_SCHEDULER_LOG_ON_FILE'.freeze
9
+ LOGS_KEYS = %w(rails stdout stderr).freeze
7
10
 
8
11
  def run
9
12
  check_log
@@ -18,15 +21,28 @@ module TasksScheduler
18
21
  end
19
22
 
20
23
  def log_path
21
- ::Rails.root.join('log', 'tasks_scheduler', 'checker.log')
24
+ rais_log.path
25
+ end
26
+
27
+ def logs
28
+ LOGS_KEYS.map { |key| send("#{key}_log") }
29
+ end
30
+
31
+ LOGS_KEYS.each do |log_key|
32
+ class_eval <<CODE, __FILE__, __LINE__ + 1
33
+ def #{log_key}_log
34
+ @#{log_key}_log ||= ::TasksScheduler::Checker::Log.new('#{log_key}')
35
+ end
36
+ CODE
22
37
  end
23
38
 
24
39
  private
25
40
 
26
41
  def check_log
27
42
  return unless log_on_file?
28
- ::FileUtils.mkdir_p(File.dirname(log_path))
29
- ::Rails.logger = ::Logger.new(log_path)
43
+ ::Rails.logger = ::Logger.new(rails_log.path)
44
+ $stdout.reopen(stdout_log.path, 'w')
45
+ $stderr.reopen(stderr_log.path, 'w')
30
46
  end
31
47
 
32
48
  def log_on_file?
@@ -0,0 +1,32 @@
1
+ require 'fileutils'
2
+
3
+ module TasksScheduler
4
+ class Checker
5
+ class Log
6
+ class << self
7
+ def logs_directory
8
+ @logs_directory ||= ::Rails.root.join('log', 'tasks_scheduler', 'checker')
9
+ end
10
+ end
11
+
12
+ attr_reader :key
13
+
14
+ def initialize(key)
15
+ @key = key
16
+ ::FileUtils.mkdir_p(dirname)
17
+ end
18
+
19
+ def dirname
20
+ ::File.dirname(path)
21
+ end
22
+
23
+ def exist?
24
+ ::File.exist?(path)
25
+ end
26
+
27
+ def path
28
+ self.class.logs_directory.join("#{key}.log")
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,3 +1,3 @@
1
1
  module TasksScheduler
2
- VERSION = '0.2.3'.freeze
2
+ VERSION = '0.3.0'.freeze
3
3
  end
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.2.3
4
+ version: 0.3.0
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: 2019-07-02 00:00:00.000000000 Z
11
+ date: 2019-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: active_scaffold
@@ -111,6 +111,7 @@ files:
111
111
  - app/assets/stylesheets/tasks_scheduler/alert.scss
112
112
  - app/controllers/scheduled_tasks_controller.rb
113
113
  - app/controllers/tasks_scheduler_daemon_controller.rb
114
+ - app/controllers/tasks_scheduler_daemon_controller/_download_log.rb
114
115
  - app/helpers/scheduled_tasks_helper.rb
115
116
  - app/models/scheduled_task.rb
116
117
  - app/models/scheduled_task/checker.rb
@@ -123,6 +124,9 @@ files:
123
124
  - app/views/scheduled_tasks/status_content.html.erb
124
125
  - app/views/tasks_scheduler/_alert.html.erb
125
126
  - app/views/tasks_scheduler/_navbar.html.erb
127
+ - app/views/tasks_scheduler_daemon/_daemon.html.erb
128
+ - app/views/tasks_scheduler_daemon/_logs.html.erb
129
+ - app/views/tasks_scheduler_daemon/_results.html.erb
126
130
  - app/views/tasks_scheduler_daemon/_running_status.html.erb
127
131
  - app/views/tasks_scheduler_daemon/index.html.erb
128
132
  - config/initializers/assets.rb
@@ -139,6 +143,7 @@ files:
139
143
  - exe/tasks_scheduler_run_task
140
144
  - lib/tasks_scheduler.rb
141
145
  - lib/tasks_scheduler/checker.rb
146
+ - lib/tasks_scheduler/checker/log.rb
142
147
  - lib/tasks_scheduler/cron_parser_patch.rb
143
148
  - lib/tasks_scheduler/cron_scheduling_validator.rb
144
149
  - lib/tasks_scheduler/daemon.rb