urge 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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