lib/crono_trigger/schedulable.rb in crono_trigger-0.1.0 vs lib/crono_trigger/schedulable.rb in crono_trigger-0.2.0

- old
+ new

@@ -44,11 +44,13 @@ end rel end - before_create :ensure_next_execute_at + before_update :update_next_execute_at_if_update_cron + + validate :validate_cron_format end module ClassMethods def executables_with_lock(primary_key_offset: nil, limit: 1000) records = nil @@ -107,10 +109,22 @@ retry_or_reset!(ex) raise end + def activate_schedule!(at: Time.current) + time = calculate_next_execute_at || at + + if new_record? + self[crono_trigger_column_name(:next_execute_at)] ||= time + else + unless self[crono_trigger_column_name(:next_execute_at)] + update_column(crono_trigger_column_name(:next_execute_at), time) + end + end + end + def retry! logger.info "Retry #{self.class}-#{id}" if logger now = Time.current wait = crono_trigger_options[:exponential_backoff] ? retry_interval * [2 * (retry_count - 1), 1].max : retry_interval @@ -169,16 +183,32 @@ end def calculate_next_execute_at(now = Time.current) if self[crono_trigger_column_name(:cron)] tz = self[crono_trigger_column_name(:timezone)].try { |zn| TZInfo::Timezone.get(zn) } - now = tz ? now.in_time_zone(tz) : now - Chrono::NextTime.new(now: now, source: self[crono_trigger_column_name(:cron)]).to_time + base = [now, self[crono_trigger_column_name(:started_at)]].max + cron_now = tz ? base.in_time_zone(tz) : base + Chrono::NextTime.new(now: cron_now, source: self[crono_trigger_column_name(:cron)]).to_time end end - def ensure_next_execute_at - self[crono_trigger_column_name(:next_execute_at)] ||= calculate_next_execute_at || Time.current + def update_next_execute_at_if_update_cron + if changes[crono_trigger_column_name(:cron)] || changes[crono_trigger_column_name(:timezone)] + if self[crono_trigger_column_name(:cron)] + self[crono_trigger_column_name(:next_execute_at)] = calculate_next_execute_at + end + end + end + + def validate_cron_format + return unless self[crono_trigger_column_name(:cron)] + + Chrono::NextTime.new(now: Time.current, source: self[crono_trigger_column_name(:cron)]).to_time + rescue Chrono::Fields::Base::InvalidField + self.errors.add( + crono_trigger_column_name(:cron).to_sym, + crono_trigger_options["invalid_field_error_message"] || "has invalid field" + ) end def retry_limit crono_trigger_options[:retry_limit] || DEFAULT_RETRY_LIMIT end