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