redis-scheduler 0.2 → 0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README +8 -3
- data/lib/redis-scheduler.rb +45 -7
- metadata +3 -5
data/README
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
This is a basic chronological scheduler for Redis. It allows you to schedule
|
2
2
|
items to be processed at arbitrary points in time (via #schedule!), and then
|
3
|
-
to easily retrieve only those items that are due to be processed (via #each
|
3
|
+
to easily retrieve only those items that are due to be processed (via #each).
|
4
|
+
|
4
5
|
Items are represented as strings.
|
5
6
|
|
6
7
|
It does everything you'd want from a production scheduler:
|
7
|
-
* You can schedule
|
8
|
+
* You can schedule items at arbitrary times.
|
8
9
|
* It supports multiple simultaneous readers and writers.
|
9
10
|
* An exception causes the in-process item to be rescheduled at the original time.
|
10
|
-
* A crash leaves the item in
|
11
|
+
* A crash leaves the item in a separate error queue, from which it can later be recovered.
|
11
12
|
* You can iterate over ready items in either blocking or non-blocking mode.
|
12
13
|
|
13
14
|
In non-blocking mode (the default), #each will iterate only over those work items
|
@@ -32,6 +33,10 @@ until items are available. In blocking mode, #each will never return.
|
|
32
33
|
20.06058172: c
|
33
34
|
... waits forever ...
|
34
35
|
|
36
|
+
== Implementation
|
37
|
+
|
38
|
+
See http://masanjin.net/blog/using-redis-for-scheduling for some details.
|
39
|
+
|
35
40
|
== Bug reports
|
36
41
|
|
37
42
|
Please file bugs here: https://github.com/wmorgan/redis-scheduler/issues
|
data/lib/redis-scheduler.rb
CHANGED
@@ -5,9 +5,8 @@ class RedisScheduler
|
|
5
5
|
CAS_DELAY = 0.5 # seconds
|
6
6
|
|
7
7
|
## options:
|
8
|
-
##
|
9
|
-
##
|
10
|
-
## there are items to be processed immediately.
|
8
|
+
## * +namespace+: prefix for redis data, e.g. "scheduler/"
|
9
|
+
## * +blocking+: whether #each should block or return immediately if there are items to be processed immediately.
|
11
10
|
##
|
12
11
|
## Note that nonblocking mode may still actually block as part of the
|
13
12
|
## check-and-set semantics, i.e. block during contention from multiple
|
@@ -35,6 +34,9 @@ class RedisScheduler
|
|
35
34
|
[@queue, @error_queue, @counter].each { |k| @redis.del k }
|
36
35
|
end
|
37
36
|
|
37
|
+
def size; @redis.zcard @queue end
|
38
|
+
def error_queue_size; @redis.llen @error_queue end
|
39
|
+
|
38
40
|
## yields items along with their scheduled times. only returns items
|
39
41
|
## on or after their scheduled times. items returned as strings. if
|
40
42
|
## @blocking is false, will stop once there are no more items that can
|
@@ -42,18 +44,27 @@ class RedisScheduler
|
|
42
44
|
## become available (and never terminate).
|
43
45
|
def each
|
44
46
|
while(x = get)
|
45
|
-
item, at = x
|
47
|
+
item, erritem, at = x
|
46
48
|
begin
|
47
49
|
yield item, at
|
48
50
|
rescue Exception # back in the hole!
|
49
51
|
schedule! item, at
|
50
52
|
raise
|
51
53
|
ensure
|
52
|
-
cleanup!
|
54
|
+
cleanup! erritem
|
53
55
|
end
|
54
56
|
end
|
55
57
|
end
|
56
58
|
|
59
|
+
## returns an Enumerable of [item, schedule time] pairs, which can be used to
|
60
|
+
## easily iterate over all the items in the queue, in order of earliest- to
|
61
|
+
## latest-scheduled. note that this view is not coordinated with write
|
62
|
+
## operations, and may be inconsistent (e.g. return duplicates, miss items,
|
63
|
+
## etc).
|
64
|
+
##
|
65
|
+
## for these reasons, this operation is mainly useful for debugging purposes.
|
66
|
+
def items; ItemEnumerator.new(@redis, @queue) end
|
67
|
+
|
57
68
|
private
|
58
69
|
|
59
70
|
def get; @blocking ? blocking_get : nonblocking_get end
|
@@ -78,8 +89,8 @@ private
|
|
78
89
|
throw :cas_retry
|
79
90
|
end
|
80
91
|
item =~ /^\d+:(\S+)$/ or raise InvalidEntryException, item
|
81
|
-
|
82
|
-
[item, Time.at(at.to_f)]
|
92
|
+
original = $1
|
93
|
+
[original, item, Time.at(at.to_f)]
|
83
94
|
end
|
84
95
|
end
|
85
96
|
end
|
@@ -87,4 +98,31 @@ private
|
|
87
98
|
def cleanup! item
|
88
99
|
@redis.lrem @error_queue, 1, item
|
89
100
|
end
|
101
|
+
|
102
|
+
## enumerable for just iterating over everything in the queue
|
103
|
+
class ItemEnumerator
|
104
|
+
include Enumerable
|
105
|
+
def initialize redis, q
|
106
|
+
@redis = redis
|
107
|
+
@q = q
|
108
|
+
end
|
109
|
+
|
110
|
+
BLOCK_SIZE = 10
|
111
|
+
def each
|
112
|
+
start = 0
|
113
|
+
while start < size
|
114
|
+
elements = @redis.zrange @q, start, start + BLOCK_SIZE,
|
115
|
+
:withscores => true
|
116
|
+
elements.each_slice(2) do |item, at| # isgh
|
117
|
+
item =~ /^\d+:(\S+)$/ or raise InvalidEntryException, item
|
118
|
+
item = $1
|
119
|
+
yield item, Time.at(at.to_f)
|
120
|
+
end
|
121
|
+
start += elements.size
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def size; @redis.zcard @q end
|
126
|
+
end
|
127
|
+
|
90
128
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis-scheduler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.3'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,8 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-04-
|
13
|
-
default_executable:
|
12
|
+
date: 2012-04-29 00:00:00.000000000 Z
|
14
13
|
dependencies: []
|
15
14
|
description: A basic chronological scheduler for Redis. Add work items to be processed
|
16
15
|
at specific times in the future, and easily retrieve all items that are ready for
|
@@ -23,7 +22,6 @@ files:
|
|
23
22
|
- README
|
24
23
|
- COPYING
|
25
24
|
- lib/redis-scheduler.rb
|
26
|
-
has_rdoc: true
|
27
25
|
homepage: http://gitub.com/wmorgan/redis-scheduler
|
28
26
|
licenses: []
|
29
27
|
post_install_message:
|
@@ -48,7 +46,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
48
46
|
version: '0'
|
49
47
|
requirements: []
|
50
48
|
rubyforge_project:
|
51
|
-
rubygems_version: 1.
|
49
|
+
rubygems_version: 1.8.11
|
52
50
|
signing_key:
|
53
51
|
specification_version: 3
|
54
52
|
summary: A basic chronological scheduler for Redis.
|