say_when 0.2.6 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +2 -1
- data/.travis.yml +4 -0
- data/Gemfile +8 -0
- data/Rakefile +9 -1
- data/lib/generators/say_when/migration/templates/migration.rb +5 -3
- data/lib/say_when/scheduler.rb +78 -36
- data/lib/say_when/storage/active_record/job.rb +14 -9
- data/lib/say_when/storage/memory/job.rb +37 -4
- data/lib/say_when/tasks.rb +1 -14
- data/lib/say_when/version.rb +1 -1
- data/say_when.gemspec +2 -4
- data/spec/active_record_spec_helper.rb +0 -2
- data/spec/db/schema.rb +4 -2
- data/spec/say_when/cron_expression_spec.rb +1 -1
- data/spec/say_when/processor/active_messaging_spec.rb +3 -4
- data/spec/say_when/scheduler_spec.rb +59 -9
- data/spec/say_when/storage/active_record/job_spec.rb +19 -6
- data/spec/say_when/storage/memory/job_spec.rb +16 -2
- data/spec/say_when/storage/memory/trigger_spec.rb +1 -1
- data/spec/say_when/triggers/once_strategy_spec.rb +2 -2
- data/spec/spec_helper.rb +7 -0
- metadata +86 -136
- data/lib/say_when/storage/mongoid/job.rb +0 -15
- data/spec/db/test.db +0 -0
- data/spec/mongoid_spec_helper.rb +0 -7
- data/spec/say_when/storage/mongoid/trigger_spec.rb +0 -57
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 39f0c8806fd8c11484d52818cb71a42e71e60b62c8cf19af670f8db7e06d3c17
|
4
|
+
data.tar.gz: 2e22ba68d95307e93f019381399ed46b257d5170dc45f5d99fb06d8cb7832b48
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9c11c37dea5355c17ac03ebfd589d769cd5526d11d34864b7890185e89aae593dfa92e58616dfa0305686c8885ac6eaaa65f955bf03d479c49151abe2385286a
|
7
|
+
data.tar.gz: 86790a64921d0f8cbbb92a11968bf036a76180c3d9fc40acec3cfd19a5e00e21c5a81f5e7029e3c23f0efbc8febc7bb8c2237f065b83e2788ac20f835e464c83
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/Gemfile
CHANGED
@@ -2,3 +2,11 @@ source "http://rubygems.org"
|
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in say_when.gemspec
|
4
4
|
gemspec
|
5
|
+
|
6
|
+
gem "rspec", "=1.3.2", git: 'https://github.com/makandra/rspec.git', branch: '1-3-lts'
|
7
|
+
|
8
|
+
git 'https://github.com/makandra/rails.git', :branch => '2-3-lts' do
|
9
|
+
gem 'rails', '~>2.3.18'
|
10
|
+
gem 'activesupport', :require => false
|
11
|
+
gem 'railslts-version', :require => false
|
12
|
+
end
|
data/Rakefile
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class CreateSayWhenTables < ActiveRecord::Migration
|
2
|
-
|
2
|
+
|
3
3
|
def self.up
|
4
4
|
|
5
5
|
create_table :say_when_jobs, :force => true do |t|
|
@@ -35,11 +35,13 @@ class CreateSayWhenTables < ActiveRecord::Migration
|
|
35
35
|
t.datetime :start_at
|
36
36
|
t.datetime :end_at
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
add_index :say_when_jobs, :status
|
40
40
|
add_index :say_when_jobs, :next_fire_at
|
41
|
+
add_index :say_when_jobs, [:next_fire_at, :status]
|
42
|
+
add_index :say_when_jobs, [:last_fire_at, :status]
|
41
43
|
end
|
42
|
-
|
44
|
+
|
43
45
|
def self.down
|
44
46
|
drop_table :say_when_job_executions
|
45
47
|
drop_table :say_when_jobs
|
data/lib/say_when/scheduler.rb
CHANGED
@@ -7,8 +7,8 @@ module SayWhen
|
|
7
7
|
|
8
8
|
@@scheduler = nil
|
9
9
|
@@lock = nil
|
10
|
-
|
11
|
-
attr_accessor :storage_strategy, :processor_class, :tick_length
|
10
|
+
|
11
|
+
attr_accessor :storage_strategy, :processor_class, :tick_length, :reset_acquired_length, :reset_next_at
|
12
12
|
|
13
13
|
attr_accessor :running
|
14
14
|
|
@@ -40,11 +40,11 @@ module SayWhen
|
|
40
40
|
def start
|
41
41
|
self.scheduler.start
|
42
42
|
end
|
43
|
-
|
44
43
|
end
|
45
44
|
|
46
45
|
def initialize
|
47
46
|
self.tick_length = 1
|
47
|
+
self.reset_acquired_length = 3600
|
48
48
|
end
|
49
49
|
|
50
50
|
def processor
|
@@ -54,7 +54,7 @@ module SayWhen
|
|
54
54
|
end
|
55
55
|
@processor
|
56
56
|
end
|
57
|
-
|
57
|
+
|
58
58
|
def start
|
59
59
|
logger.info "SayWhen::Scheduler starting"
|
60
60
|
|
@@ -63,47 +63,90 @@ module SayWhen
|
|
63
63
|
trap("TERM", "EXIT")
|
64
64
|
|
65
65
|
begin
|
66
|
-
|
67
66
|
self.running = true
|
68
67
|
|
69
68
|
logger.info "SayWhen::Scheduler running"
|
70
|
-
job = nil
|
71
69
|
while running
|
72
|
-
|
73
|
-
time_now = Time.now
|
74
|
-
logger.debug "SayWhen:: Looking for job that should be ready to fire before #{time_now}"
|
75
|
-
job = job_class.acquire_next(time_now)
|
76
|
-
if job.nil?
|
77
|
-
logger.debug "SayWhen:: no jobs to acquire, sleep"
|
78
|
-
sleep(tick_length)
|
79
|
-
else
|
80
|
-
logger.debug "SayWhen:: got a job: #{job.inspect}"
|
81
|
-
# delegate processing the trigger to the processor
|
82
|
-
self.processor.process(job)
|
83
|
-
logger.debug "SayWhen:: job processed"
|
84
|
-
|
85
|
-
# this should update next fire at, and put back in list of scheduled jobs
|
86
|
-
job.fired(time_now)
|
87
|
-
logger.debug "SayWhen:: job fired complete"
|
88
|
-
end
|
89
|
-
rescue Interrupt
|
90
|
-
job_msg = job && " job:'#{job.inspect}'"
|
91
|
-
logger.error "\nSayWhen:: Interrupt! #{job_msg}"
|
92
|
-
exit
|
93
|
-
rescue StandardError=>ex
|
94
|
-
job_msg = job && " job:'#{job.inspect}'"
|
95
|
-
logger.error "SayWhen:: Failure to process#{job_msg}: #{ex.message}\n\t#{ex.backtrace.join("\t\n")}"
|
96
|
-
job.release if job
|
97
|
-
rescue Exception=>ex
|
98
|
-
logger.error "SayWhen:: Exception in process#{job_msg}: #{ex.message}\n\t#{ex.backtrace.join("\t\n")}"
|
99
|
-
exit
|
100
|
-
end
|
70
|
+
process_jobs
|
101
71
|
end
|
72
|
+
rescue Exception => ex
|
73
|
+
logger.error "SayWhen::Scheduler stopping, error: #{ex.class.name}: #{ex.message}"
|
74
|
+
exit
|
102
75
|
end
|
103
76
|
|
104
77
|
logger.info "SayWhen::Scheduler stopped"
|
105
78
|
end
|
106
79
|
|
80
|
+
def process_waiting_jobs(max_jobs=1000)
|
81
|
+
jobs_processed = 0
|
82
|
+
while(jobs_processed < max_jobs)
|
83
|
+
if job = process_jobs
|
84
|
+
jobs_processed += 1
|
85
|
+
else
|
86
|
+
break
|
87
|
+
end
|
88
|
+
end
|
89
|
+
return jobs_processed
|
90
|
+
end
|
91
|
+
|
92
|
+
def process_jobs
|
93
|
+
job = nil
|
94
|
+
time_now = Time.now
|
95
|
+
self.reset_next_at ||= Time.now
|
96
|
+
|
97
|
+
if reset_acquired_length > 0 && reset_next_at <= time_now
|
98
|
+
self.reset_next_at = time_now + reset_acquired_length
|
99
|
+
logger.debug "SayWhen:: reset acquired at #{time_now}, try again at #{reset_next_at}"
|
100
|
+
job_class.reset_acquired(reset_acquired_length)
|
101
|
+
end
|
102
|
+
|
103
|
+
begin
|
104
|
+
logger.debug "SayWhen:: Looking for job that should be ready to fire before #{time_now}"
|
105
|
+
job = job_class.acquire_next(time_now)
|
106
|
+
rescue StandardError => ex
|
107
|
+
job_error("Failure to acquire job", job, ex)
|
108
|
+
job = nil
|
109
|
+
end
|
110
|
+
|
111
|
+
if job.nil?
|
112
|
+
logger.debug "SayWhen:: no jobs to acquire, sleep"
|
113
|
+
sleep(tick_length)
|
114
|
+
return job
|
115
|
+
end
|
116
|
+
|
117
|
+
begin
|
118
|
+
logger.debug "SayWhen:: got a job: #{job.inspect}"
|
119
|
+
# delegate processing the trigger to the processor
|
120
|
+
self.processor.process(job)
|
121
|
+
logger.debug "SayWhen:: job processed"
|
122
|
+
|
123
|
+
# if successful, update next fire at, put back to waiting / ended
|
124
|
+
job.fired(time_now)
|
125
|
+
logger.debug "SayWhen:: job fired complete"
|
126
|
+
rescue StandardError => ex
|
127
|
+
job_error("Failure to process", job, ex)
|
128
|
+
end
|
129
|
+
|
130
|
+
return job
|
131
|
+
|
132
|
+
rescue StandardError => ex
|
133
|
+
job_error("Error!", job, ex)
|
134
|
+
sleep(tick_length)
|
135
|
+
return job
|
136
|
+
rescue Interrupt => ex
|
137
|
+
job_error("Interrupt!", job, ex)
|
138
|
+
raise ex
|
139
|
+
rescue Exception => ex
|
140
|
+
job_error("Exception!", job, ex)
|
141
|
+
raise ex
|
142
|
+
end
|
143
|
+
|
144
|
+
def job_error(msg, job, ex)
|
145
|
+
job_msg = job && " job:'#{job.inspect}'"
|
146
|
+
logger.error "SayWhen::Scheduler #{msg}#{job_msg}: #{ex.message}\n\t#{ex.backtrace.join("\t\n")}"
|
147
|
+
job.release if job
|
148
|
+
end
|
149
|
+
|
107
150
|
def stop
|
108
151
|
logger.info "SayWhen::Scheduler stopping..."
|
109
152
|
self.running = false
|
@@ -127,6 +170,5 @@ module SayWhen
|
|
127
170
|
def logger
|
128
171
|
SayWhen::logger
|
129
172
|
end
|
130
|
-
|
131
173
|
end
|
132
174
|
end
|
@@ -8,18 +8,23 @@ module SayWhen
|
|
8
8
|
module ActiveRecord
|
9
9
|
|
10
10
|
class Job < ::ActiveRecord::Base
|
11
|
-
|
12
11
|
include SayWhen::BaseJob
|
13
|
-
|
14
12
|
self.table_name = "say_when_jobs"
|
15
|
-
|
16
|
-
|
17
13
|
serialize :trigger_options
|
18
14
|
serialize :data
|
19
15
|
belongs_to :scheduled, :polymorphic => true
|
20
16
|
has_many :job_executions, :class_name=>'SayWhen::Storage::ActiveRecord::JobExecution'
|
21
17
|
before_create :set_defaults
|
22
18
|
|
19
|
+
def self.reset_acquired(older_than_seconds)
|
20
|
+
return unless older_than_seconds.to_i > 0
|
21
|
+
older_than = (Time.now - older_than_seconds.to_i)
|
22
|
+
update_all(
|
23
|
+
"status = '#{STATE_WAITING}'",
|
24
|
+
["status = ? and updated_at < ?", STATE_ACQUIRED, older_than]
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
23
28
|
def self.acquire_next(no_later_than)
|
24
29
|
@next_job = nil
|
25
30
|
hide_logging do
|
@@ -28,13 +33,13 @@ module SayWhen
|
|
28
33
|
@next_job = find(:first,
|
29
34
|
:lock => true,
|
30
35
|
:order => 'next_fire_at ASC',
|
31
|
-
:conditions => ['status = ? and ? >= next_fire_at',
|
36
|
+
:conditions => ['status = ? and ? >= next_fire_at',
|
32
37
|
STATE_WAITING,
|
33
|
-
no_later_than
|
38
|
+
no_later_than])
|
34
39
|
|
35
40
|
# set status to acquired to take it out of rotation
|
36
41
|
@next_job.update_attribute(:status, STATE_ACQUIRED) unless @next_job.nil?
|
37
|
-
|
42
|
+
|
38
43
|
end
|
39
44
|
end
|
40
45
|
@next_job
|
@@ -94,9 +99,9 @@ module SayWhen
|
|
94
99
|
::ActiveRecord::Base.logger = old_logger
|
95
100
|
end
|
96
101
|
end
|
97
|
-
|
102
|
+
|
98
103
|
end
|
99
|
-
|
104
|
+
|
100
105
|
end
|
101
106
|
end
|
102
107
|
end
|
@@ -17,21 +17,45 @@ module SayWhen
|
|
17
17
|
has_properties :trigger_strategy, :trigger_options, :last_fire_at, :next_fire_at
|
18
18
|
has_properties :job_class, :job_method, :data
|
19
19
|
has_properties :scheduled
|
20
|
+
has_properties :updated_at
|
21
|
+
|
22
|
+
def self.class_lock
|
23
|
+
@@_lock ||= Mutex.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def self._reset
|
27
|
+
@@jobs = SortedSet.new
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.reset_acquired(older_than_seconds)
|
31
|
+
return unless older_than_seconds.to_i > 0
|
32
|
+
older_than = (Time.now - older_than_seconds.to_i)
|
33
|
+
self.class_lock.synchronize {
|
34
|
+
jobs.select do |j|
|
35
|
+
j.status == STATE_ACQUIRED && j.updated_at < older_than
|
36
|
+
end.each{ |j| j.status = STATE_WAITING }
|
37
|
+
}
|
38
|
+
end
|
20
39
|
|
21
40
|
def self.acquire_next(no_later_than)
|
22
|
-
self.
|
23
|
-
|
41
|
+
self.class_lock.synchronize {
|
42
|
+
|
24
43
|
next_job = jobs.detect(nil) do |j|
|
25
44
|
(j.status == STATE_WAITING) && (j.next_fire_at.to_i <= no_later_than.to_i)
|
26
45
|
end
|
27
46
|
|
28
|
-
|
47
|
+
if next_job
|
48
|
+
next_job.status = STATE_ACQUIRED
|
49
|
+
next_job.updated_at = Time.now
|
50
|
+
end
|
51
|
+
|
29
52
|
next_job
|
30
|
-
}
|
53
|
+
}
|
31
54
|
end
|
32
55
|
|
33
56
|
def initialize(options={})
|
34
57
|
super
|
58
|
+
self.updated_at = Time.now
|
35
59
|
self.status = STATE_WAITING unless self.status
|
36
60
|
self.next_fire_at = trigger.next_fire_at
|
37
61
|
self.class.jobs << self
|
@@ -41,6 +65,15 @@ module SayWhen
|
|
41
65
|
self.next_fire_at.to_i <=> job.next_fire_at.to_i
|
42
66
|
end
|
43
67
|
|
68
|
+
def fired(fired_at=Time.now)
|
69
|
+
super
|
70
|
+
self.updated_at = Time.now
|
71
|
+
end
|
72
|
+
|
73
|
+
def release
|
74
|
+
super
|
75
|
+
self.updated_at = Time.now
|
76
|
+
end
|
44
77
|
end
|
45
78
|
|
46
79
|
end
|
data/lib/say_when/tasks.rb
CHANGED
@@ -6,17 +6,4 @@ namespace :say_when do
|
|
6
6
|
SayWhen::Scheduler.start
|
7
7
|
end
|
8
8
|
|
9
|
-
|
10
|
-
# # thanks resque
|
11
|
-
# task :preload => :setup do
|
12
|
-
# if defined?(Rails) && Rails.respond_to?(:application)
|
13
|
-
# # Rails 3
|
14
|
-
# Rails.application.eager_load!
|
15
|
-
# elsif defined?(Rails::Initializer)
|
16
|
-
# # Rails 2.3
|
17
|
-
# $rails_rake_task = false
|
18
|
-
# Rails::Initializer.run :load_application_classes
|
19
|
-
# end
|
20
|
-
# end
|
21
|
-
|
22
|
-
end
|
9
|
+
end
|
data/lib/say_when/version.rb
CHANGED
data/say_when.gemspec
CHANGED
@@ -18,9 +18,7 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.add_development_dependency "activemessaging", '~> 0.9.0'
|
19
19
|
s.add_development_dependency "activesupport", '~> 2.3.14'
|
20
20
|
s.add_development_dependency "activerecord", '~> 2.3.14'
|
21
|
-
s.add_development_dependency
|
22
|
-
s.add_development_dependency '
|
21
|
+
s.add_development_dependency 'rspec', '~> 1.3'
|
22
|
+
s.add_development_dependency 'rake', '~> 10.5.0'
|
23
23
|
s.add_development_dependency 'sqlite3'
|
24
|
-
s.add_development_dependency 'rake'
|
25
|
-
|
26
24
|
end
|
data/spec/db/schema.rb
CHANGED
@@ -28,9 +28,11 @@ ActiveRecord::Schema.define(:version => 0) do
|
|
28
28
|
t.datetime :start_at
|
29
29
|
t.datetime :end_at
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
add_index :say_when_jobs, :status
|
33
33
|
add_index :say_when_jobs, :next_fire_at
|
34
|
+
add_index :say_when_jobs, [:next_fire_at, :status]
|
35
|
+
add_index :say_when_jobs, [:last_fire_at, :status]
|
34
36
|
|
35
37
|
|
36
|
-
end
|
38
|
+
end
|
@@ -1,7 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
require File.dirname(__FILE__) + '/../../../lib/say_when/storage/active_record/job'
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
require_relative '../../../lib/say_when/processor/active_messaging'
|
3
|
+
require_relative '../../../lib/say_when/storage/active_record/job'
|
5
4
|
|
6
5
|
def destination(destination_name)
|
7
6
|
d = ActiveMessaging::Gateway.find_destination(destination_name).value
|
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
require_relative '../active_record_spec_helper'
|
3
3
|
|
4
4
|
describe SayWhen::Scheduler do
|
5
5
|
|
@@ -25,6 +25,7 @@ describe SayWhen::Scheduler do
|
|
25
25
|
scheduler.storage_strategy = :active_record
|
26
26
|
scheduler.processor_class = SayWhen::Test::TestProcessor
|
27
27
|
end
|
28
|
+
SayWhen::Storage::ActiveRecord::Job.delete_all
|
28
29
|
|
29
30
|
job = SayWhen::Scheduler.schedule(
|
30
31
|
:trigger_strategy => 'once',
|
@@ -35,6 +36,58 @@ describe SayWhen::Scheduler do
|
|
35
36
|
job.should_not be_nil
|
36
37
|
end
|
37
38
|
|
39
|
+
it "can process jobs when there are no jobs" do
|
40
|
+
SayWhen::Storage::ActiveRecord::Job.delete_all
|
41
|
+
|
42
|
+
SayWhen::Scheduler.configure do |scheduler|
|
43
|
+
scheduler.storage_strategy = :active_record
|
44
|
+
scheduler.processor_class = SayWhen::Test::TestProcessor
|
45
|
+
end
|
46
|
+
job = SayWhen::Scheduler.scheduler.process_jobs
|
47
|
+
job.should be_nil
|
48
|
+
end
|
49
|
+
|
50
|
+
it "can process jobs when there is a job" do
|
51
|
+
SayWhen::Storage::ActiveRecord::Job.delete_all
|
52
|
+
|
53
|
+
SayWhen::Scheduler.configure do |scheduler|
|
54
|
+
scheduler.storage_strategy = :active_record
|
55
|
+
scheduler.processor_class = SayWhen::Test::TestProcessor
|
56
|
+
end
|
57
|
+
|
58
|
+
job = SayWhen::Scheduler.schedule(
|
59
|
+
:trigger_strategy => 'once',
|
60
|
+
:trigger_options => {:at => 1.second.since},
|
61
|
+
:job_class => 'SayWhen::Test::TestTask',
|
62
|
+
:job_method => 'execute'
|
63
|
+
)
|
64
|
+
sleep(1)
|
65
|
+
|
66
|
+
processed_job = SayWhen::Scheduler.scheduler.process_jobs
|
67
|
+
processed_job.should_not be_nil
|
68
|
+
processed_job.should == job
|
69
|
+
end
|
70
|
+
|
71
|
+
it "can process multiple waiting jobs" do
|
72
|
+
SayWhen::Scheduler.configure do |scheduler|
|
73
|
+
scheduler.storage_strategy = :active_record
|
74
|
+
scheduler.processor_class = SayWhen::Test::TestProcessor
|
75
|
+
end
|
76
|
+
SayWhen::Storage::ActiveRecord::Job.delete_all
|
77
|
+
|
78
|
+
opts = {
|
79
|
+
:trigger_strategy => 'once',
|
80
|
+
:trigger_options => {:at => 1.seconds.since},
|
81
|
+
:job_class => 'SayWhen::Test::TestTask',
|
82
|
+
:job_method => 'execute'
|
83
|
+
}
|
84
|
+
|
85
|
+
10.times{ SayWhen::Scheduler.schedule(opts) }
|
86
|
+
sleep(1)
|
87
|
+
|
88
|
+
job_count = SayWhen::Scheduler.scheduler.process_waiting_jobs(100)
|
89
|
+
job_count.should == 10
|
90
|
+
end
|
38
91
|
end
|
39
92
|
|
40
93
|
describe "instance methods" do
|
@@ -58,19 +111,16 @@ describe SayWhen::Scheduler do
|
|
58
111
|
it "should start the scheduler running and stop it" do
|
59
112
|
@scheduler.running.should be_false
|
60
113
|
|
61
|
-
puts 'starting'
|
114
|
+
# puts 'starting'
|
62
115
|
scheduler_thread = Thread.start{@scheduler.start}
|
63
|
-
puts 'started'
|
116
|
+
# puts 'started'
|
64
117
|
sleep(0.1)
|
65
118
|
@scheduler.running.should == true
|
66
119
|
|
67
|
-
puts 'stop'
|
120
|
+
# puts 'stop'
|
68
121
|
@scheduler.stop
|
69
|
-
puts 'wait for it'
|
122
|
+
# puts 'wait for it'
|
70
123
|
@scheduler.running.should == false
|
71
124
|
end
|
72
|
-
|
73
125
|
end
|
74
|
-
|
75
|
-
|
76
126
|
end
|
@@ -1,10 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require_relative '../../../spec_helper'
|
2
|
+
require_relative '../../../active_record_spec_helper'
|
3
|
+
require_relative '../../../../lib/say_when/storage/active_record/job'
|
4
4
|
|
5
5
|
describe SayWhen::Storage::ActiveRecord::Job do
|
6
6
|
|
7
7
|
before(:each) do
|
8
|
+
SayWhen::Storage::ActiveRecord::Job.delete_all
|
9
|
+
|
8
10
|
@valid_attributes = {
|
9
11
|
:trigger_strategy => :cron,
|
10
12
|
:trigger_options => {:expression => '0 0 12 ? * * *', :time_zone => 'Pacific Time (US & Canada)'},
|
@@ -48,18 +50,30 @@ describe SayWhen::Storage::ActiveRecord::Job do
|
|
48
50
|
j.next_fire_at.should == ce.next_fire_at
|
49
51
|
end
|
50
52
|
|
53
|
+
it "resets acquired jobs" do
|
54
|
+
old = 2.hours.ago
|
55
|
+
j = SayWhen::Storage::ActiveRecord::Job.create!(@valid_attributes.merge({
|
56
|
+
:status => 'acquired', :updated_at => old, :created_at => old
|
57
|
+
}))
|
58
|
+
|
59
|
+
SayWhen::Storage::ActiveRecord::Job.reset_acquired(3600)
|
60
|
+
|
61
|
+
j.reload
|
62
|
+
j.status.should == 'waiting'
|
63
|
+
end
|
64
|
+
|
51
65
|
it "can find the next job" do
|
52
66
|
j2_opts = {
|
53
67
|
:trigger_strategy => :cron,
|
54
68
|
:trigger_options => {:expression => '0 0 10 ? * * *', :time_zone => 'Pacific Time (US & Canada)'},
|
55
|
-
:data => {:foo=>'
|
69
|
+
:data => {:foo=>'can find the next job - j2', :result=>2},
|
56
70
|
:job_class => 'SayWhen::Test::TestTask',
|
57
71
|
:job_method => 'execute'
|
58
72
|
}
|
59
73
|
|
60
74
|
j1 = SayWhen::Storage::ActiveRecord::Job.create(@valid_attributes)
|
61
75
|
j2 = SayWhen::Storage::ActiveRecord::Job.create(j2_opts)
|
62
|
-
next_job = SayWhen::Storage::ActiveRecord::Job.acquire_next(
|
76
|
+
next_job = SayWhen::Storage::ActiveRecord::Job.acquire_next(25.hours.since)
|
63
77
|
next_job.should == j2
|
64
78
|
end
|
65
79
|
|
@@ -80,5 +94,4 @@ describe SayWhen::Storage::ActiveRecord::Job do
|
|
80
94
|
j.last_fire_at.should == now
|
81
95
|
j.status.should == SayWhen::BaseJob::STATE_WAITING
|
82
96
|
end
|
83
|
-
|
84
97
|
end
|
@@ -1,9 +1,10 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative '../../../spec_helper'
|
2
|
+
require_relative '../../../../lib/say_when/storage/memory/job'
|
3
3
|
|
4
4
|
describe SayWhen::Store::Memory::Job do
|
5
5
|
|
6
6
|
before(:each) do
|
7
|
+
SayWhen::Store::Memory::Job._reset
|
7
8
|
@valid_attributes = {
|
8
9
|
:name => 'Memory::Job::Test',
|
9
10
|
:group => 'Test',
|
@@ -28,4 +29,17 @@ describe SayWhen::Store::Memory::Job do
|
|
28
29
|
j.execute.should == 1
|
29
30
|
end
|
30
31
|
|
32
|
+
it "can reset acquired jobs" do
|
33
|
+
j = SayWhen::Store::Memory::Job.new(@valid_attributes)
|
34
|
+
j.status = 'acquired'
|
35
|
+
j.updated_at = 2.hours.ago
|
36
|
+
SayWhen::Store::Memory::Job.reset_acquired(3600)
|
37
|
+
j.status.should == 'waiting'
|
38
|
+
end
|
39
|
+
|
40
|
+
it "can find the next job" do
|
41
|
+
j = SayWhen::Store::Memory::Job.new(@valid_attributes)
|
42
|
+
next_job = SayWhen::Store::Memory::Job.acquire_next(1.day.since)
|
43
|
+
next_job.should == j
|
44
|
+
end
|
31
45
|
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
require_relative '../../../lib/say_when/triggers/once_strategy'
|
3
3
|
|
4
4
|
describe SayWhen::Triggers::OnceStrategy do
|
5
5
|
|
data/spec/spec_helper.rb
CHANGED
@@ -3,6 +3,7 @@ ENV['RAILS_ENV']='test'
|
|
3
3
|
require "rubygems"
|
4
4
|
require 'bundler/setup'
|
5
5
|
require 'active_support'
|
6
|
+
require 'active_record'
|
6
7
|
|
7
8
|
require 'spec'
|
8
9
|
require 'spec/autorun'
|
@@ -10,8 +11,14 @@ require 'spec/autorun'
|
|
10
11
|
$: << (File.dirname(__FILE__) + "/../lib")
|
11
12
|
require "say_when"
|
12
13
|
|
14
|
+
logger = Logger.new(STDOUT)
|
15
|
+
logger.level = Logger::ERROR
|
16
|
+
SayWhen.logger = logger
|
17
|
+
::ActiveRecord::Base.logger = logger
|
18
|
+
|
13
19
|
Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}
|
14
20
|
|
21
|
+
|
15
22
|
Spec::Runner.configure do |config|
|
16
23
|
config.mock_with :rspec
|
17
24
|
end
|
metadata
CHANGED
@@ -1,140 +1,108 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: say_when
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 2
|
9
|
-
- 6
|
10
|
-
version: 0.2.6
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.1
|
11
5
|
platform: ruby
|
12
|
-
authors:
|
6
|
+
authors:
|
13
7
|
- Andrew Kuklewicz
|
14
8
|
autorequire:
|
15
9
|
bindir: bin
|
16
10
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
- !ruby/object:Gem::Dependency
|
11
|
+
date: 2022-07-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
21
14
|
name: activemessaging
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
- !ruby/object:Gem::Version
|
27
|
-
hash: 59
|
28
|
-
segments:
|
29
|
-
- 0
|
30
|
-
- 9
|
31
|
-
- 0
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
32
19
|
version: 0.9.0
|
33
20
|
type: :development
|
34
21
|
prerelease: false
|
35
|
-
|
36
|
-
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.9.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
37
28
|
name: activesupport
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
hash: 31
|
44
|
-
segments:
|
45
|
-
- 2
|
46
|
-
- 3
|
47
|
-
- 14
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
48
33
|
version: 2.3.14
|
49
34
|
type: :development
|
50
35
|
prerelease: false
|
51
|
-
|
52
|
-
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.3.14
|
41
|
+
- !ruby/object:Gem::Dependency
|
53
42
|
name: activerecord
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
- !ruby/object:Gem::Version
|
59
|
-
hash: 31
|
60
|
-
segments:
|
61
|
-
- 2
|
62
|
-
- 3
|
63
|
-
- 14
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
64
47
|
version: 2.3.14
|
65
48
|
type: :development
|
66
49
|
prerelease: false
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
- 5
|
80
|
-
version: 1.9.5
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 2.3.14
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.3'
|
81
62
|
type: :development
|
82
63
|
prerelease: false
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
version: "1.3"
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.3'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 10.5.0
|
96
76
|
type: :development
|
97
77
|
prerelease: false
|
98
|
-
|
99
|
-
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 10.5.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
100
84
|
name: sqlite3
|
101
|
-
|
102
|
-
|
103
|
-
requirements:
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
104
87
|
- - ">="
|
105
|
-
- !ruby/object:Gem::Version
|
106
|
-
|
107
|
-
segments:
|
108
|
-
- 0
|
109
|
-
version: "0"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
110
90
|
type: :development
|
111
91
|
prerelease: false
|
112
|
-
|
113
|
-
|
114
|
-
name: rake
|
115
|
-
version_requirements: &id007 !ruby/object:Gem::Requirement
|
116
|
-
none: false
|
117
|
-
requirements:
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
118
94
|
- - ">="
|
119
|
-
- !ruby/object:Gem::Version
|
120
|
-
|
121
|
-
segments:
|
122
|
-
- 0
|
123
|
-
version: "0"
|
124
|
-
type: :development
|
125
|
-
prerelease: false
|
126
|
-
requirement: *id007
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
127
97
|
description:
|
128
|
-
email:
|
98
|
+
email:
|
129
99
|
- andrew@prx.org
|
130
100
|
executables: []
|
131
|
-
|
132
101
|
extensions: []
|
133
|
-
|
134
102
|
extra_rdoc_files: []
|
135
|
-
|
136
|
-
|
137
|
-
- .
|
103
|
+
files:
|
104
|
+
- ".gitignore"
|
105
|
+
- ".travis.yml"
|
138
106
|
- Gemfile
|
139
107
|
- Rakefile
|
140
108
|
- generators/say_when_migration/say_when_migration_generator.rb
|
@@ -154,7 +122,6 @@ files:
|
|
154
122
|
- lib/say_when/storage/active_record/job_execution.rb
|
155
123
|
- lib/say_when/storage/memory/base.rb
|
156
124
|
- lib/say_when/storage/memory/job.rb
|
157
|
-
- lib/say_when/storage/mongoid/job.rb
|
158
125
|
- lib/say_when/tasks.rb
|
159
126
|
- lib/say_when/triggers/base.rb
|
160
127
|
- lib/say_when/triggers/cron_strategy.rb
|
@@ -165,64 +132,47 @@ files:
|
|
165
132
|
- say_when.gemspec
|
166
133
|
- spec/active_record_spec_helper.rb
|
167
134
|
- spec/db/schema.rb
|
168
|
-
- spec/db/test.db
|
169
|
-
- spec/mongoid_spec_helper.rb
|
170
135
|
- spec/say_when/cron_expression_spec.rb
|
171
136
|
- spec/say_when/processor/active_messaging_spec.rb
|
172
137
|
- spec/say_when/scheduler_spec.rb
|
173
138
|
- spec/say_when/storage/active_record/job_spec.rb
|
174
139
|
- spec/say_when/storage/memory/job_spec.rb
|
175
140
|
- spec/say_when/storage/memory/trigger_spec.rb
|
176
|
-
- spec/say_when/storage/mongoid/trigger_spec.rb
|
177
141
|
- spec/say_when/triggers/once_strategy_spec.rb
|
178
142
|
- spec/spec.opts
|
179
143
|
- spec/spec_helper.rb
|
180
144
|
- spec/support/models.rb
|
181
145
|
homepage: http://labs.prx.org
|
182
146
|
licenses: []
|
183
|
-
|
147
|
+
metadata: {}
|
184
148
|
post_install_message:
|
185
149
|
rdoc_options: []
|
186
|
-
|
187
|
-
require_paths:
|
150
|
+
require_paths:
|
188
151
|
- lib
|
189
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
190
|
-
|
191
|
-
requirements:
|
152
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
153
|
+
requirements:
|
192
154
|
- - ">="
|
193
|
-
- !ruby/object:Gem::Version
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
version: "0"
|
198
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
199
|
-
none: false
|
200
|
-
requirements:
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: '0'
|
157
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
158
|
+
requirements:
|
201
159
|
- - ">="
|
202
|
-
- !ruby/object:Gem::Version
|
203
|
-
|
204
|
-
segments:
|
205
|
-
- 0
|
206
|
-
version: "0"
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: '0'
|
207
162
|
requirements: []
|
208
|
-
|
209
|
-
rubyforge_project:
|
210
|
-
rubygems_version: 1.8.22
|
163
|
+
rubygems_version: 3.1.4
|
211
164
|
signing_key:
|
212
|
-
specification_version:
|
165
|
+
specification_version: 4
|
213
166
|
summary: Scheduling system for programmatically defined and stored jobs.
|
214
|
-
test_files:
|
167
|
+
test_files:
|
215
168
|
- spec/active_record_spec_helper.rb
|
216
169
|
- spec/db/schema.rb
|
217
|
-
- spec/db/test.db
|
218
|
-
- spec/mongoid_spec_helper.rb
|
219
170
|
- spec/say_when/cron_expression_spec.rb
|
220
171
|
- spec/say_when/processor/active_messaging_spec.rb
|
221
172
|
- spec/say_when/scheduler_spec.rb
|
222
173
|
- spec/say_when/storage/active_record/job_spec.rb
|
223
174
|
- spec/say_when/storage/memory/job_spec.rb
|
224
175
|
- spec/say_when/storage/memory/trigger_spec.rb
|
225
|
-
- spec/say_when/storage/mongoid/trigger_spec.rb
|
226
176
|
- spec/say_when/triggers/once_strategy_spec.rb
|
227
177
|
- spec/spec.opts
|
228
178
|
- spec/spec_helper.rb
|
data/spec/db/test.db
DELETED
Binary file
|
data/spec/mongoid_spec_helper.rb
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../../../spec_helper'
|
2
|
-
require File.dirname(__FILE__) + '/../../../mongoid_spec_helper'
|
3
|
-
# require File.dirname(__FILE__) + '/../../../../lib/say_when/store/mongoid/trigger'
|
4
|
-
|
5
|
-
# describe SayWhen::Store::Mongoid::Trigger do
|
6
|
-
|
7
|
-
# before(:each) do
|
8
|
-
# SayWhen::Store::Mongoid::Trigger.delete_all
|
9
|
-
# @valid_attributes = {
|
10
|
-
# :expression => '0 0 12 ? * * *',
|
11
|
-
# :time_zone => 'Pacific Time (US & Canada)'
|
12
|
-
# }
|
13
|
-
# end
|
14
|
-
|
15
|
-
# it "can be created using new and save" do
|
16
|
-
# t = SayWhen::Store::Mongoid::Trigger.new(@valid_attributes)
|
17
|
-
# t.should be_valid
|
18
|
-
# t.save
|
19
|
-
# end
|
20
|
-
|
21
|
-
# it "sets a cron_expression" do
|
22
|
-
# t = SayWhen::Store::Mongoid::Trigger.create(@valid_attributes)
|
23
|
-
# t.cron_expression.should_not be_nil
|
24
|
-
# t.cron_expression.expression.should == '0 0 12 ? * * *'
|
25
|
-
# t.cron_expression.time_zone.should == 'Pacific Time (US & Canada)'
|
26
|
-
# end
|
27
|
-
|
28
|
-
# it "has a waiting state on create" do
|
29
|
-
# t = SayWhen::Store::Mongoid::Trigger.create(@valid_attributes)
|
30
|
-
# t.status.should == SayWhen::BaseTrigger::STATE_WAITING
|
31
|
-
# end
|
32
|
-
|
33
|
-
# it "has a next fire at set on create" do
|
34
|
-
# ce = SayWhen::CronExpression.new(@valid_attributes[:expression], @valid_attributes[:time_zone])
|
35
|
-
# t = SayWhen::Store::Mongoid::Trigger.create(@valid_attributes)
|
36
|
-
# t.status.should == SayWhen::BaseTrigger::STATE_WAITING
|
37
|
-
# t.next_fire_at.should == ce.next_fire_at(t.created_at)
|
38
|
-
# end
|
39
|
-
|
40
|
-
# it "can be fired" do
|
41
|
-
# ce = SayWhen::CronExpression.new(@valid_attributes[:expression], @valid_attributes[:time_zone])
|
42
|
-
# t = SayWhen::Store::Mongoid::Trigger.create(@valid_attributes)
|
43
|
-
# nfa = ce.last_fire_at(t.created_at - 1.second)
|
44
|
-
# lfa = ce.last_fire_at(nfa - 1.second)
|
45
|
-
# t.next_fire_at = nfa
|
46
|
-
# t.last_fire_at = lfa
|
47
|
-
|
48
|
-
# now = Time.now
|
49
|
-
# Time.stub!(:now).and_return(now)
|
50
|
-
|
51
|
-
# t.fired
|
52
|
-
# t.next_fire_at.should == ce.next_fire_at(now)
|
53
|
-
# t.last_fire_at.should == now
|
54
|
-
# t.status.should == SayWhen::BaseTrigger::STATE_WAITING
|
55
|
-
# end
|
56
|
-
|
57
|
-
# end
|