Class: ForemanTasks::RecurringLogic
- Inherits:
-
ApplicationRecord
- Object
- ApplicationRecord
- ForemanTasks::RecurringLogic
- Includes:
- Authorizable
- Defined in:
- app/models/foreman_tasks/recurring_logic.rb
Class Method Summary collapse
- .allowed_states ⇒ Object
- .assemble_cronline(hash) ⇒ Object
- .cronline_hash(recurring_type, time_hash, days, days_of_week_hash) ⇒ Object
- .new_from_cronline(cronline) ⇒ Object
- .new_from_triggering(triggering) ⇒ Object
Instance Method Summary collapse
- #can_continue?(time = Time.zone.now) ⇒ Boolean
- #can_start?(time = Time.zone.now) ⇒ Boolean
- #cancel ⇒ Object
- #cancelled? ⇒ Boolean
- #disabled? ⇒ Boolean
- #done? ⇒ Boolean
- #enabled=(value) ⇒ Object
- #enabled? ⇒ Boolean
- #finished? ⇒ Boolean
- #generate_delay_options(time = Time.zone.now, options = {}) ⇒ Object
- #humanized_state ⇒ Object
- #last_task ⇒ Object
- #next_occurrence_time(time = Time.zone.now) ⇒ Object
- #next_task ⇒ Object
- #start(action_class, *args) ⇒ Object
- #start_after(action_class, time, *args) ⇒ Object
- #trigger_repeat(action_class, *args) ⇒ Object
- #trigger_repeat_after(time, action_class, *args) ⇒ Object
- #valid?(*_) ⇒ Boolean
- #valid_cronline? ⇒ Boolean
- #valid_purpose? ⇒ Boolean
Class Method Details
.allowed_states ⇒ Object
28 29 30 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 28 def self.allowed_states %w[active disabled finished cancelled failed] end |
.assemble_cronline(hash) ⇒ Object
161 162 163 164 165 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 161 def self.assemble_cronline(hash) hash.values_at(:minutes, :hours, :days, :months, :days_of_week) .map { |value| value.nil? || value.blank? ? '*' : value } .join(' ') end |
.cronline_hash(recurring_type, time_hash, days, days_of_week_hash) ⇒ Object
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 188 def self.cronline_hash(recurring_type, time_hash, days, days_of_week_hash) hash = Hash[[:years, :months, :days, :hours, :minutes].zip(time_hash.values)] days_of_week = days_of_week_hash.select { |_key, value| value == '1' }.keys.join(',') hash.update :days_of_week => days_of_week, :days => days allowed_keys = case recurring_type when :monthly [:minutes, :hours, :days] when :weekly [:minutes, :hours, :days_of_week] when :daily [:minutes, :hours] when :hourly [:minutes] end hash.select { |key, _| allowed_keys.include? key } end |
.new_from_cronline(cronline) ⇒ Object
167 168 169 170 171 172 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 167 def self.new_from_cronline(cronline) new.tap do |logic| logic.cron_line = cronline logic.task_group = ::ForemanTasks::TaskGroups::RecurringLogicTaskGroup.new end end |
.new_from_triggering(triggering) ⇒ Object
174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 174 def self.new_from_triggering(triggering) cronline = if triggering.input_type == :cronline triggering.cronline else ::ForemanTasks::RecurringLogic.assemble_cronline(cronline_hash(triggering.input_type, triggering.time, triggering.days, triggering.days_of_week)) end ::ForemanTasks::RecurringLogic.new_from_cronline(cronline).tap do |manager| manager.end_time = triggering.end_time if triggering.end_time_limited.present? manager.max_iteration = triggering.max_iteration if triggering.max_iteration.present? manager.purpose = triggering.purpose if triggering.purpose.present? manager.triggering = triggering end end |
Instance Method Details
#can_continue?(time = Time.zone.now) ⇒ Boolean
130 131 132 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 130 def can_continue?(time = Time.zone.now) %w[active disabled].include?(state) && can_start?(time) end |
#can_start?(time = Time.zone.now) ⇒ Boolean
125 126 127 128 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 125 def can_start?(time = Time.zone.now) (end_time.nil? || next_occurrence_time(time) < end_time) && (max_iteration.nil? || iteration < max_iteration) end |
#cancel ⇒ Object
92 93 94 95 96 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 92 def cancel self.state = 'cancelled' save! tasks.active.each(&:cancel) end |
#cancelled? ⇒ Boolean
138 139 140 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 138 def cancelled? state == 'cancelled' end |
#disabled? ⇒ Boolean
59 60 61 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 59 def disabled? !enabled? end |
#done? ⇒ Boolean
142 143 144 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 142 def done? %w[cancelled finished].include?(state) end |
#enabled=(value) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 40 def enabled=(value) task = tasks.find_by(:state => :scheduled) if task ForemanTasks.dynflow.world.persistence.set_delayed_plan_frozen(task.execution_plan.id, !value, next_occurrence_time) if value task.update!(:start_at => next_occurrence_time) if task.start_at < Time.zone.now update(:state => 'active') end elsif value raise RecurringLogicCancelledException end update(:state => 'disabled') unless value end |
#enabled? ⇒ Boolean
55 56 57 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 55 def enabled? state != 'disabled' end |
#finished? ⇒ Boolean
134 135 136 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 134 def finished? state == 'finished' end |
#generate_delay_options(time = Time.zone.now, options = {}) ⇒ Object
106 107 108 109 110 111 112 113 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 106 def (time = Time.zone.now, = {}) { :start_at => next_occurrence_time(time), :start_before => ['start_before'], :recurring_logic_id => id, :frozen => disabled?, } end |
#humanized_state ⇒ Object
146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 146 def humanized_state case state when 'active' N_('Active') when 'cancelled' N_('Cancelled') when 'finished' N_('Finished') when 'disabled' N_('Disabled') else N_('N/A') end end |
#last_task ⇒ Object
32 33 34 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 32 def last_task tasks.order(:started_at).where.not(started_at: nil).last end |
#next_occurrence_time(time = Time.zone.now) ⇒ Object
98 99 100 101 102 103 104 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 98 def next_occurrence_time(time = Time.zone.now) @parser ||= Fugit.do_parse_cron(cron_line) # @parser.next(start_time) is not inclusive of the start_time hence stepping back one run to include checking start_time for the first run. before_next = @parser.next_time(@parser.previous_time(time.iso8601)) return before_next.utc.localtime if before_next >= time && tasks.count == 0 @parser.next_time(time).utc.localtime end |
#next_task ⇒ Object
36 37 38 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 36 def next_task tasks.order(:start_at).where(started_at: nil).last end |
#start(action_class, *args) ⇒ Object
63 64 65 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 63 def start(action_class, *args) start_after(action_class, Time.zone.now, *args) end |
#start_after(action_class, time, *args) ⇒ Object
67 68 69 70 71 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 67 def start_after(action_class, time, *args) self.state = 'active' save! trigger_repeat_after(time, action_class, *args) end |
#trigger_repeat(action_class, *args) ⇒ Object
88 89 90 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 88 def trigger_repeat(action_class, *args) trigger_repeat_after(Time.zone.now, action_class, *args) end |
#trigger_repeat_after(time, action_class, *args) ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 73 def trigger_repeat_after(time, action_class, *args) return if cancelled? if can_continue?(time) self.iteration += 1 save! ::ForemanTasks.delay action_class, (time), *args else self.state = 'finished' save! nil end end |
#valid?(*_) ⇒ Boolean
115 116 117 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 115 def valid?(*_) cron_line.present? && valid_cronline? && !state.nil? || can_start? end |
#valid_cronline? ⇒ Boolean
119 120 121 122 123 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 119 def valid_cronline? !!next_occurrence_time rescue ArgumentError => _ false end |
#valid_purpose? ⇒ Boolean
205 206 207 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 205 def valid_purpose? !(purpose.present? && self.class.where(:purpose => purpose, :state => %w[active disabled]).any?) end |