periodic-scheduler 0.5.0 → 0.6.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.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.0
1
+ 0.6.0
@@ -27,16 +27,22 @@ class PeriodicScheduler
27
27
  attr_reader :keep
28
28
  attr_reader :callback
29
29
 
30
- def initialize(quantized_space, period, keep, &callback)
30
+ def initialize(quantized_space, now, period, keep, &callback)
31
31
  @quantized_space = quantized_space
32
32
  @period = period
33
+ @run_time = now + period
33
34
  @keep = keep
34
35
  @callback = callback
35
36
  quantatize(period)
36
37
  end
37
38
 
38
- def reschedule
39
- quantatize(@period + @quantum_error)
39
+ def reschedule(qnow)
40
+ # keep rescheduling until we get it scheduled in future quant
41
+ until @quantum_period > qnow
42
+ @run_time += @period
43
+ quantatize(@run_time)
44
+ end
45
+
40
46
  @reschedule_hook.call(self) if @reschedule_hook
41
47
  end
42
48
 
@@ -70,7 +76,6 @@ class PeriodicScheduler
70
76
 
71
77
  def quantatize(period)
72
78
  @quantum_period = @quantized_space.project(period)
73
- @quantum_error = @quantized_space.projection_error(period)
74
79
  end
75
80
  end
76
81
 
@@ -89,11 +94,11 @@ class PeriodicScheduler
89
94
  end
90
95
 
91
96
  def after(period, &callback)
92
- schedule_event Event.new(@quantized_space, period, false, &callback)
97
+ schedule_event Event.new(@quantized_space, real_now, period, false, &callback)
93
98
  end
94
99
 
95
100
  def every(period, &callback)
96
- schedule_event Event.new(@quantized_space, period, true, &callback)
101
+ schedule_event Event.new(@quantized_space, real_now, period, true, &callback)
97
102
  end
98
103
 
99
104
  def run!(&block)
@@ -110,16 +115,7 @@ class PeriodicScheduler
110
115
  raise EmptyScheduleError, "no events scheduled" unless earliest_quant
111
116
 
112
117
  wait_time = @quantized_space.revers_project(earliest_quant) - real_now
113
- if wait_time < 0
114
- # we have missed our scheduled period
115
- begin
116
- # we raise it so it has proper content (backtrace)
117
- raise MissedScheduleError.new("missed schedule by #{-wait_time} seconds")
118
- rescue StandardError => error
119
- yield error if block_given?
120
- end
121
- wait_time = 0
122
- end
118
+ wait_time = 0 if wait_time < 0
123
119
  wait(wait_time)
124
120
 
125
121
  objects = []
@@ -129,6 +125,16 @@ class PeriodicScheduler
129
125
  # move quants to be run away to separate array
130
126
  quants = @events.keys.select{|k| k <= qnow}.sort.map{|q| @events.delete(q)}
131
127
 
128
+ # we have missed one or more scheduled quants
129
+ if quants.length > 1
130
+ begin
131
+ # we raise it so it has proper backtrace
132
+ raise MissedScheduleError.new("missed schedule by #{-wait_time} seconds")
133
+ rescue StandardError => error
134
+ yield error if block_given?
135
+ end
136
+ end
137
+
132
138
  # Call callback for every quant and reschedule if needed
133
139
  quants.each do |events|
134
140
  # get all events for quantum that are not stopped
@@ -139,7 +145,7 @@ class PeriodicScheduler
139
145
  # Yield errors to block
140
146
  yield error if block_given?
141
147
  end
142
- e.reschedule if e.keep? and not e.stopped?
148
+ e.reschedule(quantized_now) if e.keep? and not e.stopped?
143
149
  end
144
150
  end
145
151
 
@@ -153,13 +159,13 @@ class PeriodicScheduler
153
159
 
154
160
  private
155
161
 
156
- def schedule_event(event, from = quantized_now)
157
- quant = from + event.quantum_period
162
+ def schedule_event(event)
163
+ quant = event.quantum_period
158
164
  (@events[quant] ||= []) << event
159
165
 
160
166
  event.reschedule_hook do |event|
161
167
  unschedule_event(event, quant)
162
- schedule_event(event, quant)
168
+ schedule_event(event)
163
169
  end
164
170
 
