resque 1.5.0 → 1.5.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of resque might be problematic. Click here for more details.

@@ -1,14 +1,23 @@
1
1
  * Chris Wanstrath
2
2
  * John Barnette
3
+ * Aaron Quint
3
4
  * Adam Cooke
5
+ * Mike Mangino
4
6
  * Rob Hanlon
5
7
  * Jason Amster
6
8
  * jgeiger
7
- * Aaron Quint
9
+ * Daniel Ceballos
10
+ * Matt Duncan
11
+ * Roman Heinrich
8
12
  * Ben VandenBos
9
- * PJ Hyett
13
+ * Christos Trochalakis
14
+ * Matt Palmer
15
+ * Michael Dwan
16
+ * Brian P O'Rourke
17
+ * Karel Minarik
10
18
  * Arthur Zapparoli
11
19
  * Simon Rozet
12
- * Brian P O'Rourke
13
20
  * Dave Hoover
14
- * Michael Dwan
21
+ * PJ Hyett
22
+ * Masatomo Nakano
23
+ * gravis
data/HISTORY.md CHANGED
@@ -1,3 +1,16 @@
1
+ ## 1.5.1 (2010-03-03)
2
+
3
+ * `Job.destroy` and `Resque.dequeue` return the # of destroyed jobs.
4
+ * Hoptoad notifier improvements
5
+ * Specify the namespace with `resque-web` by passing `-N namespace`
6
+ * Bugfix: Don't crash when trying to parse invalid JSON.
7
+ * Bugfix: Non-standard namespace support
8
+ * Web: Red backgound for queue "failed" only shown if there are failed jobs.
9
+ * Web bugfix: Tabs highlight properly now
10
+ * Web bugfix: ZSET partial support in stats
11
+ * Web bugfix: Deleting failed jobs works again
12
+ * Web bugfix: Sets (or zsets, lists, etc) now paginate.
13
+
1
14
  ## 1.5.0 (2010-02-17)
2
15
 
3
16
  * Version now included in procline, e.g. `resque-1.5.0: Message`
@@ -410,6 +410,10 @@ the script as the final argument:
410
410
 
411
411
  $ resque-web -p 8282 rails_root/config/initializers/resque.rb
412
412
 
413
+ You can also set the namespace directly using `resque-web`:
414
+
415
+ $ resque-web -p 8282 -N myapp
416
+
413
417
  ### Passenger
414
418
 
415
419
  Using Passenger? Resque ships with a `config.ru` you can use. See
@@ -15,4 +15,9 @@ Vegas::Runner.new(Resque::Server, 'resque-web', {
15
15
  path = (ENV['RESQUECONFIG'] || v.args.first)
16
16
  load path.to_s.strip if path
17
17
  }
18
- })
18
+ }) do |runner, opts, app|
19
+ opts.on('-N NAMESPACE', "--namespace NAMESPACE", "set the Redis namespace") {|namespace|
20
+ runner.logger.info "Using Redis namespace '#{namespace}'"
21
+ Resque.redis.namespace = namespace
22
+ }
23
+ end
@@ -156,6 +156,8 @@ module Resque
156
156
  # the provided class. See `Resque::Job.destroy` for more
157
157
  # information.
158
158
  #
159
+ # Returns the number of jobs destroyed.
160
+ #
159
161
  # Example:
160
162
  #
161
163
  # # Removes all jobs of class `UpdateNetworkGraph`
@@ -228,7 +230,7 @@ module Resque
228
230
  # is O(N) for the keyspace, so be careful - this can be slow for big databases.
229
231
  def keys
230
232
  redis.keys("*").map do |key|
231
- key.sub('resque:', '')
233
+ key.sub("#{redis.namespace}:", '')
232
234
  end
233
235
  end
234
236
  end
@@ -1,5 +1,6 @@
1
- require 'net/http'
1
+ require 'net/https'
2
2
  require 'builder'
3
+ require 'uri'
3
4
 
4
5
  module Resque
5
6
  module Failure
@@ -10,18 +11,17 @@ module Resque
10
11
  # Resque::Failure::Hoptoad.configure do |config|
11
12
  # config.api_key = 'blah'
12
13
  # config.secure = true
