rails timezone support

This commit is contained in:
haoxilu
2017-02-24 09:05:43 +08:00
parent a7488df85b
commit 258052b852
7 changed files with 34 additions and 32 deletions

View File

@@ -22,7 +22,7 @@ module Crono
parse_options(ARGV) parse_options(ARGV)
parse_command(ARGV) parse_command(ARGV)
setup_log setup_log
write_pid unless config.daemonize write_pid unless config.daemonize
load_rails load_rails
@@ -120,7 +120,7 @@ module Crono
def start_working_loop def start_working_loop
loop do loop do
next_time, jobs = Crono.scheduler.next_jobs 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) jobs.each(&:perform)
end end
end end

View File

@@ -12,7 +12,7 @@ module Crono
def initialize(performer, period, job_args, job_options = nil) def initialize(performer, period, job_args, job_options = nil)
self.execution_interval = 0.minutes self.execution_interval = 0.minutes
self.performer, self.period = performer, period 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_log = StringIO.new
self.job_logger = Logger.new(job_log) self.job_logger = Logger.new(job_log)
self.job_options = job_options || {} self.job_options = job_options || {}
@@ -22,7 +22,7 @@ module Crono
def next def next
return next_performed_at if next_performed_at.future? return next_performed_at if next_performed_at.future?
Time.now Time.zone.now
end end
def description def description
@@ -37,7 +37,7 @@ module Crono
return Thread.new {} if perform_before_interval? return Thread.new {} if perform_before_interval?
log "Perform #{performer}" 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) self.next_performed_at = period.next(since: last_performed_at)
Thread.new { perform_job } Thread.new { perform_job }
@@ -86,7 +86,7 @@ module Crono
end end
def handle_job_fail(exception) 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 self.healthy = false
log_error "Finished #{performer} in #{finished_time_sec} seconds"\ log_error "Finished #{performer} in #{finished_time_sec} seconds"\
" with error: #{exception.message}" " with error: #{exception.message}"
@@ -94,7 +94,7 @@ module Crono
end end
def handle_job_success 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 self.healthy = true
log "Finished #{performer} in #{finished_time_sec} seconds" log "Finished #{performer} in #{finished_time_sec} seconds"
end end

View File

@@ -27,7 +27,7 @@ module Crono
@next = @next.beginning_of_week.advance(days: @on) if @on @next = @next.beginning_of_week.advance(days: @on) if @on
@next = @next.change(time_atts) @next = @next.change(time_atts)
return @next if @next.future? return @next if @next.future?
Time.now Time.zone.now
end end
def description def description
@@ -47,8 +47,8 @@ module Crono
end end
def initial_day def initial_day
return Time.now unless @on return Time.zone.now unless @on
day = Time.now.beginning_of_week.advance(days: @on) day = Time.zone.now.beginning_of_week.advance(days: @on)
day = day.change(time_atts) day = day.change(time_atts)
return day if day.future? return day if day.future?
@period.from_now.beginning_of_week.advance(days: @on) @period.from_now.beginning_of_week.advance(days: @on)
@@ -68,7 +68,7 @@ module Crono
case at case at
when String when String
time = Time.parse(at) time = Time.zone.parse(at)
return time.hour, time.min return time.hour, time.min
when Hash when Hash
return at[:hour], at[:min] return at[:hour], at[:min]

View File

@@ -8,8 +8,8 @@ module Crono
def self.parse(value) def self.parse(value)
time = time =
case value case value
when String then Time.parse(value).utc when String then Time.zone.parse(value).utc
when Hash then Time.now.change(value).utc when Hash then Time.zone.now.change(value).utc
when Time then value.utc when Time then value.utc
else else
fail "Unknown TimeOfDay format: #{value.inspect}" fail "Unknown TimeOfDay format: #{value.inspect}"

View File

@@ -98,7 +98,7 @@ describe Crono::Job do
end end
it 'should update saved job' do it 'should update saved job' do
job.last_performed_at = Time.now job.last_performed_at = Time.zone.now
job.healthy = true job.healthy = true
job.job_args = JSON.generate([{some: 'data'}]) job.job_args = JSON.generate([{some: 'data'}])
job.save job.save
@@ -134,7 +134,7 @@ describe Crono::Job do
describe '#load' do describe '#load' do
before 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 job.save
end end

View File

@@ -27,23 +27,23 @@ describe Crono::Period do
it "should return a 'on' day" do it "should return a 'on' day" do
@period = Crono::Period.new(1.week, on: :thursday, at: '15:30') @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 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) .change(hour: 15, min: 30)
expect(@period.next(since: last_run_time)).to be_eql(next_run_at) expect(@period.next(since: last_run_time)).to be_eql(next_run_at)
end end
it "should return a next week day 'on'" do it "should return a next week day 'on'" do
@period = Crono::Period.new(1.week, on: :thursday) @period = Crono::Period.new(1.week, on: :thursday)
Timecop.freeze(Time.now.beginning_of_week.advance(days: 4)) do Timecop.freeze(Time.zone.now.beginning_of_week.advance(days: 4)) do
expect(@period.next).to be_eql(Time.now.next_week.advance(days: 3)) expect(@period.next).to be_eql(Time.zone.now.next_week.advance(days: 3))
end end
end end
it 'should return a current week day on the first run if not too late' do it 'should return a current week day on the first run if not too late' do
@period = Crono::Period.new(7.days, on: :tuesday) @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) tuesday = beginning_of_the_week.advance(days: 1)
Timecop.freeze(beginning_of_the_week) do Timecop.freeze(beginning_of_the_week) do
expect(@period.next).to be_eql(tuesday) expect(@period.next).to be_eql(tuesday)
@@ -52,19 +52,19 @@ describe Crono::Period do
it 'should return today on the first run if not too late' do it 'should return today on the first run if not too late' do
@period = Crono::Period.new(1.week, on: :sunday, at: '22:00') @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 .change(hour: 21, min: 0)) do
expect(@period.next).to be_eql( 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 end
end end
context 'in daily basis' do 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') @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 end
it 'should return time 2 days from now' do it 'should return time 2 days from now' do
@@ -107,33 +107,33 @@ describe Crono::Period do
time = 10.minutes.from_now time = 10.minutes.from_now
at = { hour: time.hour, min: time.min } at = { hour: time.hour, min: time.min }
@period = Crono::Period.new(2.days, at: at) @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
end end
context 'in hourly basis' do context 'in hourly basis' do
it 'should return next hour minutes if current hour minutes passed' 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 }) @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 expect(@period.next.utc.to_s).to be_eql 1.hour.from_now.beginning_of_hour.advance(minutes: 15).utc.to_s
end end
end end
it 'should return current hour minutes if current hour minutes not passed yet' do 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 }) @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
end end
it 'should return next hour minutes within the given interval' do 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') @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 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') @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 end
end end

View File

@@ -8,6 +8,8 @@ require 'byebug'
require 'crono' require 'crono'
require 'generators/crono/install/templates/migrations/create_crono_jobs.rb' require 'generators/crono/install/templates/migrations/create_crono_jobs.rb'
Time.zone_default = Time.find_zone("UTC")
ActiveRecord::Base.establish_connection( ActiveRecord::Base.establish_connection(
adapter: 'sqlite3', adapter: 'sqlite3',
database: 'file::memory:?cache=shared' database: 'file::memory:?cache=shared'