165
171
  event.stop_hook do |event|
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "periodic-scheduler"
8
- s.version = "0.5.0"
8
+ s.version = "0.6.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jakub Pastuszek"]
12
- s.date = "2012-11-03"
12
+ s.date = "2012-11-06"
13
13
  s.description = "Controls execution of periodic scheduled tasks."
14
14
  s.email = "jpastuszek@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -275,7 +275,7 @@ describe PeriodicScheduler do
275
275
  @time_now.should == 3
276
276
  end
277
277
 
278
- it "should execut all not reschedulable tasks if we miss them" do
278
+ it "should not miss any scheduled tasks" do
279
279
  s = PeriodicScheduler.new(5.0, @options)
280
280
 
281
281
  s.after(15) do
@@ -286,7 +286,7 @@ describe PeriodicScheduler do
286
286
  @got_event.call(2)
287
287
  end
288
288
 
289
- s.after(45) do
289
+ s.after(40) do
290
290
  @got_event.call(3)
291
291
  end
292
292
 
@@ -299,21 +299,34 @@ describe PeriodicScheduler do
299
299
  @got_events.should == [1, 2, 3]
300
300
  end
301
301
 
302
- it "should skpi reschedulable tasks if we miss them" do
303
- #TODO: this behaviour is a bit of gary area
304
- s = PeriodicScheduler.new(5.0, @options)
302
+ it "should call reschedulable tasks only once every run" do
303
+ s = PeriodicScheduler.new(5.0, @options)
305
304
 
306
- s.every(15) do
307
- @got_event.call(1)
308
- end
305
+ s.every(15) do
306
+ @got_event.call(1)
307
+ end
309
308
 
310
- @options[:wait_function].call(35)
309
+ s.every(30) do
310
+ @got_event.call(2)
311
+ end
311
312
 
312
- s.run.should
313
- @got_events.should == [1]
313
+ s.every(40) do
314
+ @got_event.call(3)
315
+ end
314
316
 
315
- s.run.should
316
- @got_events.should == [1, 1]
317
+ @options[:wait_function].call(35)
318
+
319
+ # 15, 30 executed, 15 -> 45
320
+ s.run.should
321
+ @got_events.should == [1, 2]
322
+
323
+ # 40
324
+ s.run.should
325
+ @got_events.should == [1, 2, 3]
326
+
327
+ # 45
328
+ s.run.should
329
+ @got_events.should == [1, 2, 3, 1]
317
330
  end
318
331
 
319
332
  it "should report error if the schedule was missed" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: periodic-scheduler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-03 00:00:00.000000000 Z
12
+ date: 2012-11-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70289045852440 !ruby/object:Gem::Requirement
16
+ requirement: &70222808986940 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 2.8.0
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70289045852440
24
+ version_requirements: *70222808986940
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rdoc
27
- requirement: &70289045851420 !ruby/object:Gem::Requirement
27
+ requirement: &70222808986460 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '3.12'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70289045851420
35
+ version_requirements: *70222808986460
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: cucumber
38
- requirement: &70289045850520 !ruby/object:Gem::Requirement
38
+ requirement: &70222808985980 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70289045850520
46
+ version_requirements: *70222808985980
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: bundler
49
- requirement: &70289045849460 !ruby/object:Gem::Requirement
49
+ requirement: &70222808985500 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.0.0
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70289045849460
57
+ version_requirements: *70222808985500
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: jeweler
60
- requirement: &70289045848140 !ruby/object:Gem::Requirement
60
+ requirement: &70222808985020 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 1.8.3
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70289045848140
68
+ version_requirements: *70222808985020
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rcov
71
- requirement: &70289045847660 !ruby/object:Gem::Requirement
71
+ requirement: &70222808984540 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,7 +76,7 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70289045847660
79
+ version_requirements: *70222808984540
80
80
  description: Controls execution of periodic scheduled tasks.
81
81
  email: jpastuszek@gmail.com
82
82
  executables: []
@@ -112,7 +112,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
112
112
  version: '0'
113
113
  segments:
114
114
  - 0
115
- hash: -3007109713831198216
115
+ hash: -3759462292764613282
116
116
  required_rubygems_version: !ruby/object:Gem::Requirement
117
117
  none: false
118
118
  requirements: