urge 0.0.1 → 0.0.2

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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZjYwNzQxMzM3ZmQyNGJlNzBhOWY2YTJmZTFlMzk0ODFlODA1NjExYw==
4
+ Nzg5ZjVlOTg2MWUzYWE5NTYxZTliZmE3Y2ZiOWVkMzA1N2JjMTRlNg==
5
5
  data.tar.gz: !binary |-
6
- M2NmZGU5ZWY0OGVkZmI0MzU5NDYyMzc0NThhOTU2Yjc2NDA0ZGFkNw==
6
+ MmFhZjQyZTUzYTBlNGQ2Njg4MTBiNjU0NzFkNDNjZmQ2ZTMyYjg0OQ==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- MzA2NDVlMWQ1OWJkNzY1OGJjNDhkNzllMjI0NzlmODg3YzczOTQyYjUxMjZh
10
- MzMyNjZmYzRlZmUwYmI1OTFlNGZlZDNhZmIyZjEwYThjZmM4Zjg4ZGQyZDY2
11
- OTYxYjljZTQzYjNlYjdlYTcwYmNkYTZmNmFlNGRkYjlmMzU2NGM=
9
+ MzNlN2Y2M2M5ZDRmYThmOWQxZmMyYzg1N2EyN2YwOTA5NTBiZTdiNDcxYzQ2
10
+ ZDg0MDhjYjU4NjExNmJhYmU5ZjRlZjQzNTZkZTk1ZjgwYTJlOWU2NTY3NTc1
11
+ YTYxOWU5ZjUxNWQ4OTZiZWZkMTAzNTkzNDFiNTBlMzhjZTQ2ZmE=
12
12
  data.tar.gz: !binary |-
13
- NmY5M2QwNjNkZWY0N2EyOTA5MWNiMzA1NjY1ZWVmZjgwOTA3YjQzNjg3NTk4
14
- YjhmZjhmYWFmZTc4ODEyZDNkNzJhODZjZTUyZmJhZTNhY2EzMWNmNzhjYjg3
15
- ZTgzZjRlYTUwNGFiM2FkMDc3MDAwMmVkYzNmYWQzYWE3MjMzZmM=
13
+ M2FiM2I2MThjY2UxNTdiMzMyNzcwYTJiMDA0YmMxODQ1MDgwNDI1MjhlZGJk
14
+ ZjYxMTQyOTVlOGJmZDViZjEwZDE1MTYyNzE5YjNjODJlNmFmZWU1MjNkOWU3
15
+ MzQ2MmFiN2FhMjE1YzYzM2IxODk0YzQ4MTJkOWI3OGViNmQxZWI=
@@ -11,10 +11,10 @@ module Urge
11
11
  module ClassMethods
12
12
 
13
13
  # AR finder
14
- def ready_to_run( name, at = DateTime.now )
15
- options = schedules[name]
14
+ def urgent( name, at = DateTime.now )
15
+ options = urge_schedules[name]
16
16
  raise 'Unknown schedule' unless options
17
- where( "#{attr_name(name)} < ?", at )
17
+ where( "#{urge_attr_name(name)} < ?", at )
18
18
  end
19
19
 
20
20
 
@@ -36,22 +36,16 @@ module Urge
36
36
  # matches
37
37
  # end
38
38
 
39
- # Same as Scheduled::run_all but saves the rescheduled task
40
- def run_all!( name )
41
- now = DateTime.now
42
- logger.debug "run_all! Time now: #{now}"
43
- ready_to_run( now ).each do |task|
44
- logger.debug "Task of class #{task.class.name} is about to be run! (with a bang)"
45
- task.run!( name )
46
- end
39
+ def urge_all!( name )
40
+ urgent( name ).each { |u| u.urge!( name ) }
47
41
  end
48
42
 
49
43
  end
50
44
 
51
45
  module InstanceMethods
52
46
 
53
- def run!( name, options = {} )
54
- run( name, options )
47
+ def urge!( name, options = {} )
48
+ urge( name, options )
55
49
  save!
56
50
  end
57
51
 
data/lib/urge/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Urge
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/urge.rb CHANGED
@@ -1,10 +1,117 @@
1
1
  require 'urge/version'
2
- require 'urge/scheduled'
3
2
  require 'urge/persistence'
4
3
 
5
- # require 'urge/credit_control'
6
-
7
4
  require 'logging'
