uv-rays 0.2.5 → 0.2.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/uv-rays/scheduler.rb +79 -31
- data/lib/uv-rays/version.rb +1 -1
- data/spec/scheduler_spec.rb +56 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 11a2e081253e15248cae96c1f6ddeff70c72898e
|
4
|
+
data.tar.gz: d8eb1fec708fcdc68a2fb2d4a09a08e2a5e77c9b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0cb78756f4aa14503eed42df13a0a0cf0b2c1ff69e44ebb6d2104924fdeabb8184937e68b84cb68b85d789ba51bec1088c8e43e40ab22c783f885a23fd0940d7
|
7
|
+
data.tar.gz: e0a26a535f56e79edc480624c41a64d251b6ff92d206d6ded3ce9fdac412886785bbc32dfd1b441547dc94f184e26a9af7303b850c41a843edb61c9abda1a94c
|
data/lib/uv-rays/scheduler.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
module UV
|
3
3
|
|
4
4
|
class ScheduledEvent < ::Libuv::Q::DeferredPromise
|
5
|
+
# Note:: Comparable should not effect Hashes
|
6
|
+
# it will however effect arrays
|
5
7
|
include Comparable
|
6
8
|
|
7
9
|
attr_reader :created
|
@@ -26,8 +28,15 @@ module UV
|
|
26
28
|
|
27
29
|
# Provide relevant inspect information
|
28
30
|
def inspect
|
29
|
-
"#<#{self.class}:0x#{self.__id__.to_s(16)}
|
31
|
+
insp = "#<#{self.class}:0x#{self.__id__.to_s(16)} "
|
32
|
+
insp << "trigger_count=#{@trigger_count} "
|
33
|
+
insp << "config=#{info} " if self.respond_to?(:info, true)
|
34
|
+
insp << "next_scheduled=#{@next_scheduled} "
|
35
|
+
insp << "last_scheduled=#{@last_scheduled} created=#{@created}>"
|
36
|
+
insp
|
30
37
|
end
|
38
|
+
alias_method :to_s, :inspect
|
39
|
+
|
31
40
|
|
32
41
|
# required for comparable
|
33
42
|
def <=>(anOther)
|
@@ -56,7 +65,6 @@ module UV
|
|
56
65
|
# Updates the scheduled time
|
57
66
|
def update(time)
|
58
67
|
@last_scheduled = @loop.now
|
59
|
-
|
60
68
|
|
61
69
|
parsed_time = Scheduler.parse_in(time, :quiet)
|
62
70
|
if parsed_time.nil?
|
@@ -106,6 +114,7 @@ module UV
|
|
106
114
|
# can be used to reset a repeating timer
|
107
115
|
def resume
|
108
116
|
@paused = false
|
117
|
+
@last_scheduled = @loop.now
|
109
118
|
reschedule
|
110
119
|
end
|
111
120
|
|
@@ -134,11 +143,15 @@ module UV
|
|
134
143
|
end
|
135
144
|
|
136
145
|
def reschedule
|
137
|
-
|
146
|
+
unless @paused
|
138
147
|
next_time
|
139
148
|
@scheduler.reschedule(self)
|
140
149
|
end
|
141
150
|
end
|
151
|
+
|
152
|
+
def info
|
153
|
+
"repeat:#{@every}"
|
154
|
+
end
|
142
155
|
end
|
143
156
|
|
144
157
|
|
@@ -156,6 +169,9 @@ module UV
|
|
156
169
|
@timer = nil # Reference to the timer
|
157
170
|
@timer_callback = method(:on_timer)
|
158
171
|
|
172
|
+
# Not really required when used correctly
|
173
|
+
@critical = Mutex.new
|
174
|
+
|
159
175
|
# as the libuv time is taken from an arbitrary point in time we
|
160
176
|
# need to roughly synchronize between it and ruby's Time.now
|
161
177
|
@loop.update_time
|
@@ -238,41 +254,60 @@ module UV
|
|
238
254
|
# Check promise is not resolved
|
239
255
|
return if event.resolved?
|
240
256
|
|
241
|
-
|
242
|
-
|
243
|
-
@
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
257
|
+
@critical.synchronize {
|
258
|
+
# Remove the event from the scheduled list and ensure it is in the schedules set
|
259
|
+
if @schedules.include?(event)
|
260
|
+
remove(event)
|
261
|
+
else
|
262
|
+
@schedules << event
|
263
|
+
end
|
264
|
+
@next = nil if @next == event
|
248
265
|
|
249
|
-
|
250
|
-
|
266
|
+
# optimal algorithm for inserting into an already sorted list
|
267
|
+
Bisect.insort(@scheduled, event)
|
251
268
|
|
252
|
-
|
253
|
-
|
269
|
+
# Update the timer
|
270
|
+
check_timer
|
271
|
+
}
|
254
272
|
end
|
255
273
|
|
256
274
|
# Removes an event from the schedule
|
257
275
|
#
|
258
276
|
# @param event [ScheduledEvent]
|
259
277
|
def unschedule(event)
|
260
|
-
|
261
|
-
|
262
|
-
@schedules.
|
263
|
-
|
264
|
-
|
265
|
-
|
278
|
+
@critical.synchronize {
|
279
|
+
# Only call delete and update the timer when required
|
280
|
+
if @schedules.include?(event)
|
281
|
+
@schedules.delete(event)
|
282
|
+
remove(event)
|
283
|
+
check_timer
|
284
|
+
end
|
285
|
+
}
|
266
286
|
end
|
267
287
|
|
268
288
|
|
269
289
|
private
|
270
290
|
|
271
291
|
|
292
|
+
# Remove an element from the array
|
293
|
+
def remove(obj)
|
294
|
+
position = nil
|
295
|
+
|
296
|
+
@scheduled.each_index do |i|
|
297
|
+
# object level comparison
|
298
|
+
if obj.equal? @scheduled[i]
|
299
|
+
position = i
|
300
|
+
break
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
@scheduled.slice!(position) unless position.nil?
|
305
|
+
end
|
306
|
+
|
272
307
|
# First time schedule we want to bind to the promise
|
273
308
|
def schedule(event)
|
274
309
|
reschedule(event)
|
275
|
-
|
310
|
+
|
276
311
|
event.finally do
|
277
312
|
unschedule event
|
278
313
|
end
|
@@ -288,7 +323,7 @@ module UV
|
|
288
323
|
if existing != @next
|
289
324
|
# lazy load the timer
|
290
325
|
if @timer.nil?
|
291
|
-
|
326
|
+
new_timer
|
292
327
|
else
|
293
328
|
@timer.stop
|
294
329
|
end
|
@@ -309,19 +344,32 @@ module UV
|
|
309
344
|
|
310
345
|
# Is called when the libuv timer fires
|
311
346
|
def on_timer
|
312
|
-
|
313
|
-
@schedules.delete(schedule)
|
314
|
-
schedule.trigger
|
315
|
-
|
316
|
-
# execute schedules that are within 30ms of this event
|
317
|
-
# Basic timer coalescing..
|
318
|
-
now = @loop.now + 30
|
319
|
-
while @scheduled.first && @scheduled.first.next_scheduled <= now
|
347
|
+
@critical.synchronize {
|
320
348
|
schedule = @scheduled.shift
|
321
349
|
@schedules.delete(schedule)
|
322
350
|
schedule.trigger
|
351
|
+
|
352
|
+
# execute schedules that are within 30ms of this event
|
353
|
+
# Basic timer coalescing..
|
354
|
+
now = @loop.now + 30
|
355
|
+
while @scheduled.first && @scheduled.first.next_scheduled <= now
|
356
|
+
schedule = @scheduled.shift
|
357
|
+
@schedules.delete(schedule)
|
358
|
+
schedule.trigger
|
359
|
+
end
|
360
|
+
check_timer
|
361
|
+
}
|
362
|
+
end
|
363
|
+
|
364
|
+
# Provide some assurances on timer failure
|
365
|
+
def new_timer
|
366
|
+
@timer = @loop.timer @timer_callback
|
367
|
+
@timer.finally do
|
368
|
+
new_timer
|
369
|
+
unless @next.nil?
|
370
|
+
@timer.start(@next)
|
371
|
+
end
|
323
372
|
end
|
324
|
-
check_timer
|
325
373
|
end
|
326
374
|
end
|
327
375
|
end
|
data/lib/uv-rays/version.rb
CHANGED
data/spec/scheduler_spec.rb
CHANGED
@@ -32,7 +32,8 @@ describe UV::Scheduler do
|
|
32
32
|
expect(@general_failure).to eq([])
|
33
33
|
expect(@event).to eq(@result)
|
34
34
|
@diff = @triggered_at - @event.last_scheduled
|
35
|
-
expect(
|
35
|
+
expect(@diff).to be >= 500
|
36
|
+
expect(@diff).to be < 750
|
36
37
|
end
|
37
38
|
|
38
39
|
it "should be able to schedule a one shot event using 'at'" do
|
@@ -55,7 +56,8 @@ describe UV::Scheduler do
|
|
55
56
|
expect(@general_failure).to eq([])
|
56
57
|
expect(@event).to eq(@result)
|
57
58
|
@diff = @triggered_at - @event.last_scheduled
|
58
|
-
expect(
|
59
|
+
expect(@diff).to be >= 1000
|
60
|
+
expect(@diff).to be < 1250
|
59
61
|
end
|
60
62
|
|
61
63
|
it "should be able to schedule a repeat event" do
|
@@ -73,6 +75,10 @@ describe UV::Scheduler do
|
|
73
75
|
@triggered_at = triggered
|
74
76
|
@result = event
|
75
77
|
|
78
|
+
diff = triggered - event.last_scheduled
|
79
|
+
expect(diff).to be >= 250
|
80
|
+
expect(diff).to be < 500
|
81
|
+
|
76
82
|
@run += 1
|
77
83
|
if @run == 2
|
78
84
|
@event.pause
|
@@ -84,7 +90,53 @@ describe UV::Scheduler do
|
|
84
90
|
expect(@general_failure).to eq([])
|
85
91
|
expect(@run).to eq(2)
|
86
92
|
expect(@event).to eq(@result)
|
87
|
-
|
88
|
-
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should be able to cancel an event" do
|
96
|
+
# Also tests events run in order of scheduled
|
97
|
+
# Also tests events are not inadvertently canceled by other test
|
98
|
+
@loop.run { |logger|
|
99
|
+
logger.progress do |level, errorid, error|
|
100
|
+
begin
|
101
|
+
@general_failure << "Log called: #{level}: #{errorid}\n#{error.message}\n#{error.backtrace.join("\n")}\n"
|
102
|
+
rescue Exception
|
103
|
+
@general_failure << 'error in logger'
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
@triggered = []
|
108
|
+
|
109
|
+
@event1 = @scheduler.in('0.5s') do |triggered, event|
|
110
|
+
@triggered << 1
|
111
|
+
end
|
112
|
+
|
113
|
+
@event2 = @scheduler.in('0.5s') do |triggered, event|
|
114
|
+
@triggered << 2
|
115
|
+
end
|
116
|
+
|
117
|
+
@event3 = @scheduler.in('0.5s') do |triggered, event|
|
118
|
+
@triggered << 3
|
119
|
+
@loop.stop
|
120
|
+
end
|
121
|
+
|
122
|
+
@scheduled, @schedules = @scheduler.instance_eval {
|
123
|
+
[@scheduled, @schedules]
|
124
|
+
}
|
125
|
+
|
126
|
+
expect(@scheduled.size).to eq(3)
|
127
|
+
expect(@schedules.size).to eq(3)
|
128
|
+
|
129
|
+
@event2.cancel
|
130
|
+
|
131
|
+
@loop.next_tick do
|
132
|
+
expect(@scheduled.size).to eq(2)
|
133
|
+
expect(@schedules.size).to eq(2)
|
134
|
+
end
|
135
|
+
}
|
136
|
+
|
137
|
+
expect(@general_failure).to eq([])
|
138
|
+
expect(@triggered).to eq([1, 3])
|
139
|
+
expect(@scheduled.size).to eq(0)
|
140
|
+
expect(@schedules.size).to eq(0)
|
89
141
|
end
|
90
142
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uv-rays
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen von Takach
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-07-
|
11
|
+
date: 2014-07-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: libuv
|