From 65f907f2394a4b9567d01383632b32aea44afdeb Mon Sep 17 00:00:00 2001 From: akadusei Date: Wed, 6 Dec 2023 12:56:46 +0000 Subject: [PATCH] Add `from:` parameter to `Mel::Job::Every#run_every` methods This is used to specify the first run time. --- CHANGELOG.md | 5 +++++ README.md | 8 ++++++++ spec/mel/job/every_spec.cr | 24 ++++++++++++++++++++++++ src/mel/job/every.cr | 6 ++++-- 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38b7f12..47106a9 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). +## [Added] - + +### Changed +- Add `from:` parameter to `Mel::Job::Every#run_every` methods + ## [0.17.2] - 2023-12-04 ### Fixed diff --git a/README.md b/README.md index fcdf142..0098a6f 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,14 @@ This makes *Redis* the *source of truth* for schedules, allowing to easily scale DoSomeWork.run_every(10.minutes, for: 1.hour, arg_1: 5, arg_2: "value") ``` + This will do the first run 10 minutes from now. If you would like to do the first run some other time, specify that in a `from:` argument: + + ```crystal + # ->>> src/app/some_file.cr + + DoSomeWork.run_every(10.minutes, from: Time.local, for: 1.hour, arg_1: 5, arg_2: "value") + ``` + Instead of `for:`, you may use `till:` and specify a `Time`. Leave those out to run forever. - Run on a Cron schedule: diff --git a/spec/mel/job/every_spec.cr b/spec/mel/job/every_spec.cr index 77615ff..9320771 100644 --- a/spec/mel/job/every_spec.cr +++ b/spec/mel/job/every_spec.cr @@ -21,6 +21,30 @@ describe Mel::Job::Every do Mel::PeriodicTask.find(id).should be_a(Mel::PeriodicTask) end + it "starts at specified time" do + address = "user@domain.tld" + id = "1001" + + SendEmailEveryJob.run_every( + 2.hours, + from: 10.days.from_now, + id: id, + address: address + ) + + Time::Location.local = Time::Location.load("Europe/Berlin") + + Timecop.travel(6.days.from_now) do + task = Mel::PeriodicTask.find(id) + task.try(&.due?).should be_false + end + + Timecop.travel(10.days.from_now) do + task = Mel::PeriodicTask.find(id) + task.try(&.due?).should be_true + end + end + it "deletes task after given time" do address = "user@domain.tld" id = "1001" diff --git a/src/mel/job/every.cr b/src/mel/job/every.cr index 051c5b9..4d46a5c 100644 --- a/src/mel/job/every.cr +++ b/src/mel/job/every.cr @@ -5,6 +5,7 @@ module Mel::Job::Every def self.run_every( interval : Time::Span, for : Time::Span, + from : Time? = nil, id = UUID.random.hexstring, retries = nil, redis = nil, @@ -12,20 +13,21 @@ module Mel::Job::Every **job_args ) till = for.from_now - run_every(interval, till, id, retries, redis, force, **job_args) + run_every(interval, till, from, id, retries, redis, force, **job_args) end def self.run_every( interval : Time::Span, till : Time? = nil, + from : Time? = nil, id = UUID.random.hexstring, retries = nil, redis = nil, force = false, **job_args ) : String? + time = from || interval.abs.from_now job = new(**job_args) - time = interval.abs.from_now task = Mel::PeriodicTask.new( id.to_s,