Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: kookster/say_when
base: fd7fff3c3e
...
head fork: kookster/say_when
compare: 92b80d133a
  • 2 commits
  • 15 files changed
  • 0 commit comments
  • 1 contributor
View
2  bin/say_when
@@ -1,2 +0,0 @@
-#!/usr/bin/env ruby
-require "say_when"
View
4 lib/say_when.rb
@@ -10,6 +10,10 @@
require 'say_when/storage/active_record/job' if defined?(ActiveRecord)
module SayWhen
+
+ def SayWhen.logger=(logger)
+ @@logger = logger
+ end
def SayWhen.logger
unless defined?(@@logger)
View
3  lib/say_when/cron_expression.rb
@@ -428,11 +428,12 @@ def last(date)
def next(date)
next_month = self.values.detect{|v| v > date.month}
- if next_month.nil?
+ result = if next_month.nil?
date.change(:year=>date.year + 1, :month=>self.values.first, :day=>1, :hour=>0)
else
date.change(:month=>next_month, :day=>1, :hour=>0)
end
+ result
end
end
View
125 lib/say_when/scheduler.rb
@@ -4,12 +4,13 @@ class Scheduler
DEFAULT_PROCESSOR_CLASS = SayWhen::Processor::Simple
DEFAULT_STORAGE_STRATEGY = :memory
+
@@scheduler = nil
@@lock = nil
attr_accessor :storage_strategy, :processor_class, :tick_length
- attr_accessor :running, :processor_thread, :scheduler_thread
+ attr_accessor :running
# support for a singleton scheduler, but you are not restricted to this
class << self
@@ -36,10 +37,13 @@ def schedule(job)
self.scheduler.schedule(job)
end
+ def start
+ self.scheduler.start
+ end
+
end
def initialize
- @jobs_to_process = Queue.new
self.tick_length = 1
end
@@ -52,104 +56,69 @@ def processor
end
def start
- logger.info "SayWhen::Scheduler starting..."
- self.running = true
- self.scheduler_thread = start_scheduler_thread
- self.processor_thread = start_processor_thread
- threads_running = scheduler_thread.alive? || processor_thread.alive?
- logger.info "SayWhen::Scheduler started"
- while (running || threads_running)
- logger.info "SayWhen::Scheduler running"
- trap("TERM", "EXIT")
- threads_running = self.scheduler_thread.alive? || self.processor_thread.alive?
- Thread.pass
- sleep(1)
- end
- logger.info "SayWhen::Scheduler stopped"
- end
-
- def stop
- logger.info "SayWhen::Scheduler stopping..."
- self.running = false
- end
-
- def job_class
- @job_class ||= load_job_class
- end
+ logger.info "SayWhen::Scheduler starting"
- def load_job_class
- strategy = @storage_strategy || :memory
- require "say_when/storage/#{strategy}/job"
- job_class_name = "SayWhen::Storage::#{strategy.to_s.camelize}::Job"
- job_class_name.constantize
- end
-
- def schedule(job)
- job_class.create(job)
- end
+ [$stdout, $stderr].each{|s| s.sync = true; s.flush}
+ trap("TERM", "EXIT")
+ trap("QUIT") { stop }
- private
+ begin
+ self.running = true
- def start_scheduler_thread
- Thread.start do
- next_job = nil
+ logger.info "SayWhen::Scheduler running"
+ job = nil
while running
begin
time_now = Time.now
logger.debug "SayWhen:: Looking for job that should be ready to fire before #{time_now}"
- next_job = job_class.acquire_next(time_now)
- if next_job.nil?
+ job = job_class.acquire_next(time_now)
+ if job.nil?
logger.debug "SayWhen:: no jobs to acquire, sleep"
sleep(tick_length)
else
- logger.debug "SayWhen:: adding to process queue: #{next_job.inspect}"
- @jobs_to_process.enq(next_job)
- end
- rescue Object=>ex
- begin
- logger.error "SayWhen:: Failure when getting next trigger to process: #{ex.message}\n\t#{ex.backtrace.join("\t\n")}"
- next_job.release if next_job
- rescue
- puts ex
- end
- end
- Thread.pass
- end
- logger.info "SayWhen::Scheduler scheduler thread stopped"
- end
- end
-
- def start_processor_thread
- Thread.start do
- next_job = nil
- while running
- logger.info "SayWhen::Scheduler processor thread running"
- begin
- # nothing to do? sleep...
- if @jobs_to_process.empty?
- sleep(1)
- else
- # dequeue the next trigger to process
- next_job = @jobs_to_process.deq
-
+ logger.debug "SayWhen:: got a job: #{job.inspect}"
# delegate processing the trigger to the processor
- self.processor.process(next_job)
+ self.processor.process(job)
+ logger.debug "SayWhen:: job processed"
# this should update next fire at, and put back in list of scheduled jobs
- next_job.fired
+ job.fired
+ logger.debug "SayWhen:: job fired complete"
+
end
rescue Object=>ex
begin
- logger.error "SayWhen:: Failure when processing jobs: #{ex.message}\n\t#{ex.backtrace.join("\n\t")}"
- next_job.release if next_job
+ job_msg = job && " job:'#{job.inspect}'"
+ logger.error "SayWhen:: Failure to process#{job_msg}: #{ex.message}\n\t#{ex.backtrace.join("\t\n")}"
+ job.release if job
rescue
puts ex
end
end
- Thread.pass
end
- logger.info "SayWhen::Scheduler processor thread stopped"
end
+
+ logger.info "SayWhen::Scheduler stopped"
+ end
+
+ def stop
+ logger.info "SayWhen::Scheduler stopping..."
+ self.running = false
+ end
+
+ def job_class
+ @job_class ||= load_job_class
+ end
+
+ def load_job_class
+ strategy = @storage_strategy || DEFAULT_STORAGE_STRATEGY
+ require "say_when/storage/#{strategy}/job"
+ job_class_name = "SayWhen::Storage::#{strategy.to_s.camelize}::Job"
+ job_class_name.constantize
+ end
+
+ def schedule(job)
+ job_class.create(job)
end
def logger
View
2  lib/say_when/storage/memory/base.rb
@@ -1,5 +1,5 @@
module SayWhen
- module Store
+ module Storage
module Memory
module Base
View
2  lib/say_when/storage/memory/job.rb
@@ -1,4 +1,4 @@
-require 'say_when/store/memory/base'
+require 'say_when/storage/memory/base'
module SayWhen
module Store
View
22 lib/say_when/tasks.rb
@@ -0,0 +1,22 @@
+namespace :say_when do
+ task :setup
+
+ desc "Start the SayWhen Scheduler"
+ task :start => [ :preload ] do
+ require 'say_when'
+ SayWhen::Scheduler.start
+ end
+
+ # Preload app files if this is Rails
+ # thanks resque
+ task :preload => :setup do
+ if defined?(Rails) && Rails.respond_to?(:application)
+ # Rails 3
+ Rails.application.eager_load!
+ elsif defined?(Rails::Initializer)
+ # Rails 2.3
+ $rails_rake_task = false
+ Rails::Initializer.run :load_application_classes
+ end
+ end
+end
View
2  lib/tasks/say_when.rake
@@ -0,0 +1,2 @@
+$LOAD_PATH.unshift File.dirname(__FILE__) + '/../../lib'
+require 'say_when/tasks'
View
1  say_when.gemspec
@@ -17,6 +17,7 @@ Gem::Specification.new do |s|
s.add_development_dependency "activesupport", '~> 2.3.14'
s.add_development_dependency "activerecord", '~> 2.3.14'
+ s.add_development_dependency "mongoid", '~> 1.9.5'
s.add_development_dependency 'rspec', "~> 1.3"
s.add_development_dependency 'sqlite3'
s.add_development_dependency 'rake'
View
BIN  spec/db/test.db
Binary file not shown
View
2  spec/mongoid_spec_helper.rb
@@ -4,4 +4,4 @@
config.master = Mongo::Connection.new.db("say_when_test")
end
-Mongoid.logger = Logger.new($stdout)
+# Mongoid.logger = Logger.new($stdout)
View
12 spec/say_when/scheduler_spec.rb
@@ -63,21 +63,11 @@
puts 'started'
sleep(0.1)
@scheduler.running.should == true
- @scheduler.scheduler_thread.should be_alive
- @scheduler.processor_thread.should be_alive
puts 'stop'
@scheduler.stop
puts 'wait for it'
- wait = 0
- while(scheduler_thread.alive? && wait < 10)
- puts 'waiting...'
- wait += 1
- sleep(1)
- end
- puts 'done'
- @scheduler.scheduler_thread.should_not be_alive
- @scheduler.processor_thread.should_not be_alive
+ @scheduler.running.should == false
end
end
View
2  spec/say_when/storage/memory/job_spec.rb
@@ -1,5 +1,5 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
-require File.dirname(__FILE__) + '/../../../../lib/say_when/store/memory/job'
+require File.dirname(__FILE__) + '/../../../../lib/say_when/storage/memory/job'
describe SayWhen::Store::Memory::Job do
View
106 spec/say_when/storage/memory/trigger_spec.rb
@@ -1,54 +1,54 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
-require File.dirname(__FILE__) + '/../../../../lib/say_when/store/memory/trigger'
-
-describe SayWhen::Store::Memory::Trigger do
-
- before(:each) do
- @valid_attributes = {
- :expression => '0 0 12 ? * * *',
- :time_zone => 'Pacific Time (US & Canada)'
- }
- end
-
- it "can be instantiated" do
- t = SayWhen::Store::Memory::Trigger.new(@valid_attributes)
- t.should_not be_nil
- end
-
- it "sets a cron_expression" do
- t = SayWhen::Store::Memory::Trigger.new(@valid_attributes)
- t.cron_expression.should_not be_nil
- t.cron_expression.expression.should == '0 0 12 ? * * *'
- t.cron_expression.time_zone.should == 'Pacific Time (US & Canada)'
- end
-
- it "has a waiting state on instantiate" do
- t = SayWhen::Store::Memory::Trigger.new(@valid_attributes)
- t.status.should == SayWhen::BaseTrigger::STATE_WAITING
- end
-
- it "has a next fire at set on instantiate" do
- ce = SayWhen::CronExpression.new(@valid_attributes[:expression], @valid_attributes[:time_zone])
- t = SayWhen::Store::Memory::Trigger.new(@valid_attributes)
- t.status.should == SayWhen::BaseTrigger::STATE_WAITING
- t.next_fire_at.should == ce.next_fire_at
- end
-
- it "can be fired" do
- ce = SayWhen::CronExpression.new(@valid_attributes[:expression], @valid_attributes[:time_zone])
- t = SayWhen::Store::Memory::Trigger.new(@valid_attributes)
- nfa = ce.last_fire_at(1.second.ago)
- lfa = ce.last_fire_at(nfa - 1.second)
- t.next_fire_at = nfa
- t.last_fire_at = lfa
-
- now = Time.now
- Time.stub!(:now).and_return(now)
-
- t.fired
- t.next_fire_at.should == ce.next_fire_at(now)
- t.last_fire_at.should == now
- t.status.should == SayWhen::BaseTrigger::STATE_WAITING
- end
-
-end
+# require File.dirname(__FILE__) + '/../../../../lib/say_when/store/memory/trigger'
+
+# describe SayWhen::Store::Memory::Trigger do
+
+# before(:each) do
+# @valid_attributes = {
+# :expression => '0 0 12 ? * * *',
+# :time_zone => 'Pacific Time (US & Canada)'
+# }
+# end
+
+# it "can be instantiated" do
+# t = SayWhen::Store::Memory::Trigger.new(@valid_attributes)
+# t.should_not be_nil
+# end
+
+# it "sets a cron_expression" do
+# t = SayWhen::Store::Memory::Trigger.new(@valid_attributes)
+# t.cron_expression.should_not be_nil
+# t.cron_expression.expression.should == '0 0 12 ? * * *'
+# t.cron_expression.time_zone.should == 'Pacific Time (US & Canada)'
+# end
+
+# it "has a waiting state on instantiate" do
+# t = SayWhen::Store::Memory::Trigger.new(@valid_attributes)
+# t.status.should == SayWhen::BaseTrigger::STATE_WAITING
+# end
+
+# it "has a next fire at set on instantiate" do
+# ce = SayWhen::CronExpression.new(@valid_attributes[:expression], @valid_attributes[:time_zone])
+# t = SayWhen::Store::Memory::Trigger.new(@valid_attributes)
+# t.status.should == SayWhen::BaseTrigger::STATE_WAITING
+# t.next_fire_at.should == ce.next_fire_at
+# end
+
+# it "can be fired" do
+# ce = SayWhen::CronExpression.new(@valid_attributes[:expression], @valid_attributes[:time_zone])
+# t = SayWhen::Store::Memory::Trigger.new(@valid_attributes)
+# nfa = ce.last_fire_at(1.second.ago)
+# lfa = ce.last_fire_at(nfa - 1.second)
+# t.next_fire_at = nfa
+# t.last_fire_at = lfa
+
+# now = Time.now
+# Time.stub!(:now).and_return(now)
+
+# t.fired
+# t.next_fire_at.should == ce.next_fire_at(now)
+# t.last_fire_at.should == now
+# t.status.should == SayWhen::BaseTrigger::STATE_WAITING
+# end
+
+# end
View
110 spec/say_when/storage/mongoid/trigger_spec.rb
@@ -1,57 +1,57 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
require File.dirname(__FILE__) + '/../../../mongoid_spec_helper'
-require File.dirname(__FILE__) + '/../../../../lib/say_when/store/mongoid/trigger'
-
-describe SayWhen::Store::Mongoid::Trigger do
-
- before(:each) do
- SayWhen::Store::Mongoid::Trigger.delete_all
- @valid_attributes = {
- :expression => '0 0 12 ? * * *',
- :time_zone => 'Pacific Time (US & Canada)'
- }
- end
-
- it "can be created using new and save" do
- t = SayWhen::Store::Mongoid::Trigger.new(@valid_attributes)
- t.should be_valid
- t.save
- end
-
- # it "sets a cron_expression" do
- # t = SayWhen::Store::Mongoid::Trigger.create(@valid_attributes)
- # t.cron_expression.should_not be_nil
- # t.cron_expression.expression.should == '0 0 12 ? * * *'
- # t.cron_expression.time_zone.should == 'Pacific Time (US & Canada)'
- # end
-
- # it "has a waiting state on create" do
- # t = SayWhen::Store::Mongoid::Trigger.create(@valid_attributes)
- # t.status.should == SayWhen::BaseTrigger::STATE_WAITING
- # end
-
- # it "has a next fire at set on create" do
- # ce = SayWhen::CronExpression.new(@valid_attributes[:expression], @valid_attributes[:time_zone])
- # t = SayWhen::Store::Mongoid::Trigger.create(@valid_attributes)
- # t.status.should == SayWhen::BaseTrigger::STATE_WAITING
- # t.next_fire_at.should == ce.next_fire_at(t.created_at)
- # end
-
- # it "can be fired" do
- # ce = SayWhen::CronExpression.new(@valid_attributes[:expression], @valid_attributes[:time_zone])
- # t = SayWhen::Store::Mongoid::Trigger.create(@valid_attributes)
- # nfa = ce.last_fire_at(t.created_at - 1.second)
- # lfa = ce.last_fire_at(nfa - 1.second)
- # t.next_fire_at = nfa
- # t.last_fire_at = lfa
-
- # now = Time.now
- # Time.stub!(:now).and_return(now)
-
- # t.fired
- # t.next_fire_at.should == ce.next_fire_at(now)
- # t.last_fire_at.should == now
- # t.status.should == SayWhen::BaseTrigger::STATE_WAITING
- # end
-
-end
+# require File.dirname(__FILE__) + '/../../../../lib/say_when/store/mongoid/trigger'
+
+# describe SayWhen::Store::Mongoid::Trigger do
+
+# before(:each) do
+# SayWhen::Store::Mongoid::Trigger.delete_all
+# @valid_attributes = {
+# :expression => '0 0 12 ? * * *',
+# :time_zone => 'Pacific Time (US & Canada)'
+# }
+# end
+
+# it "can be created using new and save" do
+# t = SayWhen::Store::Mongoid::Trigger.new(@valid_attributes)
+# t.should be_valid
+# t.save
+# end
+
+# it "sets a cron_expression" do
+# t = SayWhen::Store::Mongoid::Trigger.create(@valid_attributes)
+# t.cron_expression.should_not be_nil
+# t.cron_expression.expression.should == '0 0 12 ? * * *'
+# t.cron_expression.time_zone.should == 'Pacific Time (US & Canada)'
+# end
+
+# it "has a waiting state on create" do
+# t = SayWhen::Store::Mongoid::Trigger.create(@valid_attributes)
+# t.status.should == SayWhen::BaseTrigger::STATE_WAITING
+# end
+
+# it "has a next fire at set on create" do
+# ce = SayWhen::CronExpression.new(@valid_attributes[:expression], @valid_attributes[:time_zone])
+# t = SayWhen::Store::Mongoid::Trigger.create(@valid_attributes)
+# t.status.should == SayWhen::BaseTrigger::STATE_WAITING
+# t.next_fire_at.should == ce.next_fire_at(t.created_at)
+# end
+
+# it "can be fired" do
+# ce = SayWhen::CronExpression.new(@valid_attributes[:expression], @valid_attributes[:time_zone])
+# t = SayWhen::Store::Mongoid::Trigger.create(@valid_attributes)
+# nfa = ce.last_fire_at(t.created_at - 1.second)
+# lfa = ce.last_fire_at(nfa - 1.second)
+# t.next_fire_at = nfa
+# t.last_fire_at = lfa
+
+# now = Time.now
+# Time.stub!(:now).and_return(now)
+
+# t.fired
+# t.next_fire_at.should == ce.next_fire_at(now)
+# t.last_fire_at.should == now
+# t.status.should == SayWhen::BaseTrigger::STATE_WAITING
+# end
+
+# end

No commit comments for this range

Something went wrong with that request. Please try again.