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
- #next_occurrence_time(time = Time.zone.now) ⇒ 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
153 154 155 156 157 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 153 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
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 180 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
159 160 161 162 163 164 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 159 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
166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 166 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
122 123 124 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 122 def can_continue?(time = Time.zone.now) %w[active disabled].include?(state) && can_start?(time) end |
#can_start?(time = Time.zone.now) ⇒ Boolean
117 118 119 120 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 117 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
84 85 86 87 88 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 84 def cancel self.state = 'cancelled' save! tasks.active.each(&:cancel) end |
#cancelled? ⇒ Boolean
130 131 132 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 130 def cancelled? state == 'cancelled' end |
#disabled? ⇒ Boolean
51 52 53 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 51 def disabled? !enabled? end |
#done? ⇒ Boolean
134 135 136 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 134 def done? %w[cancelled finished].include?(state) end |
#enabled=(value) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 32 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
47 48 49 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 47 def enabled? state != 'disabled' end |
#finished? ⇒ Boolean
126 127 128 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 126 def finished? state == 'finished' end |
#generate_delay_options(time = Time.zone.now, options = {}) ⇒ Object
98 99 100 101 102 103 104 105 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 98 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
138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 138 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 |
#next_occurrence_time(time = Time.zone.now) ⇒ Object
90 91 92 93 94 95 96 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 90 def next_occurrence_time(time = Time.zone.now) @parser ||= CronParser.new(cron_line, Time.zone) # @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(@parser.last(time)) return before_next if before_next >= time && tasks.count == 0 @parser.next(time) end |
#start(action_class, *args) ⇒ Object
55 56 57 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 55 def start(action_class, *args) start_after(action_class, Time.zone.now, *args) end |
#start_after(action_class, time, *args) ⇒ Object
59 60 61 62 63 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 59 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
80 81 82 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 80 def trigger_repeat(action_class, *args) trigger_repeat_after(Time.zone.now, action_class, *args) end |
#trigger_repeat_after(time, action_class, *args) ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 65 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
107 108 109 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 107 def valid?(*_) cron_line.present? && valid_cronline? && !state.nil? || can_start? end |
#valid_cronline? ⇒ Boolean
111 112 113 114 115 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 111 def valid_cronline? !!next_occurrence_time rescue ArgumentError => _ false end |
#valid_purpose? ⇒ Boolean
197 198 199 |
# File 'app/models/foreman_tasks/recurring_logic.rb', line 197 def valid_purpose? !(purpose.present? && self.class.where(:purpose => purpose, :state => %w[active disabled]).any?) end |