resque-dynamic-queues 0.6.1 → 0.7.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/CHANGELOG +6 -0
- data/config.ru +9 -0
- data/lib/resque-dynamic-queues-server.rb +3 -1
- data/lib/resque/plugins/dynamic_queues/attributes.rb +23 -13
- data/lib/resque/plugins/dynamic_queues/server.rb +33 -14
- data/lib/resque/plugins/dynamic_queues/server/views/queues.erb +48 -45
- data/lib/resque/plugins/dynamic_queues/version.rb +1 -1
- data/spec/queues_spec.rb +36 -0
- data/spec/server_spec.rb +28 -18
- metadata +9 -8
data/CHANGELOG
CHANGED
data/config.ru
ADDED
@@ -2,40 +2,50 @@ module Resque
|
|
2
2
|
module Plugins
|
3
3
|
module DynamicQueues
|
4
4
|
|
5
|
-
|
5
|
+
DYNAMIC_QUEUE_KEY = "dynamic_queue"
|
6
6
|
FALLBACK_KEY = "default"
|
7
7
|
|
8
8
|
module Attributes
|
9
9
|
|
10
|
-
def get_dynamic_queue(key)
|
11
|
-
|
10
|
+
def get_dynamic_queue(key, fallback=['*'])
|
11
|
+
data = redis.hget(DYNAMIC_QUEUE_KEY, key)
|
12
|
+
queue_names = Resque.decode(data)
|
12
13
|
|
13
14
|
if queue_names.nil? || queue_names.size == 0
|
14
|
-
|
15
|
+
data = redis.hget(DYNAMIC_QUEUE_KEY, FALLBACK_KEY)
|
16
|
+
queue_names = Resque.decode(data)
|
15
17
|
end
|
16
18
|
|
17
19
|
if queue_names.nil? || queue_names.size == 0
|
18
|
-
queue_names =
|
20
|
+
queue_names = fallback
|
19
21
|
end
|
20
22
|
|
21
23
|
return queue_names
|
22
24
|
end
|
23
25
|
|
24
26
|
def set_dynamic_queue(key, values)
|
25
|
-
|
27
|
+
if values.nil? or values.size == 0
|
28
|
+
redis.hdel(DYNAMIC_QUEUE_KEY, key)
|
29
|
+
else
|
30
|
+
redis.hset(DYNAMIC_QUEUE_KEY, key, Resque.encode(values))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def set_dynamic_queues(dynamic_queues)
|
26
35
|
redis.multi do
|
27
|
-
redis.del(
|
28
|
-
|
29
|
-
|
36
|
+
redis.del(DYNAMIC_QUEUE_KEY)
|
37
|
+
dynamic_queues.each do |k, v|
|
38
|
+
set_dynamic_queue(k, v)
|
30
39
|
end
|
31
40
|
end
|
32
41
|
end
|
33
42
|
|
34
43
|
def get_dynamic_queues
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
44
|
+
result = {}
|
45
|
+
queues = redis.hgetall(DYNAMIC_QUEUE_KEY)
|
46
|
+
queues.each {|k, v| result[k] = Resque.decode(v) }
|
47
|
+
result[FALLBACK_KEY] ||= ['*']
|
48
|
+
return result
|
39
49
|
end
|
40
50
|
|
41
51
|
end
|
@@ -9,25 +9,46 @@ module Resque
|
|
9
9
|
|
10
10
|
def self.registered(app)
|
11
11
|
app.get "/dynamicqueues" do
|
12
|
-
@queues =
|
13
|
-
|
12
|
+
@queues = []
|
13
|
+
dqueues = Resque.get_dynamic_queues
|
14
|
+
dqueues.each do |k, v|
|
15
|
+
view_data = {
|
16
|
+
'name' => k,
|
17
|
+
'value' => Array(v).join(", "),
|
18
|
+
'expanded' => Resque::Worker.new("@#{k}").queues.join(", ")
|
19
|
+
}
|
20
|
+
@queues << view_data
|
21
|
+
end
|
22
|
+
|
23
|
+
@queues.sort! do |a, b|
|
24
|
+
an = a['name']
|
25
|
+
bn = b['name']
|
26
|
+
if an == 'default'
|
27
|
+
1
|
28
|
+
elsif bn == 'default'
|
29
|
+
-1
|
30
|
+
else
|
31
|
+
an <=> bn
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
plugin_view :queues
|
14
36
|
end
|
15
37
|
|
16
38
|
app.post "/dynamicqueues" do
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
Resque.set_dynamic_queue(key, [])
|
39
|
+
dynamic_queues = Array(params['queues'])
|
40
|
+
queues = {}
|
41
|
+
dynamic_queues.each do |queue|
|
42
|
+
key = queue['name']
|
43
|
+
values = queue['value'].to_s.split(',').collect{|q| q.gsub(/\s/, '') }
|
44
|
+
queues[key] = values
|
45
|
+
end
|
46
|
+
Resque.set_dynamic_queues(queues)
|
26
47
|
redirect url(:dynamicqueues)
|
27
48
|
end
|
28
49
|
|
29
50
|
app.helpers do
|
30
|
-
def
|
51
|
+
def plugin_view(filename, options = {}, locals = {})
|
31
52
|
erb(File.read(File.join(::Resque::Plugins::DynamicQueues::Server::VIEW_PATH, "#{filename}.erb")), options, locals)
|
32
53
|
end
|
33
54
|
end
|
@@ -38,5 +59,3 @@ module Resque
|
|
38
59
|
end
|
39
60
|
end
|
40
61
|
end
|
41
|
-
|
42
|
-
Resque::Server.register Resque::Plugins::DynamicQueues::Server
|
@@ -1,58 +1,61 @@
|
|
1
1
|
<h1>Dynamic Queues</h1>
|
2
|
-
<
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
</tr>
|
10
|
-
<% @queues.each do |queue| %>
|
2
|
+
<p class="intro">
|
3
|
+
The list below shows the dynamic queues currently defined. When you start a worker with a dynamic queue key (@key_name), that key is looked up from the list below to determine the actual queues the worker should pull from. Wildcards (*) and negation (leading !) can be used to select the queues the worker should process. There is always a fallback key - @default, which workers will use if the key for that worker is empty. If both the key and the fallback are empty, the worker defaults to processing '*'
|
4
|
+
</p>
|
5
|
+
|
6
|
+
<form action="<%= url(:dynamicqueues) %>" method="POST" style="float:none; margin-top:10px">
|
7
|
+
|
8
|
+
<table class='queues'>
|
11
9
|
<tr>
|
12
|
-
<
|
13
|
-
<
|
14
|
-
<
|
15
|
-
<
|
16
|
-
<td>
|
17
|
-
<a href="<%= url(:dynamicqueues) %>/<%= queue %>/remove" class="remove">Remove</a>
|
18
|
-
</td>
|
10
|
+
<th>Name</th>
|
11
|
+
<th>Value</th>
|
12
|
+
<th>Expanded</th>
|
13
|
+
<th></th>
|
19
14
|
</tr>
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
<
|
25
|
-
<
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
</
|
31
|
-
|
32
|
-
</
|
15
|
+
<% @queues.each_with_index do |data, i| %>
|
16
|
+
<tr class="line">
|
17
|
+
<td><input type="text" id="input-<%= i %>-name" name="queues[][name]" value="<%= data['name'] %>" /></td>
|
18
|
+
<td><input type="text" id="input-<%= i %>-value" name="queues[][value]" value="<%= data['value'] %>" /></td>
|
19
|
+
<td class="expanded"><%= data['expanded'] %></td>
|
20
|
+
<td>
|
21
|
+
<a href="#remove" class="remove">Remove</a>
|
22
|
+
</td>
|
23
|
+
</tr>
|
24
|
+
<% end %>
|
25
|
+
</table>
|
26
|
+
|
27
|
+
<a href="#add" class="add">Add</a>
|
28
|
+
<input type="submit" value="Save"/>
|
33
29
|
|
30
|
+
</form>
|
34
31
|
|
35
32
|
<script type="text/javascript" charset="utf-8">
|
33
|
+
function markDirty()
|
34
|
+
{
|
35
|
+
$("input[type=submit]").css({border:"3px orange solid"});
|
36
|
+
}
|
37
|
+
|
36
38
|
jQuery(function($) {
|
37
39
|
|
38
|
-
$(
|
40
|
+
$("input").live("keypress", markDirty);
|
41
|
+
|
42
|
+
$("a.add").live("click", function(e) {
|
43
|
+
e.preventDefault();
|
44
|
+
var $table = $("table.queues");
|
45
|
+
var $newRow = $table.find("tr.line:first").clone();
|
46
|
+
$newRow.find("input[type=text]").attr("value", "");
|
47
|
+
$newRow.find("td.expanded").html("")
|
48
|
+
$newRow.appendTo($table);
|
49
|
+
markDirty();
|
50
|
+
});
|
51
|
+
|
52
|
+
$("a.remove").live("click", function(e) {
|
39
53
|
e.preventDefault();
|
40
|
-
var $link = $(this)
|
41
|
-
|
42
|
-
|
43
|
-
if (confirmed) {
|
44
|
-
$link.animate({opacity: 0.5});
|
45
|
-
$.ajax({
|
46
|
-
url: url,
|
47
|
-
type: 'post',
|
48
|
-
success: function() {
|
49
|
-
$link.parents('tr').remove();
|
50
|
-
}
|
51
|
-
});
|
52
|
-
} else {
|
53
|
-
return false
|
54
|
-
}
|
54
|
+
var $link = $(this);
|
55
|
+
$link.parents("tr").remove();
|
56
|
+
markDirty();
|
55
57
|
});
|
56
58
|
|
59
|
+
|
57
60
|
});
|
58
61
|
</script>
|
data/spec/queues_spec.rb
CHANGED
@@ -55,6 +55,42 @@ describe "Dynamic Queues" do
|
|
55
55
|
|
56
56
|
end
|
57
57
|
|
58
|
+
context "attributes" do
|
59
|
+
it "should always have a fallback pattern" do
|
60
|
+
Resque.get_dynamic_queues.should == {'default' => ['*']}
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should allow setting single patterns" do
|
64
|
+
Resque.get_dynamic_queue('foo').should == ['*']
|
65
|
+
Resque.set_dynamic_queue('foo', ['bar'])
|
66
|
+
Resque.get_dynamic_queue('foo').should == ['bar']
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should allow setting multiple patterns" do
|
70
|
+
Resque.set_dynamic_queues({'foo' => ['bar'], 'baz' => ['boo']})
|
71
|
+
Resque.get_dynamic_queues.should == {'foo' => ['bar'], 'baz' => ['boo'], 'default' => ['*']}
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should remove mapping when setting empty value" do
|
75
|
+
Resque.get_dynamic_queues
|
76
|
+
Resque.set_dynamic_queues({'foo' => ['bar'], 'baz' => ['boo']})
|
77
|
+
Resque.get_dynamic_queues.should == {'foo' => ['bar'], 'baz' => ['boo'], 'default' => ['*']}
|
78
|
+
|
79
|
+
Resque.set_dynamic_queues({'foo' => [], 'baz' => ['boo']})
|
80
|
+
Resque.get_dynamic_queues.should == {'baz' => ['boo'], 'default' => ['*']}
|
81
|
+
Resque.set_dynamic_queues({'baz' => nil})
|
82
|
+
Resque.get_dynamic_queues.should == {'default' => ['*']}
|
83
|
+
|
84
|
+
Resque.set_dynamic_queues({'foo' => ['bar'], 'baz' => ['boo']})
|
85
|
+
Resque.set_dynamic_queue('foo', [])
|
86
|
+
Resque.get_dynamic_queues.should == {'baz' => ['boo'], 'default' => ['*']}
|
87
|
+
Resque.set_dynamic_queue('baz', nil)
|
88
|
+
Resque.get_dynamic_queues.should == {'default' => ['*']}
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
end
|
93
|
+
|
58
94
|
context "basic queue patterns" do
|
59
95
|
|
60
96
|
before(:each) do
|
data/spec/server_spec.rb
CHANGED
@@ -37,6 +37,12 @@ describe "Dynamic Queues pages" do
|
|
37
37
|
|
38
38
|
context "show dynamic queues table" do
|
39
39
|
|
40
|
+
it "should shows default queue when nothing set" do
|
41
|
+
get "/dynamicqueues"
|
42
|
+
|
43
|
+
last_response.body.should include 'default'
|
44
|
+
end
|
45
|
+
|
40
46
|
it "should shows names of queues" do
|
41
47
|
Resque.set_dynamic_queue("key_one", ["foo"])
|
42
48
|
Resque.set_dynamic_queue("key_two", ["bar"])
|
@@ -61,23 +67,18 @@ describe "Dynamic Queues pages" do
|
|
61
67
|
|
62
68
|
context "remove queue link" do
|
63
69
|
|
64
|
-
|
65
|
-
it "should shows remove link for queue" do
|
70
|
+
it "should show remove link for queue" do
|
66
71
|
Resque.set_dynamic_queue("key_one", ["foo"])
|
67
72
|
|
68
73
|
get "/dynamicqueues"
|
69
74
|
|
70
|
-
last_response.body.should match /<a .*href=['"]
|
75
|
+
last_response.body.should match /<a .*href=['"]#remove['"].*>/
|
71
76
|
end
|
72
77
|
|
73
|
-
it "should
|
74
|
-
|
75
|
-
|
76
|
-
post "/dynamicqueues/key_one/remove"
|
78
|
+
it "should show add link" do
|
79
|
+
get "/dynamicqueues"
|
77
80
|
|
78
|
-
last_response.should
|
79
|
-
last_response['Location'].should match /dynamicqueues/
|
80
|
-
Resque.get_dynamic_queue("key_two").should be_empty
|
81
|
+
last_response.body.should match /<a .*href=['"]#add['"].*>/
|
81
82
|
end
|
82
83
|
|
83
84
|
end
|
@@ -87,22 +88,31 @@ describe "Dynamic Queues pages" do
|
|
87
88
|
it "should have form to edit queues" do
|
88
89
|
get "/dynamicqueues"
|
89
90
|
|
90
|
-
last_response.body.should match /<form
|
91
|
-
|
92
|
-
|
91
|
+
last_response.body.should match /<form action="http:\/\/example.org\/dynamicqueues"/
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should show input fields" do
|
95
|
+
Resque.set_dynamic_queue("key_one", ["foo"])
|
96
|
+
Resque.set_dynamic_queue("key_two", ["bar", "baz"])
|
97
|
+
get "/dynamicqueues"
|
98
|
+
|
99
|
+
last_response.body.should match /<input type="text" id="input-0-name" name="queues\[\]\[name\]" value="key_one"/
|
100
|
+
last_response.body.should match /<input type="text" id="input-0-value" name="queues\[\]\[value\]" value="foo"/
|
101
|
+
last_response.body.should match /<input type="text" id="input-1-name" name="queues\[\]\[name\]" value="key_two"/
|
102
|
+
last_response.body.should match /<input type="text" id="input-1-value" name="queues\[\]\[value\]" value="bar, baz"/
|
93
103
|
end
|
94
104
|
|
95
105
|
it "should delete queues on empty queue submit" do
|
96
106
|
Resque.set_dynamic_queue("key_two", ["bar", "baz"])
|
97
|
-
post "/dynamicqueues", {'name' => "key_two", "
|
107
|
+
post "/dynamicqueues", {'queues' => [{'name' => "key_two", "value" => ""}]}
|
98
108
|
|
99
109
|
last_response.should be_redirect
|
100
110
|
last_response['Location'].should match /dynamicqueues/
|
101
|
-
Resque.get_dynamic_queue("key_two").should be_empty
|
111
|
+
Resque.get_dynamic_queue("key_two", []).should be_empty
|
102
112
|
end
|
103
113
|
|
104
114
|
it "should create queues" do
|
105
|
-
post "/dynamicqueues", {'name' => "key_two", "
|
115
|
+
post "/dynamicqueues", {'queues' => [{'name' => "key_two", "value" => " foo, bar ,baz "}]}
|
106
116
|
|
107
117
|
last_response.should be_redirect
|
108
118
|
last_response['Location'].should match /dynamicqueues/
|
@@ -111,7 +121,7 @@ describe "Dynamic Queues pages" do
|
|
111
121
|
|
112
122
|
it "should update queues" do
|
113
123
|
Resque.set_dynamic_queue("key_two", ["bar", "baz"])
|
114
|
-
post "/dynamicqueues", {'name' => "key_two", "
|
124
|
+
post "/dynamicqueues", {'queues' => [{'name' => "key_two", "value" => "foo,bar,baz"}]}
|
115
125
|
|
116
126
|
last_response.should be_redirect
|
117
127
|
last_response['Location'].should match /dynamicqueues/
|
@@ -120,4 +130,4 @@ describe "Dynamic Queues pages" do
|
|
120
130
|
|
121
131
|
end
|
122
132
|
|
123
|
-
end
|
133
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resque-dynamic-queues
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.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: 2011-12-
|
12
|
+
date: 2011-12-13 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: resque
|
16
|
-
requirement: &
|
16
|
+
requirement: &2236617460 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '1.10'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2236617460
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
requirement: &
|
27
|
+
requirement: &2236616960 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '2.5'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2236616960
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rack-test
|
38
|
-
requirement: &
|
38
|
+
requirement: &2236616500 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: 0.5.4
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *2236616500
|
47
47
|
description: A resque plugin for specifying the queues a worker pulls from with wildcards,
|
48
48
|
negations, or dynamic look up from redis
|
49
49
|
email:
|
@@ -57,6 +57,7 @@ files:
|
|
57
57
|
- Gemfile
|
58
58
|
- README.md
|
59
59
|
- Rakefile
|
60
|
+
- config.ru
|
60
61
|
- init.rb
|
61
62
|
- lib/resque-dynamic-queues-server.rb
|
62
63
|
- lib/resque-dynamic-queues.rb
|