clockwork 0.7.4 → 0.7.5

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,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bb04c64391be1de07e805c05256430c06c1d0da6
4
- data.tar.gz: 3804849a9e343ce52d62609390da392ccb2c6274
3
+ metadata.gz: fe114a0ae00c9b51086eed10fa3f2cf24cbbbda8
4
+ data.tar.gz: bf37628fb300af8eee5a21e64ceaf54c625c6e41
5
5
  SHA512:
6
- metadata.gz: d3adf3511969f14520a4d3273dbf3555d690a8a2cb467e217825ce66f8cae9d8cae3c1431f31784ff987061c6acff1c8e081b91bebac858e96ac8013d071a67d
7
- data.tar.gz: 06a2920e423ecf3f656b2b5f10ad5a8a32cf5bff46a55a12416b94f77bd484b3bf443a3cfdde7267e89a011cc282ef2580ae883191b167918f23cc6e9383c833
6
+ metadata.gz: 86fe430ba1581ae9fad955fc603ca72cd534cf79992fb6c7835da5a32de45065e3c1412fb748d0bae6c5fb208b4c660661ca06357a54ffa071377b5327e5bc25
7
+ data.tar.gz: b19a6327cc02f83a875cfcb0465eb9e0fb050741007817ec5c7085a1a00a3c184f010bd7beba8bd25188e3d1e0e225c63901af28c90319bc37e2236f2794f049
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "clockwork"
3
- s.version = "0.7.4"
3
+ s.version = "0.7.5"
4
4
 
5
5
  s.authors = ["Adam Wiggins", "tomykaira"]
6
6
  s.license = 'MIT'
@@ -1,5 +1,14 @@
1
1
  module Clockwork
2
2
 
3
+ # add equality testing to At
4
+ class At
5
+ attr_reader :min, :hour, :wday
6
+
7
+ def == other
8
+ @min == other.min && @hour == other.hour && @wday == other.wday
9
+ end
10
+ end
11
+
3
12
  module Methods
4
13
  def sync_database_tasks(options={}, &block)
5
14
  Clockwork.manager.sync_database_tasks(options, &block)
@@ -25,30 +34,34 @@ module Clockwork
25
34
  @model.all.each do |db_task|
26
35
  model_ids_that_exist << db_task.id
27
36
 
28
- if !event_exists_for_task(db_task) || db_task_has_changed(db_task)
29
- create_event_for_database_task(db_task)
37
+ if !event_exists_for_task(db_task) || task_has_changed(db_task)
38
+ recreate_event_for_database_task(db_task)
30
39
  end
31
40
  end
32
41
 
33
42
  remove_deleted_database_tasks(model_ids_that_exist)
34
43
  end
35
44
 
36
- def events
37
- @events.values
45
+ def clockwork_events
46
+ @events.values.flatten
38
47
  end
39
48
 
49
+ # store events by task_id in array (array is needed as there is 1 event per At)
40
50
  def add_event(e, task_id)
41
- @events[task_id] = e
51
+ @events[task_id] ||= []
52
+ @events[task_id] << e
42
53
  end
43
54
 
44
55
  protected
45
56
 
46
- def create_event_for_database_task(db_task)
57
+ def recreate_event_for_database_task(db_task)
58
+ @events[db_task.id] = nil
59
+
47
60
  options = {
48
61
  :from_database => true,
49
62
  :db_task_id => db_task.id,
50
63
  :performer => self,
51
- :at => db_task.at.blank? ? nil : db_task.at.split(',')
64
+ :at => array_of_ats_for(db_task, :nil_if_empty => true)
52
65
  }
53
66
 
54
67
  @manager.every db_task.frequency, db_task.name, options, &@block
@@ -62,9 +75,33 @@ module Clockwork
62
75
  @events.reject!{|db_task_id, _| !model_ids_that_exist.include?(db_task_id) }
63
76
  end
64
77
 
65
- def db_task_has_changed(task)
66
- event = @events[task.id]
67
- task.name != event.job || task.frequency != event.instance_variable_get(:@period)
78
+ def task_has_changed(task)
79
+ events = @events[task.id]
80
+ event = @events[task.id].first # all events will have same frequency/name, just different ats
81
+ ats_for_task = array_of_ats_for(task)
82
+ ats_from_event = array_of_ats_from_event(task.id)
83
+
84
+ name_has_changed = task.name != event.job
85
+ frequency_has_changed = task.frequency != event.instance_variable_get(:@period)
86
+
87
+ at_has_changed = ats_for_task.length != ats_from_event.length
88
+ at_has_changed ||= ats_for_task.inject(false) do |memo, at|
89
+ memo ||= !ats_from_event.include?(At.parse(at))
90
+ end
91
+
92
+ name_has_changed || frequency_has_changed || at_has_changed
93
+ end
94
+
95
+ def array_of_ats_from_event(task_id)
96
+ @events[task_id].collect{|clockwork_event| clockwork_event.instance_variable_get(:@at) }.compact
97
+ end
98
+
99
+ def array_of_ats_for(task, opts={})
100
+ if task.at.nil?
101
+ opts[:nil_if_empty] ? nil : []
102
+ else
103
+ task.at.split(',').map(&:strip)
104
+ end
68
105
  end
69
106
  end
70
107
 
@@ -93,7 +130,7 @@ module Clockwork
93
130
  private
94
131
 
95
132
  def events_from_database_as_array
96
- @database_event_sync_performers.collect{|performer| performer.events}.flatten
133
+ @database_event_sync_performers.collect{|performer| performer.clockwork_events}.flatten
97
134
  end
98
135
 
99
136
  def events_to_run(t)
@@ -19,6 +19,20 @@ class ManagerWithDatabaseTasksTest < Test::Unit::TestCase
19
19
  @manager.handler { }