8
5
 
9
6
  module Urge
10
- end
7
+
8
+ module ClassMethods
9
+
10
+ # def run_all( name )
11
+ # now = DateTime.now
12
+ # logger.debug "run_all. Time now: #{now}"
13
+ # ready_to_run( name, now ).each do |task|
14
+ # logger.debug "Task of class #{task.class.name} named: #{name} is about to be run"
15
+ # task.run( name )
16
+ # end
17
+ # end
18
+ #
19
+ # def inspect_all( name )
20
+ # now = DateTime.now
21
+ # tasks = ready_to_run( name, now )
22
+ # logger.info "inspect_queue. Time now: #{now}. The following #{tasks.size} tasks are ready to run"
23
+ # tasks.each { |task| logger.info task.inspect }
24
+ # tasks
25
+ # end
26
+
27
+ def urge_logger
28
+ @@urge_logger ||= Logging.logger[self]
29
+ end
30
+
31
+ def urge_schedule( name, options = {} )
32
+
33
+ urge_logger.info "Defining schedule: #{name}. Options: #{options}. Class: #{self.name}"
34
+
35
+ # Warn if a schedule with this name already exists, but don't bail out.
36
+ # It's not necessarily an error. Rails autoloading classes is an example where it's not...
37
+ urge_logger.warn "A schedule with this name already exists. Old options: #{urge_schedules[name]}" if urge_schedules[name]
38
+
39
+ # NEW. Set defaults. The name pf the action metod is the same as the name of the schedule, and the name of the timestamp
40
+ # attribute is likewise, but with _at appended.
41
+
42
+ # For example, if the schedule name is 'check_credit', the signature of the action method - unless overridden - is
43
+ # expected to be
44
+
45
+ # def check_credit( options )
46
+ # end
47
+
48
+ # The timestamp name - unless set explicitly - is check_credit_at
49
+ options[:timestamp_name] ||= "#{name}_at"
50
+ options[:action] ||= name
51
+
52
+ urge_schedules[name] = options
53
+ end
54
+
55
+ def urge_schedules
56
+ @@urge_per_class_schedules ||= {}
57
+ @@urge_per_class_schedules[self.name] ||= {}
58
+ end
59
+
60
+ def urge_all_schedules
61
+ @@urge_per_class_schedules
62
+ end
63
+
64
+ # private
65
+
66
+ def urge_attr_name( name )
67
+ raise 'Non existent schedule name' unless urge_schedules[name]
68
+ urge_schedules[name][:timestamp_name]
69
+ end
70
+
71
+ end
72
+
73
+ #
74
+ #
75
+ #
76
+ module InstanceMethods
77
+
78
+ def urgent?( name )
79
+ ts = self.send( urge_attr_name( name ) )
80
+ ts ? (DateTime.now >= ts) : false
81
+ end
82
+
83
+ def urge_reschedule( name, _when )
84
+ urge_logger.debug "ScheduledTask#reschedule about to reschedule for #{_when}"
85
+ self.send( "#{urge_attr_name(name)}=", _when )
86
+ end
87
+
88
+ # Takes action and reschedules itself. That is all, and that is enough!
89
+ def urge( name, options = {} )
90
+
91
+ return false unless urgent?( name )
92
+
93
+ interval = self.send( self.class.urge_schedules[name][:action].to_sym, options )
94
+ urge_reschedule( name, interval ? interval.from_now : nil )
95
+ true
96
+
97
+ end
98
+
99
+ private
100
+
101
+ def urge_attr_name( name )
102
+ self.class.urge_attr_name( name )
103
+ end
104
+
105
+ def urge_logger
106
+ self.class.urge_logger
107
+ end
108
+
109
+ end
110
+
111
+ def self.included(base)
112
+ base.extend ClassMethods
113
+ base.send :include, InstanceMethods
114
+ Urge::Persistence.set_persistence(base)
115
+ end
116
+
117
+ end
data/spec/aasm.sqlite3.db CHANGED
Binary file
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
1
+ require 'spec_helper'
2
2
 
3
3
  load_schema
4
4
 
@@ -14,10 +14,10 @@ logger = Logging.logger['simple']
14
14
 
15
15
  class DualActionGuest < ActiveRecord::Base
16
16
 
17
- include Urge::Scheduled
17
+ include Urge
18
18
 
