resque-dynamic-queues 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,8 +1,9 @@
1
1
  *.gem
2
+ *.DS_Store
2
3
  .bundle
3
4
  Gemfile.lock
4
5
  pkg/*
5
6
  .idea
6
7
  spec/dump.rdb
7
- redis-server.log
8
- redis.pid
8
+ spec/redis-server.log
9
+ spec/redis.pid
@@ -0,0 +1,11 @@
1
+ 0.6.0
2
+ -----
3
+
4
+ Stored dynamic keys fall back to a default, or to all the queues.
5
+ Some refactoring and auto loading
6
+ Resque web interface
7
+
8
+ 0.5.1
9
+ -----
10
+
11
+ Initial version
data/README.md CHANGED
@@ -44,3 +44,12 @@ QUEUE='@key' rake resque:work
44
44
 
45
45
  Pulls jobs from queue names stored in redis, with wildcards/negations
46
46
 
47
+
48
+
49
+ There is also a tab in the resque-web UI that allows you to define the dynamic queues To activate it, you need to require 'resque-dynamic-queues-server' in whatever initializer you use to bring up resque-web.
50
+
51
+
52
+ Contributors:
53
+
54
+ Matt Conway ( https://github.com/wr0ngway )
55
+ Bert Goethals ( https://github.com/Bertg )
data/Rakefile CHANGED
@@ -1,2 +1,67 @@
1
1
  require 'bundler'
2
2
  Bundler::GemHelper.install_tasks
3
+
4
+ task :my_release => ['changelog', 'release'] do
5
+ end
6
+
7
+ task :changelog do
8
+
9
+ helper = Bundler::GemHelper.new(Dir.pwd)
10
+ version = "v#{helper.gemspec.version}"
11
+
12
+ changelog_file = 'CHANGELOG'
13
+ entries = ""
14
+
15
+ # Get a list of current tags
16
+ tags = `git tag -l`.split
17
+ tags = tags.sort_by {|t| t[1..-1].split(".").collect {|s| s.to_i } }
18
+ newest_tag = tags[-1]
19
+
20
+ if version == newest_tag
21
+ puts "You need to update version, same as most recent tag: #{version}"
22
+ exit
23
+ end
24
+
25
+ # If we already have a changelog, make the last tag be the
26
+ # last one in the changelog, and the next one be the one
27
+ # following that in the tag list
28
+ newest_changelog_version = nil
29
+ if File.exist?(changelog_file)
30
+ entries = File.read(changelog_file)
31
+ head = entries.split.first
32
+ if head =~ /\d\.\d\.\d/
33
+ newest_changelog_version = "v#{head}"
34
+
35
+ if version == newest_changelog_version
36
+ puts "You need to update version, same as most recent changelog: #{version}"
37
+ exit
38
+ end
39
+
40
+ end
41
+ end
42
+
43
+ # Generate changelog from repo
44
+ log=`git log --pretty='format:%s <%h> [%cn]' #{newest_tag}..#{HEAD}`
45
+
46
+ # Strip out maintenance entries
47
+ log = log.lines.to_a.delete_if do |l|
48
+ l =~ /^Regenerated? gemspec/ ||
49
+ l =~ /^version bump/i ||
50
+ l =~ /^Updated changelog/ ||
51
+ l =~ /^Merged? branch/
52
+ end
53
+
54
+ # Write out changelog file
55
+ File.open(changelog_file, 'w') do |out|
56
+ out.puts version.gsub(/^v/, '')
57
+ out.puts "-----"
58
+ out.puts "\n"
59
+ out.puts log
60
+ out.puts "\n"
61
+ out.puts entries
62
+ end
63
+
64
+ # Commit and push
65
+ sh "git ci -m'Updated changelog' #{changelog_file}"
66
+ sh "git push"
67
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'resque-dynamic-queues'
@@ -0,0 +1,2 @@
1
+ require 'resque-dynamic-queues'
2
+ require 'resque/plugins/dynamic_queues/server'
@@ -4,7 +4,17 @@ module Resque
4
4
  module Attributes
5
5
 
6
6
  def get_dynamic_queue(key)
7
- redis.lrange("dynamic_queue:#{key}", 0, -1)
7
+ queue_names = redis.lrange("dynamic_queue:#{key}", 0, -1)
8
+
9
+ if queue_names.nil? || queue_names.size == 0
10
+ queue_names = redis.lrange("dynamic_queue:default", 0, -1)
11
+ end
12
+
13
+ if queue_names.nil? || queue_names.size == 0
14
+ queue_names = Resque.queues
15
+ end
16
+
17
+ return queue_names
8
18
  end
9
19
 
10
20
  def set_dynamic_queue(key, values)
@@ -15,6 +25,10 @@ module Resque
15
25
  end
16
26
  end
17
27
 
28
+ def get_dynamic_queues
29
+ (redis.keys("dynamic_queue:*") || []).collect{|q| q.gsub('dynamic_queue:', '')}
30
+ end
31
+
18
32
  end
19
33
  end
20
34
  end
@@ -17,7 +17,7 @@ module Resque
17
17
  # list for a key with Resque.set_dynamic_queue(key, ["q1", "q2"]
18
18
  #
19
19
  def queues_with_dynamic
20
- queue_names = @queues
20
+ queue_names = @queues.dup
21
21
 
22
22
  return queues_without_dynamic if queue_names.grep(/(^!)|(^@)|(\*)/).size == 0
23
23
 
@@ -0,0 +1,42 @@
1
+ require 'resque-dynamic-queues'
2
+
3
+ module Resque
4
+ module Plugins
5
+ module DynamicQueues
6
+ module Server
7
+
8
+ VIEW_PATH = File.join(File.dirname(__FILE__), 'server', 'views')
9
+
10
+ def self.registered(app)
11
+ app.get "/dynamicqueues" do
12
+ @queues = Resque.get_dynamic_queues
13
+ dq_view :queues
14
+ end
15
+
16
+ app.post "/dynamicqueues" do
17
+ key = params['name']
18
+ values = params['queues'].to_s.split.collect{|q| q.gsub(/\s/, '')}
19
+ Resque.set_dynamic_queue(key, values)
20
+ redirect url(:dynamicqueues)
21
+ end
22
+
23
+ app.post "/dynamicqueues/:key/remove" do
24
+ key = params['key']
25
+ Resque.set_dynamic_queue(key, [])
26
+ redirect url(:dynamicqueues)
27
+ end
28
+
29
+ app.helpers do
30
+ def dq_view(filename, options = {}, locals = {})
31
+ erb(File.read(File.join(::Resque::Plugins::DynamicQueues::Server::VIEW_PATH, "#{filename}.erb")), options, locals)
32
+ end
33
+ end
34
+
35
+ app.tabs << "DynamicQueues"
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ Resque::Server.register Resque::Plugins::DynamicQueues::Server
@@ -0,0 +1,66 @@
1
+ <h1>Dynamic Queues</h1>
2
+ <table class='workers'>
3
+ <tr>
4
+ <th>Name</th>
5
+ <th>Value</th>
6
+ <th>Result</th>
7
+ <th>Workers</th>
8
+ <th></th>
9
+ </tr>
10
+ <% @queues.each do |queue| %>
11
+ <tr>
12
+ <td><%= queue %></td>
13
+ <td><%= Resque.get_dynamic_queue(queue).join(", ") %></td>
14
+ <td><%= Resque::Worker.new("@#{queue}").queues.join(", ") %></td>
15
+ <td></td>
16
+ <td>
17
+ <a href="<%= url(:dynamicqueues) %>/<%= queue %>/remove" class="remove">Remove</a>
18
+ </td>
19
+ </tr>
20
+ <% end %>
21
+ <tr>
22
+ <td>Fallback</td>
23
+ <td>-</td>
24
+ <td><%= Resque::Worker.new("@---").queues.join(', ') %></td>
25
+ <td></td>
26
+ <td>
27
+ </td>
28
+ </tr>
29
+ </table>
30
+
31
+
32
+ <h1>Make a new queue</h1>
33
+ <form action="<%= url(:dynamicqueues) %>" method="post" accept-charset="utf-8">
34
+ <p><input type="text" name="name"></p>
35
+ <p>
36
+ <textarea name="queues"></textarea>
37
+ Separate new queues by lines
38
+ </p>
39
+ <p><input type="submit" value="Create or Update"></p>
40
+ </form>
41
+
42
+
43
+ <script type="text/javascript" charset="utf-8">
44
+ jQuery(function($) {
45
+
46
+ $('a.remove').click(function(e) {
47
+ e.preventDefault();
48
+ var $link = $(this),
49
+ url = $link.attr('href'),
50
+ confirmed = confirm("Are you sure you want to kill this job? There is no undo.");
51
+ if (confirmed) {
52
+ $link.animate({opacity: 0.5});
53
+ $.ajax({
54
+ url: url,
55
+ type: 'post',
56
+ success: function() {
57
+ $link.parents('tr').remove();
58
+ }
59
+ });
60
+ } else {
61
+ return false
62
+ }
63
+ });
64
+
65
+ });
66
+ </script>
@@ -1,7 +1,7 @@
1
1
  module Resque
2
2
  module Plugins
3
3
  module DynamicQueues
4
- VERSION = "0.5.1"
4
+ VERSION = "0.6.0"
5
5
  end
6
6
  end
7
7
  end
@@ -22,6 +22,7 @@ Gem::Specification.new do |s|
22
22
 
23
23
  s.add_dependency("resque", '~> 1.10')
24
24
  s.add_development_dependency('rspec', '~> 2.5')
25
+ s.add_development_dependency('rack-test', '~> 0.5.4')
25
26
 
26
27
  end
27
28
 
@@ -52,7 +52,7 @@ describe "Dynamic Queues" do
52
52
  it "should pass lint" do
53
53
  Resque::Plugin.lint(Resque::Plugins::DynamicQueues)
54
54
  end
55
-
55
+
56
56
  end
57
57
 
58
58
  context "basic queue patterns" do
@@ -80,7 +80,7 @@ describe "Dynamic Queues" do
80
80
  it "can include queues with pattern"do
81
81
  worker = Resque::Worker.new("high*")
82
82
  worker.queues.should == ["high_x", "high_y"]
83
-
83
+
84
84
  worker = Resque::Worker.new("*high_z")
85
85
  worker.queues.should == ["superhigh_z"]
86
86
 
@@ -108,6 +108,16 @@ describe "Dynamic Queues" do
108
108
  worker.queues.should == ["bar", "foo"]
109
109
  end
110
110
 
111
+ it "will not bloat the workers queue" do
112
+ Resque.watch_queue("high_x")
113
+ worker = Resque::Worker.new("@mykey")
114
+
115
+ worker.send(:instance_eval, "@queues").should == ['@mykey']
116
+ worker.queues.should == ["high_x"]
117
+ worker.send(:instance_eval, "@queues").should == ['@mykey']
118
+ worker.queues.should == ["high_x"]
119
+ end
120
+
111
121
  it "uses hostname as default key in dynamic queues" do
112
122
  host = `hostname`.chomp
113
123
  Resque.set_dynamic_queue(host, ["foo", "bar"])
@@ -120,12 +130,34 @@ describe "Dynamic Queues" do
120
130
  Resque.watch_queue("foo")
121
131
  Resque.watch_queue("high_y")
122
132
  Resque.watch_queue("superhigh_z")
123
-
133
+
124
134
  Resque.set_dynamic_queue("mykey", ["*high*", "!high_y"])
125
135
  worker = Resque::Worker.new("@mykey")
126
136
  worker.queues.should == ["high_x", "superhigh_z"]
127
137
  end
128
-
138
+
139
+ it "falls back to default queues when missing" do
140
+ Resque.set_dynamic_queue("default", ["foo", "bar"])
141
+ worker = Resque::Worker.new("@mykey")
142
+ worker.queues.should == ["bar", "foo"]
143
+ end
144
+
145
+ it "falls back to all queues when missing and no default" do
146
+ Resque.watch_queue("high_x")
147
+ Resque.watch_queue("foo")
148
+ worker = Resque::Worker.new("@mykey")
149
+ worker.queues.should == ["foo", "high_x"]
150
+ end
151
+
152
+ it "falls back to all queues when missing and no default and keep up to date" do
153
+ Resque.watch_queue("high_x")
154
+ Resque.watch_queue("foo")
155
+ worker = Resque::Worker.new("@mykey")
156
+ worker.queues.should == ["foo", "high_x"]
157
+ Resque.watch_queue("bar")
158
+ worker.queues.should == ["bar", "foo", "high_x"]
159
+ end
160
+
129
161
  end
130
162
 
131
163
  end
@@ -0,0 +1,123 @@
1
+ ENV['RACK_ENV'] = 'test'
2
+
3
+ require 'spec_helper'
4
+ require 'rack'
5
+ require 'rack/test'
6
+ require 'resque/server'
7
+ require 'resque-dynamic-queues-server'
8
+
9
+ Sinatra::Base.set :environment, :test
10
+ # ::Test::Unit::TestCase.send :include, Rack::Test::Methods
11
+
12
+
13
+ describe "Dynamic Queues pages" do
14
+ include Rack::Test::Methods
15
+
16
+ def app
17
+ @app ||= Resque::Server.new
18
+ end
19
+
20
+ before(:each) do
21
+ Resque.redis.flushall
22
+ end
23
+
24
+ context "existnce in application" do
25
+
26
+ it "should respond to it's url" do
27
+ get "/dynamicqueues"
28
+ last_response.should be_ok
29
+ end
30
+
31
+ it "should display its tab" do
32
+ get "/overview"
33
+ last_response.body.should include "<a href='/dynamicqueues'>DynamicQueues</a>"
34
+ end
35
+
36
+ end
37
+
38
+ context "show dynamic queues table" do
39
+
40
+ it "should shows names of queues" do
41
+ Resque.set_dynamic_queue("key_one", ["foo"])
42
+ Resque.set_dynamic_queue("key_two", ["bar"])
43
+
44
+ get "/dynamicqueues"
45
+
46
+ last_response.body.should include 'key_one'
47
+ last_response.body.should include 'key_two'
48
+ end
49
+
50
+ it "should shows values of queues" do
51
+ Resque.set_dynamic_queue("key_one", ["foo"])
52
+ Resque.set_dynamic_queue("key_two", ["bar", "baz"])
53
+
54
+ get "/dynamicqueues"
55
+
56
+ last_response.body.should include 'foo'
57
+ last_response.body.should include 'bar, baz'
58
+ end
59
+
60
+ end
61
+
62
+ context "remove queue link" do
63
+
64
+
65
+ it "should shows remove link for queue" do
66
+ Resque.set_dynamic_queue("key_one", ["foo"])
67
+
68
+ get "/dynamicqueues"
69
+
70
+ last_response.body.should match /<a .*href=['"]http:\/\/example.org\/dynamicqueues\/key_one\/remove['"].*>/
71
+ end
72
+
73
+ it "should remove queue when remove link clicked" do # JS will do the post
74
+ Resque.set_dynamic_queue("key_one", ["foo"])
75
+
76
+ post "/dynamicqueues/key_one/remove"
77
+
78
+ last_response.should be_redirect
79
+ last_response['Location'].should match /dynamicqueues/
80
+ Resque.get_dynamic_queue("key_two").should be_empty
81
+ end
82
+
83
+ end
84
+
85
+ context "form to edit queues" do
86
+
87
+ it "should have form to edit queues" do
88
+ get "/dynamicqueues"
89
+
90
+ last_response.body.should match /<form .*action=['"]http:\/\/example.org\/dynamicqueues['"].*>/
91
+ last_response.body.should match /<input .*name=['"]name['"].*>/
92
+ last_response.body.should match /<textarea .*name=['"]queues['"].*>/
93
+ end
94
+
95
+ it "should delete queues on empty queue submit" do
96
+ Resque.set_dynamic_queue("key_two", ["bar", "baz"])
97
+ post "/dynamicqueues", {'name' => "key_two", "queues" => ""}
98
+
99
+ last_response.should be_redirect
100
+ last_response['Location'].should match /dynamicqueues/
101
+ Resque.get_dynamic_queue("key_two").should be_empty
102
+ end
103
+
104
+ it "should create queues" do
105
+ post "/dynamicqueues", {'name' => "key_two", "queues" => "foo\n\rbar\n\rbaz"}
106
+
107
+ last_response.should be_redirect
108
+ last_response['Location'].should match /dynamicqueues/
109
+ Resque.get_dynamic_queue("key_two").should == %w{foo bar baz}
110
+ end
111
+
112
+ it "should update queues" do
113
+ Resque.set_dynamic_queue("key_two", ["bar", "baz"])
114
+ post "/dynamicqueues", {'name' => "key_two", "queues" => "foo\n\rbar\n\rbaz"}
115
+
116
+ last_response.should be_redirect
117
+ last_response['Location'].should match /dynamicqueues/
118
+ Resque.get_dynamic_queue("key_two").should == %w{foo bar baz}
119
+ end
120
+
121
+ end
122
+
123
+ end
@@ -1,3 +1,4 @@
1
+ require 'rspec'
1
2
  require 'resque-dynamic-queues'
2
3
 
3
4
  spec_dir = File.dirname(File.expand_path(__FILE__))
metadata CHANGED
@@ -1,91 +1,104 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: resque-dynamic-queues
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.6.0
4
5
  prerelease:
5
- version: 0.5.1
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Matt Conway
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-03-28 00:00:00 -04:00
12
+ date: 2011-06-08 00:00:00.000000000 -04:00
14
13
  default_executable:
15
- dependencies:
16
- - !ruby/object:Gem::Dependency
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
17
16
  name: resque
18
- prerelease: false
19
- requirement: &id001 !ruby/object:Gem::Requirement
17
+ requirement: &2156532920 !ruby/object:Gem::Requirement
20
18
  none: false
21
- requirements:
19
+ requirements:
22
20
  - - ~>
23
- - !ruby/object:Gem::Version
24
- version: "1.10"
21
+ - !ruby/object:Gem::Version
22
+ version: '1.10'
25
23
  type: :runtime
26
- version_requirements: *id001
27
- - !ruby/object:Gem::Dependency
24
+ prerelease: false
25
+ version_requirements: *2156532920
26
+ - !ruby/object:Gem::Dependency
28
27
  name: rspec
28
+ requirement: &2156532420 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '2.5'
34
+ type: :development
29
35
  prerelease: false
30
- requirement: &id002 !ruby/object:Gem::Requirement
36
+ version_requirements: *2156532420
37
+ - !ruby/object:Gem::Dependency
38
+ name: rack-test
39
+ requirement: &2156531960 !ruby/object:Gem::Requirement
31
40
  none: false
32
- requirements:
41
+ requirements:
33
42
  - - ~>
34
- - !ruby/object:Gem::Version
35
- version: "2.5"
43
+ - !ruby/object:Gem::Version
44
+ version: 0.5.4
36
45
  type: :development
37
- version_requirements: *id002
38
- description: A resque plugin for specifying the queues a worker pulls from with wildcards, negations, or dynamic look up from redis
39
- email:
46
+ prerelease: false
47
+ version_requirements: *2156531960
48
+ description: A resque plugin for specifying the queues a worker pulls from with wildcards,
49
+ negations, or dynamic look up from redis
50
+ email:
40
51
  - matt@conwaysplace.com
41
52
  executables: []
42
-
43
53
  extensions: []
44
-
45
54
  extra_rdoc_files: []
46
-
47
- files:
55
+ files:
48
56
  - .gitignore
57
+ - CHANGELOG
49
58
  - Gemfile
50
59
  - README.md
51
60
  - Rakefile
61
+ - init.rb
62
+ - lib/resque-dynamic-queues-server.rb
52
63
  - lib/resque-dynamic-queues.rb
53
64
  - lib/resque/plugins/dynamic_queues/attributes.rb
54
65
  - lib/resque/plugins/dynamic_queues/queues.rb
66
+ - lib/resque/plugins/dynamic_queues/server.rb
67
+ - lib/resque/plugins/dynamic_queues/server/views/queues.erb
55
68
  - lib/resque/plugins/dynamic_queues/version.rb
56
69
  - resque-dynamic-queues.gemspec
57
70
  - spec/queues_spec.rb
58
71
  - spec/redis-test.conf
72
+ - spec/server_spec.rb
59
73
  - spec/spec_helper.rb
60
74
  has_rdoc: true
61
- homepage: ""
75
+ homepage: ''
62
76
  licenses: []
63
-
64
77
  post_install_message:
65
78
  rdoc_options: []
66
-
67
- require_paths:
79
+ require_paths:
68
80
  - lib
69
- required_ruby_version: !ruby/object:Gem::Requirement
81
+ required_ruby_version: !ruby/object:Gem::Requirement
70
82
  none: false
71
- requirements:
72
- - - ">="
73
- - !ruby/object:Gem::Version
74
- version: "0"
75
- required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
88
  none: false
77
- requirements:
78
- - - ">="
79
- - !ruby/object:Gem::Version
80
- version: "0"
89
+ requirements:
90
+ - - ! '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
81
93
  requirements: []
82
-
83
94
  rubyforge_project: resque-dynamic-queues
84
- rubygems_version: 1.6.1
95
+ rubygems_version: 1.6.2
85
96
  signing_key:
86
97
  specification_version: 3
87
- summary: A resque plugin for specifying the queues a worker pulls from with wildcards, negations, or dynamic look up from redis
88
- test_files:
98
+ summary: A resque plugin for specifying the queues a worker pulls from with wildcards,
99
+ negations, or dynamic look up from redis
100
+ test_files:
89
101
  - spec/queues_spec.rb
90
102
  - spec/redis-test.conf
103
+ - spec/server_spec.rb
91
104
  - spec/spec_helper.rb