Skip to content

Commit

Permalink
✨ rails timezone support
Browse files Browse the repository at this point in the history
  • Loading branch information
0xRichardH committed Feb 24, 2017
1 parent a7488df commit 258052b
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 32 deletions.
4 changes: 2 additions & 2 deletions lib/crono/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def run
parse_options(ARGV)
parse_command(ARGV)

setup_log
setup_log

write_pid unless config.daemonize
load_rails
Expand Down Expand Up @@ -120,7 +120,7 @@ def rails_root_defined?
def start_working_loop
loop do
next_time, jobs = Crono.scheduler.next_jobs
sleep(next_time - Time.now) if next_time > Time.now
sleep(next_time - Time.zone.now) if next_time > Time.zone.now
jobs.each(&:perform)
end
end
Expand Down
10 changes: 5 additions & 5 deletions lib/crono/job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class Job
def initialize(performer, period, job_args, job_options = nil)
self.execution_interval = 0.minutes
self.performer, self.period = performer, period
self.job_args = JSON.generate(job_args)
self.job_args = JSON.generate(job_args)
self.job_log = StringIO.new
self.job_logger = Logger.new(job_log)
self.job_options = job_options || {}
Expand All @@ -22,7 +22,7 @@ def initialize(performer, period, job_args, job_options = nil)

def next
return next_performed_at if next_performed_at.future?
Time.now
Time.zone.now
end

def description
Expand All @@ -37,7 +37,7 @@ def perform
return Thread.new {} if perform_before_interval?

log "Perform #{performer}"
self.last_performed_at = Time.now
self.last_performed_at = Time.zone.now
self.next_performed_at = period.next(since: last_performed_at)

Thread.new { perform_job }
Expand Down Expand Up @@ -86,15 +86,15 @@ def perform_job
end

def handle_job_fail(exception)
finished_time_sec = format('%.2f', Time.now - last_performed_at)
finished_time_sec = format('%.2f', Time.zone.now - last_performed_at)
self.healthy = false
log_error "Finished #{performer} in #{finished_time_sec} seconds"\
" with error: #{exception.message}"
log_error exception.backtrace.join("\n")
end

def handle_job_success
finished_time_sec = format('%.2f', Time.now - last_performed_at)
finished_time_sec = format('%.2f', Time.zone.now - last_performed_at)
self.healthy = true
log "Finished #{performer} in #{finished_time_sec} seconds"
end
Expand Down
8 changes: 4 additions & 4 deletions lib/crono/period.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def next(since: nil)
@next = @next.beginning_of_week.advance(days: @on) if @on
@next = @next.change(time_atts)
return @next if @next.future?
Time.now
Time.zone.now
end

def description
Expand All @@ -47,8 +47,8 @@ def initial_next
end

def initial_day
return Time.now unless @on
day = Time.now.beginning_of_week.advance(days: @on)
return Time.zone.now unless @on
day = Time.zone.now.beginning_of_week.advance(days: @on)
day = day.change(time_atts)
return day if day.future?
@period.from_now.beginning_of_week.advance(days: @on)
Expand All @@ -68,7 +68,7 @@ def parse_at(at)

case at
when String
time = Time.parse(at)
time = Time.zone.parse(at)
return time.hour, time.min
when Hash
return at[:hour], at[:min]
Expand Down
4 changes: 2 additions & 2 deletions lib/crono/time_of_day.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ class TimeOfDay
def self.parse(value)
time =
case value
when String then Time.parse(value).utc
when Hash then Time.now.change(value).utc
when String then Time.zone.parse(value).utc
when Hash then Time.zone.now.change(value).utc
when Time then value.utc
else
fail "Unknown TimeOfDay format: #{value.inspect}"
Expand Down
4 changes: 2 additions & 2 deletions spec/job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def test_preform_job_twice
end

it 'should update saved job' do
job.last_performed_at = Time.now
job.last_performed_at = Time.zone.now
job.healthy = true
job.job_args = JSON.generate([{some: 'data'}])
job.save
Expand Down Expand Up @@ -134,7 +134,7 @@ def test_preform_job_twice

describe '#load' do
before do
@saved_last_performed_at = job.last_performed_at = Time.now
@saved_last_performed_at = job.last_performed_at = Time.zone.now
job.save
end

Expand Down
34 changes: 17 additions & 17 deletions spec/period_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,23 @@

it "should return a 'on' day" do
@period = Crono::Period.new(1.week, on: :thursday, at: '15:30')
current_week = Time.now.beginning_of_week
current_week = Time.zone.now.beginning_of_week
last_run_time = current_week.advance(days: 1) # last run on the tuesday
next_run_at = Time.now.next_week.advance(days: 3)
next_run_at = Time.zone.now.next_week.advance(days: 3)
.change(hour: 15, min: 30)
expect(@period.next(since: last_run_time)).to be_eql(next_run_at)
end