19
- urge_schedule( :status_check, :scheduled_for => :status_check_at, :action => :check_status )
20
- urge_schedule( :insurance_check, :scheduled_for => :insurance_check_at, :action => :check_insurance )
19
+ urge_schedule( :status_check, :timestamp_name => :status_check_at, :action => :check_status )
20
+ urge_schedule( :insurance_check, :timestamp_name => :insurance_check_at, :action => :check_insurance )
21
21
 
22
22
  def status_checked?
23
23
  @status_checked
@@ -83,13 +83,13 @@ describe 'AR model with more than one schedule' do
83
83
  @checks = [:status_check, :insurance_check]
84
84
  end
85
85
 
86
- it "both checks should be ready to run" do
87
- @checks.each { |c| @guest.should be_ready_to_run( c ) }
86
+ it "both checks should be urgent" do
87
+ @checks.each { |c| @guest.should be_urgent( c ) }
88
88
  end
89
89
 
90
90
  context "when run" do
91
91
  before(:each) do
92
- @checks.each { |c| @guest.run( c )}
92
+ @checks.each { |c| @guest.urge( c )}
93
93
  end
94
94
 
95
95
  it "should result in the guest having his status and his insurance checked" do
@@ -118,14 +118,12 @@ describe "AR finders" do
118
118
 
119
119
  it "should return the correct number guests ready to run" do
120
120
 
121
- logger.info "All schedules: #{DualActionGuest.all_schedules}"
122
-
123
121
  expect {
124
- DualActionGuest.ready_to_run( :default )
122
+ DualActionGuest.urgent( :default )
125
123
  }.to raise_error( RuntimeError )
126
124
 
127
- DualActionGuest.ready_to_run( :status_check ).should have(@count).items
128
- DualActionGuest.ready_to_run( :insurance_check ).should have(@count).items
125
+ DualActionGuest.urgent( :status_check ).should have(@count).items
126
+ DualActionGuest.urgent( :insurance_check ).should have(@count).items
129
127
  end
130
128
 
131
129
  end
@@ -1,17 +1,16 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
1
+ require 'spec_helper'
2
2
 
3
3
  load_schema
4
4
 
5
5
  class SimpleGuest < ActiveRecord::Base
6
6
 
7
- include Urge::Scheduled
8
-
9
- urge_schedule( :default, :scheduled_for => :scheduled_for, :action => :take_action )
7
+ include Urge
8
+ urge_schedule( :default, :timestamp_name => :scheduled_for, :action => :take_action )
10
9
 
11
10
  private
12
11
 
13
12
  def take_action( options )
14
- logger.debug "In take_action. About to return empty set"
13
+ logger.debug "In take_action. About to return nil"
15
14
  nil
16
15
  end
17
16
 
@@ -52,7 +51,7 @@ describe 'Simplest active record model' do
52
51
  end
53
52
 
54
53
  it "should be ready to run" do
55
- @guest.should be_ready_to_run( :default )
54
+ @guest.should be_urgent( :default )
56
55
  end
57
56
 
58
57
  it "should raise an exception if an attempt is made to access a schedule that doesn't exist" do
@@ -61,9 +60,9 @@ describe 'Simplest active record model' do
61
60
  }.to raise_error
62
61
  end
63
62
 
64
- context "when run" do
63
+ context "when urged" do
65
64
  before(:each) do
66
- @guest.run :default
65
+ @guest.urge :default
67
66
  end
68
67
 
69
68
  it "should not be rescheduled" do
@@ -73,7 +72,7 @@ describe 'Simplest active record model' do
73
72
 
74
73
  end
75
74
 
76
- describe "AR finders" do
75
+ describe "Class method finders" do
77
76
 
78
77
  before(:each) do
79
78
 
@@ -85,9 +84,39 @@ describe "AR finders" do
85
84
  end
86
85
  end
87
86
 
88
- it "should return the correct number guests ready to run" do
89
- SimpleGuest.ready_to_run( :default ).should have(@count).items
87
+ it "should find the correct number of urgent guests" do
88
+ SimpleGuest.urgent( :default ).should have(@count).items
90
89
  end
91
90
 
92
91
  end
93
92
 
