Compare commits

..

5 Commits

Author SHA1 Message Date
Dzmitry Plashchynski
b4ad8fb953 Handle a few jobs scheduled at the same time 2015-04-08 20:08:58 +03:00
Dzmitry Plashchynski
d075a55f03 Merge branch 'master' of github.com:plashchynski/crono 2015-03-24 23:25:49 +02:00
Dzmitry Plashchynski
2d72020ac4 Fix spec 2015-03-24 23:25:38 +02:00
Dzmitry Plashchynski
cde8a2d214 Update README.md 2015-03-24 22:46:21 +02:00
Dzmitry Plashchynski
2ec9cfa829 Update Gemfile.lock 2015-03-24 22:24:08 +02:00
7 changed files with 49 additions and 40 deletions

View File

@@ -1,7 +1,7 @@
PATH
remote: .
specs:
crono (0.8.0)
crono (0.8.1)
activejob (~> 4.0)
activerecord (~> 4.0)
activesupport (~> 4.0)
@@ -9,17 +9,17 @@ PATH
GEM
remote: https://rubygems.org/
specs:
activejob (4.2.0)
activesupport (= 4.2.0)
activejob (4.2.1)
activesupport (= 4.2.1)
globalid (>= 0.3.0)
activemodel (4.2.0)
activesupport (= 4.2.0)
activemodel (4.2.1)
activesupport (= 4.2.1)
builder (~> 3.1)
activerecord (4.2.0)
activemodel (= 4.2.0)
activesupport (= 4.2.0)
activerecord (4.2.1)
activemodel (= 4.2.1)
activesupport (= 4.2.1)
arel (~> 6.0)
activesupport (4.2.0)
activesupport (4.2.1)
i18n (~> 0.7)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)

View File

@@ -1,8 +1,6 @@
Crono — Job scheduler for Rails
------------------------
[![Gem Version](https://badge.fury.io/rb/crono.svg)](http://badge.fury.io/rb/crono)Here's an example of a test job:
[![Gem Version](https://badge.fury.io/rb/crono.svg)](http://badge.fury.io/rb/crono)
[![Build Status](https://travis-ci.org/plashchynski/crono.svg?branch=master)](https://travis-ci.org/plashchynski/crono)
[![Code Climate](https://codeclimate.com/github/plashchynski/crono/badges/gpa.svg)](https://codeclimate.com/github/plashchynski/crono)
[![security](https://hakiri.io/github/plashchynski/crono/master.svg)](https://hakiri.io/github/plashchynski/crono/master)

View File

@@ -79,9 +79,10 @@ module Crono
end
def start_working_loop
while (job = Crono.scheduler.next)
sleep(job.next - Time.now)
job.perform
while true
next_time, jobs = Crono.scheduler.next_jobs
sleep(next_time - Time.now)
jobs.each(&:perform)
end
end

View File

@@ -17,8 +17,7 @@ module Crono
end
def next
next_time = period.next(since: last_performed_at)
next_time.past? ? period.next : next_time
period.next(since: last_performed_at)
end
def description

View File

@@ -12,14 +12,8 @@ module Crono
jobs << job
end
def next
queue.first
end
private
def queue
jobs.sort_by(&:next)
def next_jobs
jobs.group_by(&:next).sort_by {|time,_| time }.first
end
end

View File

@@ -1,7 +1,7 @@
require 'spec_helper'
describe Crono::Job do
let(:period) { Crono::Period.new(2.day) }
let(:period) { Crono::Period.new(2.day, at: '15:00') }
let(:job) { Crono::Job.new(TestJob, period) }
let(:failing_job) { Crono::Job.new(TestFailingJob, period) }
@@ -10,6 +10,12 @@ describe Crono::Job do
expect(job.period).to be period
end
describe '#next' do
it 'should return next performing time according to period' do
expect(job.next).to be_eql period.next
end
end
describe '#perform' do
after { job.send(:model).destroy }
@@ -40,14 +46,14 @@ describe Crono::Job do
expect(failing_job.healthy).to be false
end
it 'should set @_crono_job variable to instance' do
xit 'should set @_crono_job variable to instance' do
job.perform
end
end
describe '#description' do
it 'should return job identificator' do
expect(job.description).to be_eql('Perform TestJob every 2 days')
expect(job.description).to be_eql('Perform TestJob every 2 days at 15:00')
end
end

View File

@@ -1,27 +1,38 @@
require 'spec_helper'
describe Crono::Scheduler do
before(:each) do
@scheduler = Crono::Scheduler.new
@jobs = [
Crono::Period.new(3.day, at: 10.minutes.from_now.strftime('%H:%M')),
Crono::Period.new(1.day, at: 20.minutes.from_now.strftime('%H:%M')),
Crono::Period.new(7.day, at: 40.minutes.from_now.strftime('%H:%M'))
].map { |period| Crono::Job.new(TestJob, period) }
@scheduler.jobs = @jobs
end
let(:scheduler) { Crono::Scheduler.new }
describe '#add_job' do
it 'should call Job#load on Job' do
@job = Crono::Job.new(TestJob, Crono::Period.new(10.day, at: '04:05'))
expect(@job).to receive(:load)
@scheduler.add_job(@job)
scheduler.add_job(@job)
end
end
describe '#next' do
describe '#next_jobs' do
it 'should return next job in schedule' do
expect(@scheduler.next).to be @jobs[0]
scheduler.jobs = jobs = [
Crono::Period.new(3.days, at: 10.minutes.from_now.strftime('%H:%M')),
Crono::Period.new(1.day, at: 20.minutes.from_now.strftime('%H:%M')),
Crono::Period.new(7.days, at: 40.minutes.from_now.strftime('%H:%M'))
].map { |period| Crono::Job.new(TestJob, period) }
time, jobs = scheduler.next_jobs
expect(jobs).to be_eql [jobs[0]]
end
it 'should return an array of jobs scheduled at same time' do
time = 5.minutes.from_now
scheduler.jobs = jobs = [
Crono::Period.new(1.day, at: time.strftime('%H:%M')),
Crono::Period.new(1.day, at: time.strftime('%H:%M')),
Crono::Period.new(1.day, at: 10.minutes.from_now.strftime('%H:%M'))
].map { |period| Crono::Job.new(TestJob, period) }
time, jobs = scheduler.next_jobs
expect(jobs).to be_eql [jobs[0], jobs[1]]
end
end
end