later 0.1.0 → 0.1.1
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/later.gemspec +1 -0
- data/lib/later.rb +38 -15
- data/lib/later/version.rb +1 -1
- data/test/helper.rb +2 -2
- data/test/lib/later.rb +36 -7
- metadata +18 -2
data/later.gemspec
CHANGED
data/lib/later.rb
CHANGED
@@ -1,13 +1,10 @@
|
|
1
1
|
require 'later/version'
|
2
2
|
require 'redis'
|
3
3
|
require 'nest'
|
4
|
+
require 'json'
|
4
5
|
|
5
6
|
module Later
|
6
7
|
class Schedule
|
7
|
-
def key
|
8
|
-
@key
|
9
|
-
end
|
10
|
-
|
11
8
|
def initialize(key)
|
12
9
|
if key.is_a?(Nest)
|
13
10
|
@key = key
|
@@ -16,6 +13,14 @@ module Later
|
|
16
13
|
end
|
17
14
|
end
|
18
15
|
|
16
|
+
def key
|
17
|
+
@key
|
18
|
+
end
|
19
|
+
|
20
|
+
def exceptions
|
21
|
+
@exceptions ||= key[:exceptions]
|
22
|
+
end
|
23
|
+
|
19
24
|
def [](event)
|
20
25
|
Time.at key[:schedule].zscore(event) rescue nil
|
21
26
|
end
|
@@ -44,24 +49,42 @@ module Later
|
|
44
49
|
|
45
50
|
time = Time.now.to_i
|
46
51
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
ids =
|
52
|
+
schedule.redis.multi
|
53
|
+
schedule.zrangebyscore '-inf', time
|
54
|
+
schedule.zremrangebyscore '-inf', time
|
55
|
+
ids = schedule.redis.exec.first
|
51
56
|
|
52
|
-
key.redis.
|
53
|
-
|
54
|
-
|
55
|
-
end
|
56
|
-
end
|
57
|
+
key.redis.multi
|
58
|
+
ids.each { |id| queue.lpush id }
|
59
|
+
key.redis.exec
|
57
60
|
|
58
|
-
event =
|
61
|
+
event = queue.brpoplpush(backup, 1)
|
59
62
|
|
60
63
|
next unless event
|
61
64
|
|
62
|
-
|
65
|
+
begin
|
66
|
+
block.call event
|
67
|
+
rescue Exception => e
|
68
|
+
exceptions.rpush JSON(time: Time.now, event: event, message: e.inspect)
|
69
|
+
ensure
|
70
|
+
backup.del
|
71
|
+
end
|
63
72
|
end
|
64
73
|
end
|
74
|
+
|
75
|
+
protected
|
76
|
+
|
77
|
+
def schedule
|
78
|
+
@schedule ||= key[:schedule]
|
79
|
+
end
|
80
|
+
|
81
|
+
def queue
|
82
|
+
@queue ||= key[:queue]
|
83
|
+
end
|
84
|
+
|
85
|
+
def backup
|
86
|
+
@backup ||= queue[Socket.gethostname][Process.pid]
|
87
|
+
end
|
65
88
|
end
|
66
89
|
|
67
90
|
@schedules = {}
|
data/lib/later/version.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -6,12 +6,12 @@ class MiniTest::Unit::TestCase
|
|
6
6
|
def setup
|
7
7
|
system 'redis-server', File.join(File.dirname(__FILE__), 'redis.conf')
|
8
8
|
until File.exist? 'redis.pid'
|
9
|
-
sleep 1
|
9
|
+
sleep 0.1
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
13
|
def teardown
|
14
14
|
system "kill `cat redis.pid`"
|
15
|
-
sleep 1
|
15
|
+
sleep 0.1
|
16
16
|
end
|
17
17
|
end
|
data/test/lib/later.rb
CHANGED
@@ -30,25 +30,25 @@ class LaterTest < MiniTest::Unit::TestCase
|
|
30
30
|
def test_count_set_and_unset_event_schedules
|
31
31
|
time = Time.now
|
32
32
|
|
33
|
-
1.upto(
|
33
|
+
1.upto(3) do |i|
|
34
34
|
Later[@key].set i.to_s, time
|
35
35
|
assert_equal i, Later[@key].count
|
36
36
|
end
|
37
37
|
|
38
|
-
1.upto(
|
38
|
+
1.upto(3) do |i|
|
39
39
|
Later[@key].unset i.to_s
|
40
|
-
assert_equal
|
40
|
+
assert_equal 3 - i, Later[@key].count
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
44
|
def test_process_many_event_schedules
|
45
|
-
start = Time.now +
|
45
|
+
start = Time.now + 2
|
46
46
|
|
47
47
|
times = []
|
48
48
|
schedules = Hash.new { |h,k| h[k] = [] }
|
49
49
|
|
50
|
-
1.upto(
|
51
|
-
time = start + i /
|
50
|
+
1.upto(100) do |i|
|
51
|
+
time = start + i / 10
|
52
52
|
times.unshift time
|
53
53
|
schedules[time].unshift event: i.to_s, time: time
|
54
54
|
end
|
@@ -58,7 +58,7 @@ class LaterTest < MiniTest::Unit::TestCase
|
|
58
58
|
end
|
59
59
|
|
60
60
|
Thread.new do
|
61
|
-
sleep
|
61
|
+
sleep 2 + 10 + (start - Time.now).to_i
|
62
62
|
Later[@key].stop
|
63
63
|
end
|
64
64
|
|
@@ -71,4 +71,33 @@ class LaterTest < MiniTest::Unit::TestCase
|
|
71
71
|
|
72
72
|
assert_equal 0, Later[@key].count
|
73
73
|
end
|
74
|
+
|
75
|
+
def test_exceptions_raised_within_the_worker_loop_are_handled_and_logged
|
76
|
+
start = Time.now + 2
|
77
|
+
|
78
|
+
1.upto(3) do |i|
|
79
|
+
Later[@key].set i.to_s, start + i
|
80
|
+
end
|
81
|
+
|
82
|
+
Thread.new do
|
83
|
+
sleep 2 + 3 + (start - Time.now).to_i
|
84
|
+
Later[@key].stop
|
85
|
+
end
|
86
|
+
|
87
|
+
Later[@key].each do |event|
|
88
|
+
raise Exception, "an unknown error for #{event} has occurred"
|
89
|
+
end
|
90
|
+
|
91
|
+
assert_equal 0, Later[@key].count
|
92
|
+
|
93
|
+
exceptions = Later[@key].exceptions.lrange 0, -1
|
94
|
+
exceptions = exceptions.map{ |e| JSON(e) }
|
95
|
+
|
96
|
+
assert_equal '1', exceptions[0]['event']
|
97
|
+
assert_equal '#<Exception: an unknown error for 1 has occurred>', exceptions[0]['message']
|
98
|
+
assert_equal '2', exceptions[1]['event']
|
99
|
+
assert_equal '#<Exception: an unknown error for 2 has occurred>', exceptions[1]['message']
|
100
|
+
assert_equal '3', exceptions[2]['event']
|
101
|
+
assert_equal '#<Exception: an unknown error for 3 has occurred>', exceptions[2]['message']
|
102
|
+
end
|
74
103
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: later
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-08-
|
12
|
+
date: 2012-08-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: redis
|
@@ -43,6 +43,22 @@ dependencies:
|
|
43
43
|
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: json
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
46
62
|
- !ruby/object:Gem::Dependency
|
47
63
|
name: minitest
|
48
64
|
requirement: !ruby/object:Gem::Requirement
|