20
20
  end
21
21
 
22
+ def assert_will_run(t)
23
+ if t.is_a? String
24
+ t = Time.parse(t)
25
+ end
26
+ assert_equal 1, @manager.tick(t).size
27
+ end
28
+
29
+ def assert_wont_run(t)
30
+ if t.is_a? String
31
+ t = Time.parse(t)
32
+ end
33
+ assert_equal 0, @manager.tick(t).size
34
+ end
35
+
22
36
  def tick_at(now = Time.now, options = {})
23
37
  seconds_to_tick_for = options[:and_every_second_for] || 0
24
38
  number_of_ticks = seconds_to_tick_for + 1 # add one for right now
@@ -139,21 +153,42 @@ class ManagerWithDatabaseTasksTest < Test::Unit::TestCase
139
153
  assert_equal before, after
140
154
  end
141
155
 
142
- def test_edited_tasks_switch_to_new_settings
156
+ def test_task_with_edited_name_switches_to_new_name
143
157
  tick_at @now, :and_every_second_for => @database_reload_frequency.seconds - 1.second
158
+ @tasks_run = [] # clear tasks run before change
159
+
144
160
  modified_task_1 = stub(:frequency => 30, :name => 'ScheduledTask:1_modified', :at => nil, :id => 1)
145
161
  ScheduledTask.stubs(:all).returns([modified_task_1])
146
162
  tick_at @now + @database_reload_frequency.seconds, :and_every_second_for => @database_reload_frequency.seconds - 1.seconds
147
- assert_equal [
148
- "ScheduledTask:1",
149
- "ScheduledTask:1",
150
- "ScheduledTask:1",
151
- "ScheduledTask:1",
152
- "ScheduledTask:1",
153
- "ScheduledTask:1",
154
- "ScheduledTask:1_modified",
155
- "ScheduledTask:1_modified"
156
- ], @tasks_run
163
+
164
+ assert_equal ["ScheduledTask:1_modified", "ScheduledTask:1_modified"], @tasks_run
165
+ end
166
+
167
+ def test_task_with_edited_frequency_switches_to_new_frequency
168
+ tick_at @now, :and_every_second_for => @database_reload_frequency.seconds - 1.second
169
+ @tasks_run = [] # clear tasks run before change
170
+
171
+ modified_task_1 = stub(:frequency => 30, :name => 'ScheduledTask:1', :at => nil, :id => 1)
172
+ ScheduledTask.stubs(:all).returns([modified_task_1])
173
+ tick_at @now + @database_reload_frequency.seconds, :and_every_second_for => @database_reload_frequency.seconds - 1.seconds
174
+
175
+ assert_equal 2, @tasks_run.length
176
+ end
177
+
178
+ def test_task_with_edited_at_runs_at_new_at
179
+ task_1 = stub(:frequency => 1.day, :name => 'ScheduledTask:1', :at => '10:30', :id => 1)
180
+ ScheduledTask.stubs(:all).returns([task_1])
181
+
182
+ assert_will_run 'jan 1 2010 10:30:00'
183
+ assert_wont_run 'jan 1 2010 09:30:00'
184
+ tick_at @now, :and_every_second_for => @database_reload_frequency.seconds - 1.second
185
+
186
+ modified_task_1 = stub(:frequency => 1.day, :name => 'ScheduledTask:1', :at => '09:30', :id => 1)
187
+ ScheduledTask.stubs(:all).returns([modified_task_1])
188
+ tick_at @now + @database_reload_frequency.seconds, :and_every_second_for => @database_reload_frequency.seconds - 1.seconds
189
+
190
+ assert_will_run 'jan 1 2010 09:30:00'
191
+ assert_wont_run 'jan 1 2010 10:30:00'
157
192
  end
158
193
 
159
194
  def test_daily_task_with_at_should_only_run_once
@@ -168,6 +203,21 @@ class ManagerWithDatabaseTasksTest < Test::Unit::TestCase
168
203
  assert_equal 1, @tasks_run.length
169
204
  end
170
205
 
206
+ def test_comma_separated_at_from_task_leads_to_multiple_event_ats
207
+ task = stub(:frequency => 1.day, :name => 'ScheduledTask:1', :at => '16:20, 18:10', :id => 1)
208
+ ScheduledTask.stubs(:all).returns([task])
209
+
210
+ tick_at @now, :and_every_second_for => @database_reload_frequency.seconds
211
+
212
+ assert_wont_run 'jan 1 2010 16:19:59'
213
+ assert_will_run 'jan 1 2010 16:20:00'
214
+ assert_wont_run 'jan 1 2010 16:20:01'
215
+
216
+ assert_wont_run 'jan 1 2010 18:09:59'
217
+ assert_will_run 'jan 1 2010 18:10:00'
218
+ assert_wont_run 'jan 1 2010 18:10:01'
219
+ end
220
+
171
221
  def test_having_multiple_sync_database_tasks_will_work
172
222
  ScheduledTask.stubs(:all).returns([@scheduled_task1])
173
223
 
@@ -204,8 +254,6 @@ class ManagerWithDatabaseTasksTest < Test::Unit::TestCase
204
254
  end
205
255
  end
206
256
 
207
- # For example: if the manager updates every minute, but the task specifies 5 minutes,
208
- # the task will still run every minute.
209
257
  def test_it_only_runs_the_task_once_within_the_task_frequency_period
210
258
  tick_at(@now, :and_every_second_for => 5.minutes)
211
259
  assert_equal 1, @tasks_run.length
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clockwork
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.4
4
+ version: 0.7.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Wiggins
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-04-14 00:00:00.000000000 Z
12
+ date: 2014-04-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: tzinfo