Add Job class

This commit is contained in:
Dzmitry Plashchynski
2015-03-04 18:31:59 +02:00
parent 36c35bce7d
commit 828488a6bc
10 changed files with 91 additions and 38 deletions

15
examples/cronotab.rb Normal file
View File

@@ -0,0 +1,15 @@
# cronotab.rb — Crono configuration example file
#
# Here you can specify periodic jobs and their schedule.
# You can specify a periodic job as a ActiveJob class in `app/jobs/`
# Actually you can use any class. The only requirement is that
# the class should implement a method `perform` without arguments.
#
class TestJob
def perform
puts "Test!"
end
end
Crono.perform(TestJob).every 5.second

View File

@@ -4,6 +4,7 @@ end
require "active_support/all"
require "crono/version.rb"
require "crono/period.rb"
require "crono/job.rb"
require "crono/schedule.rb"
require "crono/config.rb"
require "crono/performer_proxy.rb"

View File

@@ -3,17 +3,15 @@ require 'optparse'
module Crono
mattr_accessor :schedule
mattr_accessor :logger
class CLI
include Singleton
attr_accessor :config
attr_accessor :schedule
attr_accessor :logger
def initialize
self.config = Config.new
self.schedule = Schedule.new
Crono.schedule = schedule
Crono.schedule = Schedule.new
end
def run
@@ -44,12 +42,12 @@ module Crono
def init_logger
logfile = config.daemonize ? config.logfile : STDOUT
self.logger = Logger.new(logfile)
Crono.logger = Logger.new(logfile)
end
def print_banner
logger.info "Loading Crono #{Crono::VERSION}"
logger.info "Running in #{RUBY_DESCRIPTION}"
Crono.logger.info "Loading Crono #{Crono::VERSION}"
Crono.logger.info "Running in #{RUBY_DESCRIPTION}"
end
def load_rails
@@ -60,16 +58,11 @@ module Crono
require File.expand_path(config.cronotab)
end
def run_job(klass)
logger.info "Perform #{klass}"
Thread.new { klass.new.perform }
end
def start_working_loop
loop do
klass, time = schedule.next
sleep(time - Time.now)
run_job(klass)
job = Crono.schedule.next
sleep(job.next - Time.now)
job.perform
end
end

19
lib/crono/job.rb Normal file
View File

@@ -0,0 +1,19 @@
module Crono
class Job
attr_accessor :performer
attr_accessor :period
def initialize(performer, period)
self.performer, self.period = performer, period
end
def next
period.next
end
def perform
Crono.logger.info "Perform #{performer}"
Thread.new { performer.new.perform }
end
end
end

View File

@@ -6,7 +6,8 @@ module Crono
end
def every(period, *args)
@schedule.add(@performer, Period.new(period, *args))
job = Job.new(@performer, Period.new(period, *args))
@schedule.add(job)
end
end

View File

@@ -1,20 +1,22 @@
module Crono
class Schedule
attr_accessor :schedule
def initialize
@schedule = []
self.schedule = []
end
def add(peformer, period)
@schedule << [peformer, period]
def add(job)
schedule << job
end
def next
[queue.first[0], queue.first[1].next]
queue.first
end
private
private
def queue
@schedule.sort { |a,b| a[1].next <=> b[1].next }
schedule.sort { |a,b| a.next <=> b.next }
end
end
end

View File

@@ -18,13 +18,6 @@ describe Crono::CLI do
end
end
describe "#run_job" do
it "should run job in separate thread" do
thread = cli.send(:run_job, TestJob).join
expect(thread).to be_stop
end
end
describe "#start_working_loop" do
it "should start working loop"
end

22
spec/job_spec.rb Normal file
View File

@@ -0,0 +1,22 @@
require "spec_helper"
class TestJob
def perform;end
end
describe Crono::Job do
let(:period) { Crono::Period.new(2.day) }
let(:job) { Crono::Job.new(TestJob, period) }
it "should contain performer and period" do
expect(job.performer).to be TestJob
expect(job.period).to be period
end
describe "#perform" do
it "should run performer in separate thread" do
thread = job.perform.join
expect(thread).to be_stop
end
end
end

View File

@@ -5,8 +5,8 @@ class TestJob
end
describe Crono::PerformerProxy do
it "should add job and period to schedule" do
expect(Crono.schedule).to receive(:add).with(TestJob, kind_of(Crono::Period))
it "should add job to schedule" do
expect(Crono.schedule).to receive(:add).with(kind_of(Crono::Job))
Crono.perform(TestJob).every(2.days, at: "15:30")
end
end

View File

@@ -5,16 +5,23 @@ class TestJob
end
describe Crono::Schedule do
before(:each) do
@schedule = Crono::Schedule.new
@jobs = [
Crono::Period.new(3.day, at: "18:55"),
Crono::Period.new(1.day, at: "15:30"),
Crono::Period.new(7.day, at: "06:05")
].map { |period| Crono::Job.new(TestJob, period) }
@schedule.schedule = @jobs
end
describe "#next" do
it "should return next job in schedule" do
@schedule = Crono::Schedule.new
[
Crono::Period.new(3.day, at: "18:55"),
Crono::Period.new(1.day, at: "15:30"),
Crono::Period.new(7.day, at: "06:05")
].each { |period| @schedule.add(TestJob, period) }
expect(@schedule.next).to be @jobs[1]
end
expect(@schedule.next).to be_eql([TestJob, 1.day.from_now.change(hour: 15, min: 30)])
it "should return next based on last" do
expect(@schedule.next)
end
end
end