93
+
94
+ describe "AR saving. 10 guests, when scheduled" do
95
+
96
+ before(:each) do
97
+
98
+ SimpleGuest.delete_all
99
+ @count = 10
100
+ @count.times do |index|
101
+ FactoryGirl.create :simple_guest, :scheduled_for => 1.day.ago
102
+ end
103
+
104
+ end
105
+
106
+ it "should return the correct number of urgent guests" do
107
+ SimpleGuest.urgent( :default ).should have(@count).items
108
+ end
109
+
110
+ context "when urged" do
111
+
112
+ before(:each) do
113
+ SimpleGuest.urge_all! :default
114
+ end
115
+
116
+ it "should have no urgent guests" do
117
+ SimpleGuest.urgent( :default ).should be_empty
118
+ end
119
+
120
+ end
121
+
122
+ end
@@ -1,11 +1,11 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require 'spec_helper'
2
2
 
3
3
  #
4
4
  #
5
5
  #
6
6
  class TwoTask
7
7
 
8
- include Urge::Scheduled
8
+ include Urge
9
9
 
10
10
  attr_accessor :scheduled_for_one, :scheduled_for_two
11
11
 
@@ -15,13 +15,13 @@ class TwoTask
15
15
  @scheduled_for_one = attrs[:scheduled_for_one]
16
16
  @scheduled_for_two = attrs[:scheduled_for_two]
17
17
 
18
- @logger = options[:logger] || Logging.logger['scheduled_test']
18
+ @logger = options[:logger] || Logging.logger['test']
19
19
 
20
20
  @actions = options[:actions]
21
21
  end
22
22
 
23
- urge_schedule( :one, :scheduled_for => :scheduled_for_one, :action => :take_one )
24
- urge_schedule( :two, :scheduled_for => :scheduled_for_two, :action => :take_two )
23
+ urge_schedule( :one, :timestamp_name => :scheduled_for_one, :action => :take_one )
24
+ urge_schedule( :two, :timestamp_name => :scheduled_for_two, :action => :take_two )
25
25
 
26
26
  def take_one( options )
27
27
  @actions << :action_one
@@ -35,7 +35,7 @@ class TwoTask
35
35
 
36
36
  end
37
37
 
38
- describe Urge::Scheduled do
38
+ describe Urge do
39
39
 
40
40
  context "when applied to an in memory object requiring two separate actions, that object" do
41
41
 
@@ -53,10 +53,10 @@ describe Urge::Scheduled do
53
53
  @actions.should be_empty
54
54
  end
55
55
 
56
- context "when run in the context of task 1" do
56
+ context "when urged in the context of task 1" do
57
57
 
58
58
  before(:each) do
59
- @object.run( :one )
59
+ @object.urge( :one )
60
60
  end
61
61
 
62
62
  it "should produce one action" do
@@ -70,10 +70,10 @@ describe Urge::Scheduled do
70
70
 
71
71
  end
72
72
 
73
- context "when run in the context of task 2" do
73
+ context "when urged in the context of task 2" do
74
74
 
75
75
  before(:each) do
76
- @object.run( :two )
76
+ @object.urge( :two )
77
77
  end
78
78
 
79
79
  it "should produce another action" do
@@ -87,11 +87,11 @@ describe Urge::Scheduled do
87
87
 
88
88
  end
89
89
 
90
- context "when run in the context of both tasks" do
90
+ context "when urged in the context of both tasks" do
91
91
 
92
92
  before(:each) do
93
- @object.run( :one )
94
- @object.run( :two )
93
+ @object.urge( :one )
94
+ @object.urge( :two )
95
95
  end
96
96
 
97
97
  it "should produce two actions" do
@@ -1,38 +1,42 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require 'spec_helper'
2
2
 
3
3
  Logging.logger['simple'].tap {|logger|
4
4
  logger.add_appenders 'colourful_stdout'
5
5
  logger.level = :info
6
6
  }
7
7
 
8
-
9
8
  #
10
9
  #
11
10
  #
12
11
  class Simple
12
+
13
+ # By including the Urge module, we drag in all the class methods from that module
14
+ include Urge
13
15
 
14
- include Urge::Scheduled
15
-
16
- attr_accessor :scheduled_for
16
+ attr_accessor :something_at
17
17
  attr_reader :actions, :logger
18
18
 
19
19
  def initialize( attrs = {} )
20
- self.scheduled_for = attrs[:scheduled_for]
20
+ self.something_at = attrs[:something_at]
21
21
 
22
22
  @logger = Logging.logger['simple']
23
23
  @actions = []
24
24
  end
25
25
 
