say_when 0.4.1 → 1.0.0
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 +5 -5
- data/.gitignore +13 -4
- data/Gemfile +1 -9
- data/LICENSE +21 -0
- data/README.md +31 -0
- data/Rakefile +6 -6
- data/lib/generators/say_when/migration/migration_generator.rb +8 -5
- data/lib/generators/say_when/migration/templates/migration.rb +8 -7
- data/lib/say_when/base_job.rb +2 -0
- data/lib/say_when/cron_expression.rb +129 -191
- data/lib/say_when/processor/active_messaging.rb +7 -8
- data/lib/say_when/processor/base.rb +5 -3
- data/lib/say_when/processor/shoryuken.rb +14 -0
- data/lib/say_when/processor/simple.rb +2 -0
- data/lib/say_when/railtie.rb +9 -0
- data/lib/say_when/scheduler.rb +49 -90
- data/lib/say_when/storage/active_record/acts.rb +16 -16
- data/lib/say_when/storage/active_record/job.rb +17 -24
- data/lib/say_when/storage/active_record/job_execution.rb +5 -8
- data/lib/say_when/storage/memory/base.rb +3 -1
- data/lib/say_when/storage/memory/job.rb +14 -42
- data/lib/say_when/tasks.rb +4 -4
- data/lib/say_when/triggers/base.rb +4 -3
- data/lib/say_when/triggers/cron_strategy.rb +4 -3
- data/lib/say_when/triggers/instance_strategy.rb +4 -3
- data/lib/say_when/triggers/once_strategy.rb +3 -2
- data/lib/say_when/version.rb +3 -1
- data/lib/say_when.rb +8 -7
- data/lib/tasks/say_when.rake +3 -1
- data/say_when.gemspec +26 -19
- data/test/active_record_helper.rb +13 -0
- data/{spec → test}/db/schema.rb +4 -4
- data/{spec/spec_helper.rb → test/minitest_helper.rb} +9 -19
- data/test/say_when/cron_expression_spec.rb +74 -0
- data/{spec/say_when/processor/active_messaging_spec.rb → test/say_when/processor/active_messaging_test.rb} +17 -13
- data/test/say_when/scheduler_test.rb +75 -0
- data/test/say_when/storage/active_record/job_test.rb +90 -0
- data/test/say_when/storage/memory/job_test.rb +32 -0
- data/test/say_when/storage/memory/trigger_test.rb +54 -0
- data/test/say_when/triggers/once_strategy_test.rb +23 -0
- data/{spec → test}/support/models.rb +5 -3
- metadata +97 -54
- data/.travis.yml +0 -4
- data/generators/say_when_migration/say_when_migration_generator.rb +0 -11
- data/generators/say_when_migration/templates/migration.rb +0 -48
- data/spec/active_record_spec_helper.rb +0 -9
- data/spec/say_when/cron_expression_spec.rb +0 -72
- data/spec/say_when/scheduler_spec.rb +0 -126
- data/spec/say_when/storage/active_record/job_spec.rb +0 -97
- data/spec/say_when/storage/memory/job_spec.rb +0 -45
- data/spec/say_when/storage/memory/trigger_spec.rb +0 -54
- data/spec/say_when/triggers/once_strategy_spec.rb +0 -22
- data/spec/spec.opts +0 -4
@@ -1,22 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
require 'activemessaging/message_sender'
|
2
4
|
|
3
5
|
module SayWhen
|
4
6
|
module Processor
|
5
|
-
|
6
7
|
class ActiveMessaging < SayWhen::Processor::Base
|
7
|
-
|
8
|
+
|
8
9
|
include ::ActiveMessaging::MessageSender
|
9
|
-
|
10
|
+
|
10
11
|
def initialize(scheduler)
|
11
12
|
super(scheduler)
|
12
13
|
end
|
13
14
|
|
14
15
|
# send the job to the other end, then in the a13g processor, call the execute method
|
15
16
|
def process(job)
|
16
|
-
publish(:say_when, {:
|
17
|
+
publish(:say_when, { job_id: job.id }.to_yaml )
|
17
18
|
end
|
18
|
-
|
19
|
-
end
|
20
|
-
|
19
|
+
end if defined?(::ActiveMessaging)
|
21
20
|
end
|
22
|
-
end
|
21
|
+
end
|
@@ -1,13 +1,15 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module SayWhen
|
2
4
|
module Processor
|
3
|
-
|
5
|
+
|
4
6
|
class Base
|
5
7
|
attr_accessor :scheduler
|
6
|
-
|
8
|
+
|
7
9
|
def initialize(scheduler)
|
8
10
|
@scheduler = scheduler
|
9
11
|
end
|
10
|
-
|
12
|
+
|
11
13
|
def process(job)
|
12
14
|
raise NotImplementedError.new('You need to implement process(job)')
|
13
15
|
end
|
data/lib/say_when/scheduler.rb
CHANGED
@@ -1,50 +1,42 @@
|
|
1
|
-
|
1
|
+
# encoding: utf-8
|
2
2
|
|
3
|
+
module SayWhen
|
3
4
|
class Scheduler
|
4
5
|
|
5
6
|
DEFAULT_PROCESSOR_CLASS = SayWhen::Processor::Simple
|
6
7
|
DEFAULT_STORAGE_STRATEGY = :memory
|
7
8
|
|
8
9
|
@@scheduler = nil
|
9
|
-
@@lock =
|
10
|
+
@@lock = Mutex.new
|
10
11
|
|
11
|
-
attr_accessor :storage_strategy, :processor_class, :tick_length
|
12
|
+
attr_accessor :storage_strategy, :processor_class, :tick_length
|
12
13
|
|
13
14
|
attr_accessor :running
|
14
15
|
|
15
16
|
# support for a singleton scheduler, but you are not restricted to this
|
16
17
|
class << self
|
17
|
-
|
18
18
|
def scheduler
|
19
|
-
|
20
|
-
|
21
|
-
@@scheduler = self.new
|
22
|
-
end
|
23
|
-
}
|
19
|
+
return @@scheduler if @@scheduler
|
20
|
+
@@lock.synchronize { @@scheduler = self.new if @@scheduler.nil? }
|
24
21
|
@@scheduler
|
25
22
|
end
|
26
23
|
|
27
24
|
def configure
|
28
|
-
yield
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
def lock
|
33
|
-
@@lock ||= Mutex.new
|
25
|
+
yield scheduler
|
26
|
+
scheduler
|
34
27
|
end
|
35
28
|
|
36
29
|
def schedule(job)
|
37
|
-
|
30
|
+
scheduler.schedule(job)
|
38
31
|
end
|
39
32
|
|
40
33
|
def start
|
41
|
-
|
34
|
+
scheduler.start
|
42
35
|
end
|
43
36
|
end
|
44
37
|
|
45
38
|
def initialize
|
46
|
-
self.tick_length =
|
47
|
-
self.reset_acquired_length = 3600
|
39
|
+
self.tick_length = [ENV['SAY_WHEN_TICK_LENGTH'].to_i, 5].max
|
48
40
|
end
|
49
41
|
|
50
42
|
def processor
|
@@ -63,88 +55,55 @@ module SayWhen
|
|
63
55
|
trap("TERM", "EXIT")
|
64
56
|
|
65
57
|
begin
|
58
|
+
|
66
59
|
self.running = true
|
67
60
|
|
68
61
|
logger.info "SayWhen::Scheduler running"
|
62
|
+
job = nil
|
69
63
|
while running
|
70
|
-
|
64
|
+
begin
|
65
|
+
time_now = Time.now
|
66
|
+
logger.debug "SayWhen:: Looking for job that should be ready to fire before #{time_now}"
|
67
|
+
job = job_class.acquire_next(time_now)
|
68
|
+
if job.nil?
|
69
|
+
logger.debug "SayWhen:: no jobs to acquire, sleep"
|
70
|
+
sleep(tick_length)
|
71
|
+
else
|
72
|
+
logger.debug "SayWhen:: got a job: #{job.inspect}"
|
73
|
+
# delegate processing the trigger to the processor
|
74
|
+
self.processor.process(job)
|
75
|
+
logger.debug "SayWhen:: job processed"
|
76
|
+
|
77
|
+
# this should update next fire at, and put back in list of scheduled jobs
|
78
|
+
job.fired(time_now)
|
79
|
+
logger.debug "SayWhen:: job fired complete"
|
80
|
+
end
|
81
|
+
rescue StandardError => ex
|
82
|
+
job_msg = job && "job: #{job.inspect} "
|
83
|
+
logger.error "SayWhen:: Failure: #{job_msg}exception: #{ex.message}\n\t#{ex.backtrace.join("\t\n")}"
|
84
|
+
safe_release(job)
|
85
|
+
sleep(tick_length)
|
86
|
+
rescue Interrupt => ex
|
87
|
+
job_msg = job && "\n - interrupted job: #{job.inspect}\n"
|
88
|
+
logger.error "\nSayWhen:: Interrupt! #{ex.inspect}#{job_msg}"
|
89
|
+
safe_release(job)
|
90
|
+
exit
|
91
|
+
rescue Exception => ex
|
92
|
+
job_msg = job && "job: #{job.inspect} "
|
93
|
+
logger.error "SayWhen:: Exception: #{job_msg}exception: #{ex.message}\n\t#{ex.backtrace.join("\t\n")}"
|
94
|
+
safe_release(job)
|
95
|
+
exit
|
96
|
+
end
|
71
97
|
end
|
72
|
-
rescue Exception => ex
|
73
|
-
logger.error "SayWhen::Scheduler stopping, error: #{ex.class.name}: #{ex.message}"
|
74
|
-
exit
|
75
98
|
end
|
76
99
|
|
77
100
|
logger.info "SayWhen::Scheduler stopped"
|
78
101
|
end
|
79
102
|
|
80
|
-
def
|
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")}"
|
103
|
+
def safe_release(job)
|
147
104
|
job.release if job
|
105
|
+
rescue
|
106
|
+
logger "Failed to release job: #{job.inspect}" rescue nil
|
148
107
|
end
|
149
108
|
|
150
109
|
def stop
|
@@ -1,57 +1,59 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module SayWhen #:nodoc:
|
2
4
|
module Storage #:nodoc:
|
3
5
|
module ActiveRecord #:nodoc:
|
4
6
|
module Acts #:nodoc:
|
5
7
|
|
6
|
-
|
7
|
-
base.extend ClassMethods
|
8
|
-
end
|
8
|
+
extend ActiveSupport::Concern
|
9
9
|
|
10
10
|
module ClassMethods
|
11
11
|
def acts_as_scheduled
|
12
12
|
include SayWhen::Storage::ActiveRecord::Acts::InstanceMethods
|
13
|
-
|
14
|
-
has_many :scheduled_jobs, :
|
13
|
+
|
14
|
+
has_many :scheduled_jobs, as: :scheduled, class_name: 'SayWhen::Storage::ActiveRecord::Job', dependent: :destroy
|
15
15
|
end
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
module InstanceMethods
|
19
19
|
|
20
20
|
def schedule_instance(next_at_method, job={})
|
21
21
|
options = job_options(job)
|
22
22
|
options[:trigger_strategy] = 'instance'
|
23
|
-
options[:trigger_options] = {:next_at_method
|
23
|
+
options[:trigger_options] = { next_at_method: next_at_method }
|
24
24
|
Scheduler.schedule(options)
|
25
25
|
end
|
26
26
|
|
27
27
|
def schedule_cron(expression, time_zone, job={})
|
28
28
|
options = job_options(job)
|
29
29
|
options[:trigger_strategy] = 'cron'
|
30
|
-
options[:trigger_options] = {:
|
30
|
+
options[:trigger_options] = { expression: expression, time_zone: time_zone }
|
31
31
|
Scheduler.schedule(options)
|
32
32
|
end
|
33
33
|
|
34
34
|
def schedule_once(time, job={})
|
35
35
|
options = job_options(job)
|
36
36
|
options[:trigger_strategy] = 'once'
|
37
|
-
options[:trigger_options] = {:
|
37
|
+
options[:trigger_options] = { at: time}
|
38
38
|
Scheduler.schedule(options)
|
39
39
|
end
|
40
40
|
|
41
41
|
def schedule_in(after, job={})
|
42
42
|
options = job_options(job)
|
43
43
|
options[:trigger_strategy] = 'once'
|
44
|
-
options[:trigger_options] = {:
|
44
|
+
options[:trigger_options] = { at: (Time.now + after)}
|
45
45
|
Scheduler.schedule(options)
|
46
46
|
end
|
47
47
|
|
48
48
|
# helpers
|
49
49
|
|
50
50
|
def job_options(job)
|
51
|
-
{
|
52
|
-
:
|
53
|
-
:
|
54
|
-
:
|
51
|
+
{
|
52
|
+
scheduled: self,
|
53
|
+
job_class: extract_job_class(job),
|
54
|
+
job_method: extract_job_method(job),
|
55
|
+
data: extract_data(job)
|
56
|
+
}
|
55
57
|
end
|
56
58
|
|
57
59
|
def extract_job_class(job)
|
@@ -81,9 +83,7 @@ module SayWhen #:nodoc:
|
|
81
83
|
nil
|
82
84
|
end
|
83
85
|
end
|
84
|
-
|
85
86
|
end # InstanceMethods
|
86
|
-
|
87
87
|
end
|
88
88
|
end
|
89
89
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
require 'active_record'
|
2
4
|
require 'say_when/base_job'
|
3
5
|
require 'say_when/storage/active_record/job_execution'
|
@@ -8,41 +10,34 @@ module SayWhen
|
|
8
10
|
module ActiveRecord
|
9
11
|
|
10
12
|
class Job < ::ActiveRecord::Base
|
13
|
+
|
11
14
|
include SayWhen::BaseJob
|
12
|
-
|
15
|
+
|
16
|
+
self.table_name = 'say_when_jobs'
|
17
|
+
|
13
18
|
serialize :trigger_options
|
14
19
|
serialize :data
|
15
|
-
belongs_to :scheduled, :polymorphic => true
|
16
|
-
has_many :job_executions, :class_name=>'SayWhen::Storage::ActiveRecord::JobExecution'
|
17
|
-
before_create :set_defaults
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
"status = '#{STATE_WAITING}'",
|
24
|
-
["status = ? and updated_at < ?", STATE_ACQUIRED, older_than]
|
25
|
-
)
|
26
|
-
end
|
21
|
+
belongs_to :scheduled, polymorphic: true
|
22
|
+
has_many :job_executions, class_name: 'SayWhen::Storage::ActiveRecord::JobExecution'
|
23
|
+
|
24
|
+
before_create :set_defaults
|
27
25
|
|
28
26
|
def self.acquire_next(no_later_than)
|
29
|
-
|
27
|
+
next_job = nil
|
28
|
+
|
30
29
|
hide_logging do
|
31
30
|
SayWhen::Storage::ActiveRecord::Job.transaction do
|
32
31
|
# select and lock the next job that needs executin' (status waiting, and after no_later_than)
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
:conditions => ['status = ? and ? >= next_fire_at',
|
37
|
-
STATE_WAITING,
|
38
|
-
no_later_than])
|
32
|
+
next_job = where('status = ? and next_fire_at < ?', STATE_WAITING, no_later_than.in_time_zone('UTC')).
|
33
|
+
order('next_fire_at ASC').
|
34
|
+
lock(true).first
|
39
35
|
|
40
36
|
# set status to acquired to take it out of rotation
|
41
|
-
|
42
|
-
|
37
|
+
next_job.update_attribute(:status, STATE_ACQUIRED) unless next_job.nil?
|
43
38
|
end
|
44
39
|
end
|
45
|
-
|
40
|
+
next_job
|
46
41
|
end
|
47
42
|
|
48
43
|
def set_defaults
|
@@ -99,9 +94,7 @@ module SayWhen
|
|
99
94
|
::ActiveRecord::Base.logger = old_logger
|
100
95
|
end
|
101
96
|
end
|
102
|
-
|
103
97
|
end
|
104
|
-
|
105
98
|
end
|
106
99
|
end
|
107
100
|
end
|
@@ -1,17 +1,14 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
require 'active_record'
|
2
4
|
|
3
5
|
module SayWhen
|
4
6
|
module Storage
|
5
7
|
module ActiveRecord
|
6
|
-
|
7
|
-
class JobExecution < ::ActiveRecord::Base
|
8
|
-
|
8
|
+
class JobExecution < ::ActiveRecord::Base
|
9
9
|
self.table_name = "say_when_job_executions"
|
10
|
-
|
11
|
-
belongs_to :job, :class_name=>'SayWhen::Storage::ActiveRecord::Job'
|
12
|
-
|
10
|
+
belongs_to :job, class_name: 'SayWhen::Storage::ActiveRecord::Job'
|
13
11
|
end
|
14
|
-
|
15
12
|
end
|
16
13
|
end
|
17
|
-
end
|
14
|
+
end
|
@@ -1,81 +1,53 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
require 'say_when/storage/memory/base'
|
2
4
|
|
3
5
|
module SayWhen
|
4
|
-
module
|
6
|
+
module Storage
|
5
7
|
module Memory
|
6
8
|
|
7
9
|
# define a trigger class
|
8
10
|
class Job
|
9
11
|
|
10
|
-
cattr_accessor :jobs
|
11
|
-
@@jobs = SortedSet.new
|
12
|
-
|
13
12
|
include SayWhen::Storage::Memory::Base
|
14
|
-
|
13
|
+
include SayWhen::BaseJob
|
15
14
|
|
16
15
|
has_properties :group, :name, :status, :start_at, :end_at
|
17
16
|
has_properties :trigger_strategy, :trigger_options, :last_fire_at, :next_fire_at
|
18
17
|
has_properties :job_class, :job_method, :data
|
19
18
|
has_properties :scheduled
|
20
|
-
has_properties :updated_at
|
21
|
-
|
22
|
-
def self.class_lock
|
23
|
-
@@_lock ||= Mutex.new
|
24
|
-
end
|
25
19
|
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
+
cattr_accessor :jobs
|
21
|
+
@@jobs = SortedSet.new
|
22
|
+
@@acquire_lock = Mutex.new
|
39
23
|
|
40
24
|
def self.acquire_next(no_later_than)
|
41
|
-
|
25
|
+
@@acquire_lock.synchronize {
|
42
26
|
|
43
27
|
next_job = jobs.detect(nil) do |j|
|
44
28
|
(j.status == STATE_WAITING) && (j.next_fire_at.to_i <= no_later_than.to_i)
|
45
29
|
end
|
46
30
|
|
47
|
-
if next_job
|
48
|
-
next_job.status = STATE_ACQUIRED
|
49
|
-
next_job.updated_at = Time.now
|
50
|
-
end
|
51
|
-
|
31
|
+
next_job.status = STATE_ACQUIRED if next_job
|
52
32
|
next_job
|
53
33
|
}
|
54
34
|
end
|
55
35
|
|
36
|
+
def self.create(job)
|
37
|
+
job = new(job) if job.is_a?(Hash)
|
38
|
+
self.jobs << job
|
39
|
+
end
|
40
|
+
|
56
41
|
def initialize(options={})
|
57
42
|
super
|
58
|
-
self.updated_at = Time.now
|
59
43
|
self.status = STATE_WAITING unless self.status
|
60
44
|
self.next_fire_at = trigger.next_fire_at
|
61
|
-
self.class.jobs << self
|
62
45
|
end
|
63
46
|
|
64
47
|
def <=>(job)
|
65
48
|
self.next_fire_at.to_i <=> job.next_fire_at.to_i
|
66
49
|
end
|
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
|
77
50
|
end
|
78
|
-
|
79
51
|
end
|
80
52
|
end
|
81
53
|
end
|
data/lib/say_when/tasks.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
|
1
|
+
# encoding: utf-8
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
namespace :say_when do
|
4
|
+
desc 'Start the SayWhen Scheduler'
|
5
|
+
task start: :environment do
|
5
6
|
require 'say_when'
|
6
7
|
SayWhen::Scheduler.start
|
7
8
|
end
|
8
|
-
|
9
9
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module SayWhen
|
2
4
|
module Triggers
|
3
5
|
module Base
|
@@ -5,13 +7,12 @@ module SayWhen
|
|
5
7
|
attr_accessor :job
|
6
8
|
|
7
9
|
def initialize(options={})
|
8
|
-
|
10
|
+
self.job = options.delete(:job)
|
9
11
|
end
|
10
12
|
|
11
13
|
def next_fire_at(time=nil)
|
12
14
|
raise NotImplementedError.new('You need to implement next_fire_at in your strategy')
|
13
15
|
end
|
14
|
-
|
15
16
|
end
|
16
17
|
end
|
17
|
-
end
|
18
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
require 'say_when/triggers/base'
|
2
4
|
require 'say_when/cron_expression'
|
3
5
|
|
@@ -11,13 +13,12 @@ module SayWhen
|
|
11
13
|
|
12
14
|
def initialize(options={})
|
13
15
|
super
|
14
|
-
|
16
|
+
self.cron_expression = SayWhen::CronExpression.new(options)
|
15
17
|
end
|
16
18
|
|
17
19
|
def next_fire_at(time=nil)
|
18
20
|
cron_expression.next_fire_at(time || Time.now)
|
19
21
|
end
|
20
|
-
|
21
22
|
end
|
22
23
|
end
|
23
|
-
end
|
24
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
require 'say_when/triggers/base'
|
2
4
|
|
3
5
|
module SayWhen
|
@@ -10,14 +12,13 @@ module SayWhen
|
|
10
12
|
|
11
13
|
def initialize(options={})
|
12
14
|
super
|
13
|
-
|
14
|
-
|
15
|
+
self.instance = job.scheduled
|
16
|
+
self.next_at_method = options[:next_at_method] || 'next_fire_at'
|
15
17
|
end
|
16
18
|
|
17
19
|
def next_fire_at(time=Time.now)
|
18
20
|
instance.send(next_at_method, time)
|
19
21
|
end
|
20
|
-
|
21
22
|
end
|
22
23
|
end
|
23
24
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
require 'say_when/triggers/base'
|
2
4
|
|
3
5
|
module SayWhen
|
@@ -10,14 +12,13 @@ module SayWhen
|
|
10
12
|
|
11
13
|
def initialize(options=nil)
|
12
14
|
super
|
13
|
-
|
15
|
+
self.once_at = options[:at] || Time.now
|
14
16
|
end
|
15
17
|
|
16
18
|
def next_fire_at(time=nil)
|
17
19
|
nfa = once_at if (!time || (time <= once_at))
|
18
20
|
return nfa
|
19
21
|
end
|
20
|
-
|
21
22
|
end
|
22
23
|
end
|
23
24
|
end
|
data/lib/say_when/version.rb
CHANGED