13
- # config.subdomain = 'your_hoptoad_subdomain'
14
+ #
15
+ # # optional proxy support
16
+ # config.proxy_host = 'x.y.z.t'
17
+ # config.proxy_port = 8080
14
18
  # end
15
19
  class Hoptoad < Base
16
- #from the hoptoad plugin
17
- INPUT_FORMAT = %r{^([^:]+):(\d+)(?::in `([^']+)')?$}.freeze
18
-
19
- class << self
20
- attr_accessor :secure, :api_key, :subdomain
21
- end
20
+ # From the hoptoad plugin
21
+ INPUT_FORMAT = /^([^:]+):(\d+)(?::in `([^']+)')?$/
22
22
 
23
- def self.url
24
- "http://#{subdomain}.hoptoadapp.com/" if subdomain
23
+ class << self
24
+ attr_accessor :secure, :api_key, :proxy_host, :proxy_port
25
25
  end
26
26
 
27
27
  def self.count
@@ -35,13 +35,12 @@ module Resque
35
35
  Resque::Failure.backend = self
36
36
  end
37
37
 
38
-
39
-
40
38
  def save
41
39
  http = use_ssl? ? :https : :http
42
40
  url = URI.parse("#{http}://hoptoadapp.com/notifier_api/v2/notices")
43
41
 
44
- http = Net::HTTP.new(url.host, url.port)
42
+ request = Net::HTTP::Proxy(self.class.proxy_host, self.class.proxy_port)
43
+ http = request.new(url.host, url.port)
45
44
  headers = {
46
45
  'Content-type' => 'text/xml',
47
46
  'Accept' => 'text/xml, application/xml'
@@ -49,7 +48,7 @@ module Resque
49
48
 
50
49
  http.read_timeout = 5 # seconds
51
50
  http.open_timeout = 2 # seconds
52
-
51
+
53
52
  http.use_ssl = use_ssl?
54
53
 
55
54
  begin
@@ -66,7 +65,7 @@ module Resque
66
65
  log "Hoptoad Failure: #{response.class}\n#{body}"
67
66
  end
68
67
  end
69
-
68
+
70
69
  def xml
71
70
  x = Builder::XmlMarkup.new
72
71
  x.instruct!
@@ -99,10 +98,10 @@ module Resque
99
98
  x.tag!("server-environment") do
100
99
  x.tag!("environment-name",RAILS_ENV)
101
100
  end
102
-
101
+
103
102
  end
104
103
  end
105
-
104
+
106
105
  def fill_in_backtrace_lines(x)
107
106
  exception.backtrace.each do |unparsed_line|
108
107
  _, file, number, method = unparsed_line.match(INPUT_FORMAT).to_a
@@ -25,7 +25,7 @@ module Resque
25
25
  end
26
26
 
27
27
  def self.clear
28
- Resque.redis.delete('resque:failed')
28
+ Resque.redis.del(:failed)
29
29
  end
30
30
 
31
31
  end
@@ -23,7 +23,11 @@ module Resque
23
23
  if defined? Yajl
24
24
  Yajl::Parser.parse(object, :check_utf8 => false)
25
25
  else
26
- JSON.parse(object)
26
+ begin
27
+ JSON.parse(object)
28
+ rescue JSON::ParserError
29
+ logger.error "#{$!}"
30
+ end
27
31
  end
28
32
  end
29
33
 
@@ -50,6 +50,8 @@ module Resque
50
50
  # Removes a job from a queue. Expects a string queue name, a
51
51
  # string class name, and, optionally, args.
52
52
  #
53
+ # Returns the number of jobs destroyed.
54
+ #
53
55
  # If no args are provided, it will remove all jobs of the class
54
56
  # provided.
55
57
  #
@@ -72,6 +74,7 @@ module Resque
72
74
  def self.destroy(queue, klass, *args)
73
75
  klass = klass.to_s
74
76
  queue = "queue:#{queue}"
77
+ destroyed = 0
75
78
 
76
79
  redis.lrange(queue, 0, -1).each do |string|
77
80
  json = decode(string)
@@ -80,9 +83,11 @@ module Resque
80
83
  match &= json['args'] == args unless args.empty?
81
84
 
82
85
  if match
83
- redis.lrem(queue, 0, string)
86
+ destroyed += redis.lrem(queue, 0, string).to_i
84
87
  end
85
88
  end
89
+
90
+ destroyed
86
91
  end
87
92
 
88
93
  # Given a string queue name, returns an instance of Resque::Job
@@ -32,13 +32,14 @@ module Resque
32
32
  request.env['SCRIPT_NAME']
33
33
  end
34
34
 
35
- def class_if_current(page = '')
36
- 'class="current"' if current_page.include? page.to_s
35
+ def class_if_current(path = '')
36
+ 'class="current"' if current_page.start_with?(path.to_s)
37
37
  end
38
38
 
39
39
  def tab(name)
40
40
  dname = name.to_s.downcase
41
- "<li #{class_if_current(dname)}><a href='#{url dname}'>#{name}</a></li>"
41
+ path = url(dname)
42
+ "<li #{class_if_current(path)}><a href='#{path}'>#{name}</a></li>"
42
43
  end
43
44
 
44
45
  def tabs
@@ -55,19 +56,23 @@ module Resque
55
56
  Resque.redis.scard(key)
56
57
  when 'string'
57
58
  Resque.redis.get(key).length
59
+ when 'zset'
60
+ Resque.redis.zcard(key)
58
61
  end
59
62
  end
60
63
 
61
- def redis_get_value_as_array(key)
64
+ def redis_get_value_as_array(key, start=0)
62
65
  case Resque.redis.type(key)
63
66
  when 'none'
64
67
  []
65
68
  when 'list'
66
- Resque.redis.lrange(key, 0, 20)
69
+ Resque.redis.lrange(key, start, start + 20)
67
70
  when 'set'
68
- Resque.redis.smembers(key)
71
+ Resque.redis.smembers(key)[start..(start + 20)]
69
72
  when 'string'
70
73
  [Resque.redis.get(key)]
74
+ when 'zset'
75
+ Resque.redis.zrange(key, start, start + 20)
71
76
  end
72
77
  end
73
78
 
@@ -85,7 +90,7 @@ module Resque
85
90
  ensure
86
91
  @partial = false
87
92
  end
88
-
93
+
89
94
  def poll
90
95
  if @polling
91
96
  text = "Last Updated: #{Time.now.strftime("%H:%M:%S")}"
@@ -94,7 +99,7 @@ module Resque
94
99
  end
95
100
  "<p class='poll'>#{text}</p>"
96
101
  end
97
-
102
+
98
103
  end
99
104
 
100
105
  def show(page, layout = true)
@@ -119,7 +124,7 @@ module Resque
119
124
  show page
120
125
  end
121
126
  end
122
-
127
+
123
128
  %w( overview workers ).each do |page|
124
129
  get "/#{page}.poll" do
125
130
  content_type "text/plain"
@@ -135,7 +140,7 @@ module Resque
135
140
  show :failed
136
141
  end
137
142
  end
138
-
143
+
139
144
  post "/failed/clear" do
140
145
  Resque::Failure.clear
141
146
  redirect u('failed')
@@ -31,8 +31,9 @@ body { padding:0; margin:0; }
31
31
 
32
32
  #main table.queues { width:40%;}
33
33
  #main table.queues td.queue { font-weight:bold; width:50%;}
34
- #main table.queues tr.failed td { background:#ffecec; border-top:2px solid #d37474; font-size:90%; color:#d37474;}
35
- #main table.queues tr.failed td a{ color:#d37474;}
34
+ #main table.queues tr.failed td { border-top:2px solid; font-size:90%; }
35
+ #main table.queues tr.failure td { background:#ffecec; border-top:2px solid #d37474; font-size:90%; color:#d37474;}
36
+ #main table.queues tr.failure td a{ color:#d37474;}
36
37
 
37
38
  #main table.jobs td.class { font-family:Monaco, "Courier New", monospace; font-size:90%; width:50%;}
38
39
  #main table.jobs td.args{ width:50%;}
@@ -0,0 +1,20 @@
1
+ <% if key = params[:key] %>
2
+
3
+ <p class='sub'>
4
+ Showing <%= start = params[:start].to_i %> to <%= start + 20 %> of <b><%=size = redis_get_size(key) %></b>
5
+ </p>
6
+
7
+
8
+ <h1>Key "<%= key %>" is a <%= resque.redis.type key %></h1>
9
+ <table>
10
+ <% for row in redis_get_value_as_array(key, start) %>
11
+ <tr>
12
+ <td>
13
+ <%= row %>
14
+ </td>
15
+ </tr>
16
+ <% end %>
17
+ </table>
18
+
19
+ <%= partial :next_more, :start => start, :size => size %>
20
+ <% end %>
@@ -1,17 +1,11 @@
1
1
  <% if key = params[:key] %>
2
-
3
2
  <h1>Key "<%= key %>" is a <%= resque.redis.type key %></h1>
4
3
  <h2>size: <%= redis_get_size(key) %></h2>
5
4
  <table>
6
- <% for row in redis_get_value_as_array(key) %>
7
5
  <tr>
8
6
  <td>
9
- <%= row %>
7
+ <%= redis_get_value_as_array(key) %>
10
8
  </td>
11
9
  </tr>
12
- <% end %>
13
10
  </table>
14
-
15
- <% else %>
16
-
17
- <% end %>
11
+ <% end %>
@@ -37,10 +37,10 @@
37
37
  <td class='size'><%= resque.size queue %></td>
38
38
  </tr>
39
39
  <% end %>
40
- <tr class='failed'>
40
+ <tr class="<%= Resque::Failure.count.zero? ? "failed" : "failure" %>">
41
41
  <td class='queue failed'><a class="queue" href="<%= url :failed %>">failed</a></td>
42
42
  <td class='size'><%= Resque::Failure.count %></td>
43
43
  </tr>
44
44
  </table>
45
45
 
46
- <% end %>
46
+ <% end %>
@@ -2,7 +2,7 @@
2
2
 
3
3
  <% if params[:key] %>
4
4
 
5
- <%= partial :key %>
5
+ <%= partial resque.redis.type(params[:key]).eql?("string") ? :key_string : :key_sets %>
6
6
 
7
7
  <% elsif params[:id] == "resque" %>
8
8
 
@@ -59,4 +59,4 @@
59
59
 
60
60
  <% else %>
61
61
 
62
- <% end %>
62
+ <% end %>
@@ -24,7 +24,7 @@ namespace :resque do
24
24
  worker.work(ENV['INTERVAL'] || 5) # interval, will block
25
25
  end
26
26
 
27
- desc "Start multiple Resque workers"
27
+ desc "Start multiple Resque workers. Should only be used in dev mode."
28
28
  task :workers do
29
29
  threads = []
30
30
 
@@ -1,3 +1,3 @@
1
1
  module Resque
2
- Version = '1.5.0'
2
+ Version = '1.5.1'
3
3
  end
@@ -79,9 +79,9 @@ context "Resque" do
79
79
  assert Resque::Job.create(:jobs, 'BadJob', 20, '/tmp')
80
80
 
81
81
  assert_equal 5, Resque.size(:jobs)
82
- Resque::Job.destroy(:jobs, 'SomeJob')
82
+ assert_equal 2, Resque::Job.destroy(:jobs, 'SomeJob')
83
83
  assert_equal 3, Resque.size(:jobs)
84
- Resque::Job.destroy(:jobs, 'BadJob', 30, '/tmp')
84
+ assert_equal 1, Resque::Job.destroy(:jobs, 'BadJob', 30, '/tmp')
85
85
  assert_equal 2, Resque.size(:jobs)
86
86
  end
87
87
 
@@ -217,4 +217,8 @@ context "Resque" do
217
217
  assert_equal 1, stats[:failed]
218
218
  assert_equal ['localhost:9736'], stats[:servers]
219
219
  end
220
+
221
+ test "decode bad json" do
222
+ assert_nil Resque.decode("{\"error\":\"Module not found \\u002\"}")
223
+ end
220
224
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resque
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Wanstrath
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-17 00:00:00 -08:00
12
+ date: 2010-03-03 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -115,7 +115,8 @@ files:
115
115
  - lib/resque/server/public/working.png
116
116
  - lib/resque/server/views/error.erb
117
117
  - lib/resque/server/views/failed.erb
118
- - lib/resque/server/views/key.erb
118
+ - lib/resque/server/views/key_sets.erb
119
+ - lib/resque/server/views/key_string.erb
119
120
  - lib/resque/server/views/layout.erb
120
121
  - lib/resque/server/views/next_more.erb
121
122
  - lib/resque/server/views/overview.erb