Class: ScheduledTask

Inherits:
ActiveRecord::Base
  • Object
show all
Includes:
Checker, Log, Runner, Status
Defined in:
app/models/scheduled_task.rb,
app/models/scheduled_task/log.rb,
app/models/scheduled_task/runner.rb,
app/models/scheduled_task/status.rb,
app/models/scheduled_task/checker.rb

Defined Under Namespace

Modules: Checker, Log, Runner, Status

Constant Summary collapse

DEFAULT_TIMEOUT_ENVVAR_NAME =
'TASKS_SCHEDULER_TIMEOUT'
DEFAULT_TIMEOUT =
12.hours
LAST_FAIL_STATUSES =
[STATUS_FAILED, STATUS_ABORTED, STATUS_TASK_NOT_FOUND, STATUS_TIMEOUT].freeze
LOG_RUNNING =
'running'
LOG_SUCCESSFUL =
'successful'
LOG_UNSUCCESSFUL =
'unsuccessful'

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Status

#failed?, #running?, #status, #waiting?

Methods included from Runner

#run

Methods included from Log

#log_file

Methods included from Checker

#check

Class Method Details

.rake_tasksObject



17
18
19
20
21
22
# File 'app/models/scheduled_task.rb', line 17

def rake_tasks
  @rake_tasks ||= begin
    Rails.application.load_tasks if Rake.application.tasks.empty?
    Rake.application.tasks.map(&:name)
  end
end

.timeoutObject



24
25
26
27
28
29
30
31
# File 'app/models/scheduled_task.rb', line 24

def timeout
  @timeout ||= begin
    r = Integer(ENV.fetch(DEFAULT_TIMEOUT_ENVVAR_NAME, nil))
    r.positive? ? r.seconds : DEFAULT_TIMEOUT
  rescue ArgumentError, TypeError
    DEFAULT_TIMEOUT
  end
end

Instance Method Details

#_write_attribute(name, value) ⇒ Object



64
65
66
67
# File 'app/models/scheduled_task.rb', line 64

def _write_attribute(name, value)
  @cron_parser = nil if name == 'scheduling'
  super
end

#calculate_next_run(time = nil) ⇒ Object



58
59
60
61
62
# File 'app/models/scheduled_task.rb', line 58

def calculate_next_run(time = nil)
  (time.present? ? cron_parser.next(time.utc) : cron_parser.next).then do |v|
    Time.utc(v.year, v.month, v.day, v.hour, v.min, v.sec)
  end
end

#cron_parserObject



50
51
52
# File 'app/models/scheduled_task.rb', line 50

def cron_parser
  @cron_parser ||= ::CronParser.new(scheduling)
end

#process_running?Boolean

Returns:

  • (Boolean)


69
70
71
72
73
74
75
76
77
78
79
80
# File 'app/models/scheduled_task.rb', line 69

def process_running?
  return false if pid.nil?

  Process.kill(0, pid)
  true
rescue Errno::EPERM
  raise "No permission to query #{pid}!"
rescue Errno::ESRCH
  false
rescue StandardError
  raise "Unable to determine status for #{pid}"
end

#task_exist?Boolean

Returns:

  • (Boolean)


82
83
84
# File 'app/models/scheduled_task.rb', line 82

def task_exist?
  self.class.rake_tasks.include?(task)
end

#to_sObject



54
55
56
# File 'app/models/scheduled_task.rb', line 54

def to_s
  "S: #{scheduling}, T: #{task}, NR: #{next_run.present? ? next_run.in_time_zone : '-'}"
end

#validate_taskObject



86
87
88
89
90
91
92
# File 'app/models/scheduled_task.rb', line 86

def validate_task
  return if task.blank?
  return unless task_changed?
  return if self.class.rake_tasks.include?(task)

  errors.add(:task, "Task \"#{task}\" not found")
end