diff --git a/CHANGELOG.md b/CHANGELOG.md index bfa51b6..92fe993 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [Unreleased] - + +### Fixed +- Skip missed schedules to avoid running tasks multiple times on next schedule + ## [0.17.1] - 2023-12-02 ### Fixed diff --git a/spec/mel/task_spec.cr b/spec/mel/task_spec.cr index 1ee89d2..814e65f 100644 --- a/spec/mel/task_spec.cr +++ b/spec/mel/task_spec.cr @@ -90,6 +90,15 @@ describe Mel::Task do Mel::PeriodicTask.find(id).try(&.attempts.> 0).should be_true end end + + it "skips missed schedules" do + SendEmailJob.run_every(1.hour, address: "aa@bb.cc") + + Timecop.travel(10.hours.from_now) do + Mel.start_and_stop + Mel::Task.find_lte(Time.local, -1).should be_nil + end + end end describe "#enqueue" do diff --git a/src/mel/task/log_helpers.cr b/src/mel/task/log_helpers.cr index 252a7a4..c25292b 100644 --- a/src/mel/task/log_helpers.cr +++ b/src/mel/task/log_helpers.cr @@ -41,7 +41,7 @@ abstract class Mel::Task end private def log_failed : Nil - attempts_str = 1 == attempts ? "attempt" : "attempts" + attempts_str = first_attempt? ? "attempt" : "attempts" Mel.log.error &.emit( "Task failed after #{attempts} #{attempts_str}", diff --git a/src/worker/task.cr b/src/worker/task.cr index acc6077..de6b7f4 100644 --- a/src/worker/task.cr +++ b/src/worker/task.cr @@ -9,6 +9,7 @@ abstract class Mel::Task spawn(name: id) do log_running + set_run_time job.run rescue error log_errored(error) @@ -48,6 +49,14 @@ abstract class Mel::Task do_after_run(false) end + private def set_run_time + self.time = Time.local if first_attempt? + end + + private def first_attempt? + 1 == attempts + end + macro inherited def self.find_pending(count : Int, *, delete : Bool = false) : Array(self)? return if count.zero?