uv-rays 0.2.5 → 0.2.6
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 +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
|