26
- urge_schedule( :something, :scheduled_for => :scheduled_for, :action => :do_something )
26
+ urge_schedule :something, :action => 'do_something'
27
27
 
28
28
  def do_something( options )
29
29
  @actions << :foo
30
30
  nil
31
31
  end
32
32
 
33
+ # def self.attr_name( name )
34
+ # raise 'ILLEGAL!'
35
+ # end
36
+
33
37
  end
34
38
 
35
- describe Urge::Scheduled do
39
+ describe Urge do
36
40
 
37
41
  context "when applied to a simple, in memory object" do
38
42
 
@@ -47,10 +51,10 @@ describe Urge::Scheduled do
47
51
 
48
52
  context "that is not scheduled" do
49
53
 
50
- context "when run in the correct context" do
54
+ context "when urged to do something" do
51
55
 
52
56
  before(:each) do
53
- @object.run( :something )
57
+ @object.urge( :something )
54
58
  end
55
59
 
56
60
  it "should do nothing" do
@@ -64,13 +68,13 @@ describe Urge::Scheduled do
64
68
  context "that has been scheduled to run 1 second ago" do
65
69
 
66
70
  before(:each) do
67
- @object.scheduled_for = 1.second.ago
71
+ @object.something_at = 1.second.ago
68
72
  end
69
73
 
70
- context "when run in the correct context" do
74
+ context "when urged in the correct context" do
71
75
 
72
76
  before(:each) do
73
- @object.run( :something )
77
+ @object.urge( :something )
74
78
  end
75
79
 
76
80
  it "should produce one action" do
@@ -79,16 +83,16 @@ describe Urge::Scheduled do
79
83
  end
80
84
 
81
85
  it "should not be rescheduled" do
82
- @object.scheduled_for.should be_nil
86
+ @object.something_at.should be_nil
83
87
  end
84
88
 
85
89
  end
86
90
 
87
- context "when run in a non existent context" do
91
+ context "when urged in a non existent context" do
88
92
 
89
93
  it "should raise an error" do
90
94
  expect {
91
- @object.run( :doesnt_exist )
95
+ @object.urge( :doesnt_exist )
92
96
  }.to raise_error( RuntimeError )
93
97
  end
94
98
 
data/spec/spec_helper.rb CHANGED
@@ -26,7 +26,7 @@ Logging.configure do
26
26
  )
27
27
  )
28
28
 
29
- test_loggers = %w{ scheduled_task_test credit_control_test scheduled_test scheduled }
29
+ test_loggers = %w{ test }
30
30
  # test_loggers = []
31
31
 
32
32
  test_loggers.each do |name|
@@ -40,31 +40,13 @@ end
40
40
 
41
41
  require 'aasm'
42
42
  require 'logging'
43
- require 'urge/scheduled'
44
43
  require 'active_support/time'
45
44
  require 'active_record'
46
45
  require 'factory_girl'
47
46
 
48
47
  FactoryGirl.find_definitions
49
48
 
50
- class ScheduledTask
51
-
52
- include Urge::Scheduled
53
-
54
- attr_reader :logger
55
-
56
- def initialize( name, options = {} )
57
- if options[:logger]
58
- @logger = options[:logger]
59
- else
60
- @logger = Logging.logger['scheduled_task_test']
61
- end
62
- self.name = name
63
- end
64
-
65
- end
66
-
67
- ActiveRecord::Base.logger = Logging.logger['credit_control_test']
49
+ ActiveRecord::Base.logger = Logging.logger['test']
68
50
 
69
51
  def load_schema
70
52
  config = YAML::load( IO.read( File.dirname(__FILE__) + '/database.yml' ) )
@@ -72,6 +54,4 @@ def load_schema
72
54
  load( File.dirname(__FILE__) + "/schema.rb" )
73
55
  end
74
56
 
75
- class Client < ActiveRecord::Base
76
- end
77
57
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: urge
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Adams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-03-02 00:00:00.000000000 Z
11
+ date: 2013-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -110,15 +110,14 @@ files:
110
110
  - lib/urge/persistence.rb
111
111
  - lib/urge/persistence/active_record_persistence.rb
112
112
  - lib/urge/persistence/base.rb
113
- - lib/urge/scheduled.rb
114
113
  - lib/urge/version.rb
115
114
  - spec/aasm.sqlite3.db
116
115
  - spec/database.yml
117
116
  - spec/factories/factory.rb