it "should return a next week day 'on'" do
@period = Crono::Period.new(1.week, on: :thursday)
Timecop.freeze(Time.now.beginning_of_week.advance(days: 4)) do
expect(@period.next).to be_eql(Time.now.next_week.advance(days: 3))
Timecop.freeze(Time.zone.now.beginning_of_week.advance(days: 4)) do
expect(@period.next).to be_eql(Time.zone.now.next_week.advance(days: 3))
end
end

it 'should return a current week day on the first run if not too late' do
@period = Crono::Period.new(7.days, on: :tuesday)
beginning_of_the_week = Time.now.beginning_of_week
beginning_of_the_week = Time.zone.now.beginning_of_week
tuesday = beginning_of_the_week.advance(days: 1)
Timecop.freeze(beginning_of_the_week) do
expect(@period.next).to be_eql(tuesday)
Expand All @@ -52,19 +52,19 @@

it 'should return today on the first run if not too late' do
@period = Crono::Period.new(1.week, on: :sunday, at: '22:00')
Timecop.freeze(Time.now.beginning_of_week.advance(days: 6)
Timecop.freeze(Time.zone.now.beginning_of_week.advance(days: 6)
.change(hour: 21, min: 0)) do
expect(@period.next).to be_eql(
Time.now.beginning_of_week.advance(days: 6).change(hour: 22, min: 0)
Time.zone.now.beginning_of_week.advance(days: 6).change(hour: 22, min: 0)
)
end
end
end

context 'in daily basis' do
it "should return Time.now if the next time in past" do
it "should return Time.zone.now if the next time in past" do
@period = Crono::Period.new(1.day, at: '06:00')
expect(@period.next(since: 2.days.ago).to_s).to be_eql(Time.now.to_s)
expect(@period.next(since: 2.days.ago).to_s).to be_eql(Time.zone.now.to_s)
end

it 'should return time 2 days from now' do
Expand Down Expand Up @@ -107,33 +107,33 @@
time = 10.minutes.from_now
at = { hour: time.hour, min: time.min }
@period = Crono::Period.new(2.days, at: at)
expect(@period.next.utc.to_s).to be_eql(Time.now.change(at).utc.to_s)
expect(@period.next.utc.to_s).to be_eql(Time.zone.now.change(at).utc.to_s)
end
end

context 'in hourly basis' do
it 'should return next hour minutes if current hour minutes passed' do
Timecop.freeze(Time.now.beginning_of_hour.advance(minutes: 20)) do
Timecop.freeze(Time.zone.now.beginning_of_hour.advance(minutes: 20)) do
@period = Crono::Period.new(1.hour, at: { min: 15 })
expect(@period.next.utc.to_s).to be_eql 1.hour.from_now.beginning_of_hour.advance(minutes: 15).utc.to_s
end
end

it 'should return current hour minutes if current hour minutes not passed yet' do
Timecop.freeze(Time.now.beginning_of_hour.advance(minutes: 10)) do
Timecop.freeze(Time.zone.now.beginning_of_hour.advance(minutes: 10)) do
@period = Crono::Period.new(1.hour, at: { min: 15 })
expect(@period.next.utc.to_s).to be_eql Time.now.beginning_of_hour.advance(minutes: 15).utc.to_s
expect(@period.next.utc.to_s).to be_eql Time.zone.now.beginning_of_hour.advance(minutes: 15).utc.to_s
end
end

it 'should return next hour minutes within the given interval' do
Timecop.freeze(Time.now.change(hour: 16, min: 10)) do
Timecop.freeze(Time.zone.now.change(hour: 16, min: 10)) do
@period = Crono::Period.new(1.hour, at: { min: 15 }, within: '08:00-16:00')
expect(@period.next.utc.to_s).to be_eql Time.now.tomorrow.change(hour: 8, min: 15).utc.to_s
expect(@period.next.utc.to_s).to be_eql Time.zone.now.tomorrow.change(hour: 8, min: 15).utc.to_s
end
Timecop.freeze(Time.now.change(hour: 16, min: 10)) do
Timecop.freeze(Time.zone.now.change(hour: 16, min: 10)) do
@period = Crono::Period.new(1.hour, at: { min: 15 }, within: '23:00-07:00')
expect(@period.next.utc.to_s).to be_eql Time.now.change(hour: 23, min: 15).utc.to_s
expect(@period.next.utc.to_s).to be_eql Time.zone.now.change(hour: 23, min: 15).utc.to_s
end
end
end
Expand Down
2 changes: 2 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
require 'crono'
require 'generators/crono/install/templates/migrations/create_crono_jobs.rb'

Time.zone_default = Time.find_zone("UTC")

ActiveRecord::Base.establish_connection(
adapter: 'sqlite3',
database: 'file::memory:?cache=shared'
Expand Down

0 comments on commit 258052b

Please sign in to comment.