tasks_scheduler 0.2.3 → 0.3.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 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