118
- - spec/lib/active_record/dual_action_model_spec.rb
119
- - spec/lib/active_record/simple_model_spec.rb
120
- - spec/lib/dual_action_spec.rb
121
- - spec/lib/scheduled_spec.rb
117
+ - spec/models/active_record/dual_action_model_spec.rb
118
+ - spec/models/active_record/simple_model_spec.rb
119
+ - spec/models/dual_action_spec.rb
120
+ - spec/models/scheduled_spec.rb
122
121
  - spec/schema.rb
123
122
  - spec/spec_helper.rb
124
123
  - urge.gemspec
@@ -149,9 +148,9 @@ test_files:
149
148
  - spec/aasm.sqlite3.db
150
149
  - spec/database.yml
151
150
  - spec/factories/factory.rb
152
- - spec/lib/active_record/dual_action_model_spec.rb
153
- - spec/lib/active_record/simple_model_spec.rb
154
- - spec/lib/dual_action_spec.rb
155
- - spec/lib/scheduled_spec.rb
151
+ - spec/models/active_record/dual_action_model_spec.rb
152
+ - spec/models/active_record/simple_model_spec.rb
153
+ - spec/models/dual_action_spec.rb
154
+ - spec/models/scheduled_spec.rb
156
155
  - spec/schema.rb
157
156
  - spec/spec_helper.rb
@@ -1,95 +0,0 @@
1
- require 'logging'
2
-
3
- module Urge
4
- module Scheduled
5
- module ClassMethods
6
-
7
- def run_all( name )
8
- now = DateTime.now
9
- logger.debug "run_all. Time now: #{now}"
10
- ready_to_run( name, now ).each do |task|
11
- logger.debug "Task of class #{task.class.name} named: #{name} is about to be run"
12
- task.run( name )
13
- end
14
- end
15
-
16
- def inspect_all( name )
17
- now = DateTime.now
18
- tasks = ready_to_run( name, now )
19
- logger.info "inspect_queue. Time now: #{now}. The following #{tasks.size} tasks are ready to run"
20
- tasks.each { |task| logger.info task.inspect }
21
- tasks
22
- end
23
-
24
- def logger
25
- @@logger ||= Logging.logger[self]
26
- end
27
-
28
- def urge_schedule( name, options = {} )
29
- logger.info "Defining schedule: #{name}. Options: #{options}. Class: #{self.name}"
30
- raise 'Cannot have two schedules with the same name' if schedules[name]
31
- schedules[name] = options
32
- end
33
-
34
- def schedules
35
- @@per_class_schedules ||= {}
36
- @@per_class_schedules[self.name] ||= {}
37
- end
38
-
39
- def attr_name( name )
40
- raise 'Non existent schedule name' if schedules[name].blank?
41
- schedules[name][:scheduled_for] || "scheduled_for_#{name}"
42
- end
43
-
44
- def all_schedules
45
- @@per_class_schedules
46
- end
47
-
48
- end
49
-
50
- module InstanceMethods
51
-
52
- def ready_to_run?( name )
53
- ts = self.send( attr_name( name ) )
54
- ts ? (DateTime.now >= ts) : false
55
- end
56
-
57
- def reschedule( name, _when )
58
- logger.debug "ScheduledTask#reschedule about to reschedule for #{_when}"
59
- self.send( "#{attr_name(name)}=", _when )
60
- end
61
-
62
- # Takes action and reschedules itself. That is all, and that is enough!
63
- def run( name, options = {} )
64
-
65
- return false unless ready_to_run?( name )
66
-
67
- logger.debug "About to call take_action_#{name}"
68
- interval = internal_take_action( name, options )
69
-
70
- logger.debug "Action taken. Calculated run interval: #{interval ? interval : 'none - task will *not* be rescheduled'}"
71
- reschedule( name, interval ? interval.from_now : nil )
72
-
73
- true
74
-
75
- end
76
-
77
- private
78
-
79
- def internal_take_action( name, options )
80
- self.send( self.class.schedules[name][:action] || "take_action_#{name}".to_sym, options )
81
- end
82
-
83
- def attr_name( name )
84
- self.class.attr_name( name )
85
- end
86
-
87
- end
88
-
89
- def self.included(base)
90
- base.extend ClassMethods
91
- base.send :include, InstanceMethods
92
- Urge::Persistence.set_persistence(base)
93
- end
94
- end
95
- end