resque 1.11.0 → 1.12.0

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.

data/HISTORY.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## 1.12.0 (2011-02-03)
2
+
3
+ * Added pidfile writing from `rake resque:work`
4
+ * Added Worker#pid method
5
+ * Added configurable location for `rake install`
6
+ * Bugfix: Errors in failure backend are rescue'd
7
+ * Bugfix: Non-working workers no longer counted in "working" count
8
+ * Bugfix: Don't think resque-web is a worker
9
+
1
10
  ## 1.11.0 (2010-08-23)
2
11
 
3
12
  * Web UI: Group /workers page by hostnames
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009 Chris Wanstrath
1
+ Copyright (c) 2009, 2010 Chris Wanstrath
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.markdown CHANGED
@@ -1,8 +1,9 @@
1
1
  Resque
2
2
  ======
3
3
 
4
- Resque is a Redis-backed library for creating background jobs, placing
5
- those jobs on multiple queues, and processing them later.
4
+ Resque (pronounced like "rescue") is a Redis-backed library for creating
5
+ background jobs, placing those jobs on multiple queues, and processing
6
+ them later.
6
7
 
7
8
  Background jobs can be any Ruby class or module that responds to
8
9
  `perform`. Your existing classes can easily be converted to background
@@ -234,6 +235,13 @@ variable.
234
235
 
235
236
  $ VVERBOSE=1 QUEUE=file_serve rake environment resque:work
236
237
 
238
+ ### Process IDs (PIDs)
239
+
240
+ There are scenarios where it's helpful to record the PID of a resque
241
+ worker process. Use the PIDFILE option for easy access to the PID:
242
+
243
+ $ PIDFILE=./resque.pid QUEUE=file_serve rake environment resque:work
244
+
237
245
 
238
246
  ### Priorities and Queue Lists
239
247
 
@@ -419,7 +427,8 @@ You can also set the namespace directly using `resque-web`:
419
427
  Using Passenger? Resque ships with a `config.ru` you can use. See
420
428
  Phusion's guide:
421
429
 
422
- <http://www.modrails.com/documentation/Users%20guide.html#_deploying_a_rack_based_ruby_application>
430
+ Apache: <http://www.modrails.com/documentation/Users%20guide%20Apache.html#_deploying_a_rack_based_ruby_application>
431
+ Nginx: <http://www.modrails.com/documentation/Users%20guide%20Nginx.html#deploying_a_rack_app>
423
432
 
424
433
  ### Rack::URLMap
425
434
 
@@ -764,7 +773,7 @@ To join the list simply send an email to <resque@librelist.com>. This
764
773
  will subscribe you and send you information about your subscription,
765
774
  including unsubscribe information.
766
775
 
767
- The archive can be found at <http://librelist.com/browser/>.
776
+ The archive can be found at <http://librelist.com/browser/resque/>.
768
777
 
769
778
 
770
779
  Meta
@@ -26,8 +26,11 @@ module Resque
26
26
  INPUT_FORMAT = /^([^:]+):(\d+)(?::in `([^']+)')?$/
27
27
 
28
28
  class << self
29
- attr_accessor :secure, :api_key, :proxy_host, :proxy_port
29
+ attr_accessor :secure, :api_key
30
+ attr_accessor :proxy_host, :proxy_port, :proxy_user, :proxy_pass
30
31
  attr_accessor :server_environment
32
+ attr_accessor :host, :port
33
+ attr_accessor :http_read_timeout, :http_open_timeout
31
34
  end
32
35
 
33
36
  def self.count
@@ -43,17 +46,20 @@ module Resque
43
46
 
44
47
  def save
45
48
  http = use_ssl? ? :https : :http
46
- url = URI.parse("#{http}://hoptoadapp.com/notifier_api/v2/notices")
49
+ host = self.class.host || 'hoptoadapp.com'
50
+ port = self.class.port
51
+ url = URI.parse("#{http}://#{host}:#{port}/notifier_api/v2/notices/")
47
52
 
48
- request = Net::HTTP::Proxy(self.class.proxy_host, self.class.proxy_port)
53
+ request = Net::HTTP::Proxy self.class.proxy_host, self.class.proxy_port,
54
+ self.class.proxy_user, self.class.proxy_pass
49
55
  http = request.new(url.host, url.port)
50
56
  headers = {
51
57
  'Content-type' => 'text/xml',
52
58
  'Accept' => 'text/xml, application/xml'
53
59
  }
54
60
 
55
- http.read_timeout = 5 # seconds
56
- http.open_timeout = 2 # seconds
61
+ http.read_timeout = self.class.http_read_timeout || 5 # seconds
62
+ http.open_timeout = self.class.http_open_timeout || 2 # seconds
57
63
 
58
64
  http.use_ssl = use_ssl?
59
65
 
data/lib/resque/server.rb CHANGED
@@ -147,7 +147,7 @@ module Resque
147
147
 
148
148
  %w( overview workers ).each do |page|
149
149
  get "/#{page}.poll" do
150
- content_type "text/plain"
150
+ content_type "text/html"
151
151
  @polling = true
152
152
  show(page.to_sym, false).gsub(/\s{1,}/, ' ')
153
153
  end
@@ -201,7 +201,7 @@ module Resque
201
201
  stats << "queues.#{queue}=#{Resque.size(queue)}"
202
202
  end
203
203
 
204
- content_type 'text/plain'
204
+ content_type 'text/html'
205
205
  stats.join "\n"
206
206
  end
207
207
 
@@ -1,4 +1,4 @@
1
- <% @subtabs = resque.queues unless partial? %>
1
+ <% @subtabs = resque.queues unless partial? || params[:id].nil? %>
2
2
 
3
3
  <% if queue = params[:id] %>
4
4
 
@@ -85,7 +85,7 @@
85
85
  <%=poll%>
86
86
 
87
87
  <% else %>
88
-
88
+ <% @subtabs = [] %>
89
89
  <h1 class='wi'>Workers</h1>
90
90
  <p class='intro'>The hostnames below all have registered workers. Select a hostname to view its workers, or "all" to see all workers.</p>
91
91
  <table class='queues'>
@@ -93,7 +93,7 @@
93
93
  <th>Hostname</th>
94
94
  <th>Workers</th>
95
95
  </tr>
96
- <% for hostname, workers in worker_hosts %>
96
+ <% for hostname, workers in worker_hosts.sort_by { |h,w| h } %>
97
97
  <tr>
98
98
  <td class='queue'><a class="queue" href="<%= url "workers/#{hostname}" %>"><%= hostname %></a></td>
99
99
  <td class='size'><%= workers.size %></td>
data/lib/resque/tasks.rb CHANGED
@@ -8,7 +8,6 @@ namespace :resque do
8
8
  task :work => :setup do
9
9
  require 'resque'
10
10
 
11
- worker = nil
12
11
  queues = (ENV['QUEUES'] || ENV['QUEUE']).to_s.split(',')
13
12
 
14
13
  begin
@@ -19,6 +18,10 @@ namespace :resque do
19
18
  abort "set QUEUE env var, e.g. $ QUEUE=critical,high rake resque:work"
20
19
  end
21
20
 
21
+ if ENV['PIDFILE']
22
+ File.open(ENV['PIDFILE'], 'w') { |f| f << Process.pid.to_s }
23
+ end
24
+
22
25
  worker.log "Starting worker #{worker}"
23
26
 
24
27
  worker.work(ENV['INTERVAL'] || 5) # interval, will block
@@ -1,3 +1,3 @@
1
1
  module Resque
2
- Version = VERSION = '1.11.0'
2
+ Version = VERSION = '1.12.0'
3
3
  end
data/lib/resque/worker.rb CHANGED
@@ -32,8 +32,13 @@ module Resque
32
32
  def self.working
33
33
  names = all
34
34
  return [] unless names.any?
35
+
35
36
  names.map! { |name| "worker:#{name}" }
36
- redis.mapped_mget(*names).keys.map do |key|
37
+
38
+ reportedly_working = redis.mapped_mget(*names).reject do |key, value|
39
+ value.nil?
40
+ end
41
+ reportedly_working.keys.map do |key|
37
42
  find key.sub("worker:", '')
38
43
  end.compact
39
44
  end
@@ -73,7 +78,7 @@ module Resque
73
78
  # in alphabetical order. Queues can be dynamically added or
74
79
  # removed without needing to restart workers using this method.
75
80
  def initialize(*queues)
76
- @queues = queues
81
+ @queues = queues.map { |queue| queue.to_s.strip }
77
82
  validate_queues
78
83
  end
79
84
 
@@ -157,7 +162,11 @@ module Resque
157
162
  job.perform
158
163
  rescue Object => e
159
164
  log "#{job.inspect} failed: #{e.inspect}"
160
- job.fail(e)
165
+ begin
166
+ job.fail(e)
167
+ rescue Object => e
168
+ log "Received exception when reporting failure: #{e.inspect}"
169
+ end
161
170
  failed!
162
171
  else
163
172
  log "done: #{job.inspect}"
@@ -178,6 +187,10 @@ module Resque
178
187
  end
179
188
 
180
189
  nil
190
+ rescue Exception => e
191
+ log "Error reserving job: #{e.inspect}"
192
+ log e.backtrace.join("\n")
193
+ raise e
181
194
  end
182
195
 
183
196
  # Returns a list of queues to use when searching for a job.
@@ -440,7 +453,7 @@ module Resque
440
453
  # The string representation is the same as the id for this worker
441
454
  # instance. Can be used with `Worker.find`.
442
455
  def to_s
443
- @to_s ||= "#{hostname}:#{Process.pid}:#{@queues.join(',')}"
456
+ @to_s ||= "#{hostname}:#{pid}:#{@queues.join(',')}"
444
457
  end
445
458
  alias_method :id, :to_s
446
459
 
@@ -449,10 +462,15 @@ module Resque
449
462
  @hostname ||= `hostname`.chomp
450
463
  end
451
464
 
465
+ # Returns PID of running worker
466
+ def pid
467
+ @pid ||= Process.pid
468
+ end
469
+
452
470
  # Returns an array of string pids of all the other workers on this
453
471
  # machine. Useful when pruning dead workers on startup.
454
472
  def worker_pids
455
- `ps -A -o pid,command | grep [r]esque`.split("\n").map do |line|
473
+ `ps -A -o pid,command | grep [r]esque | grep -i "resque-web"`.split("\n").map do |line|
456
474
  line.split(' ')[0]
457
475
  end
458
476
  end
data/tasks/redis.rake CHANGED
@@ -4,7 +4,6 @@ require 'open-uri'
4
4
  require 'pathname'
5
5
 
6
6
  class RedisRunner
7
-
8
7
  def self.redis_dir
9
8
  @redis_dir ||= if ENV['PREFIX']
10
9
  Pathname.new(ENV['PREFIX'])
@@ -48,11 +47,11 @@ class RedisRunner
48
47
  def self.stop
49
48
  sh 'echo "SHUTDOWN" | nc localhost 6379'
50
49
  end
51
-
52
50
  end
53
51
 
54
- namespace :redis do
52
+ INSTALL_DIR = ENV['INSTALL_DIR'] || '/tmp/redis'
55
53
 
54
+ namespace :redis do
56
55
  desc 'About redis'
57
56
  task :about do
58
57
  puts "\nSee http://code.google.com/p/redis/ for information about redis.\n\n"
@@ -79,7 +78,12 @@ namespace :redis do
79
78
  RedisRunner.attach
80
79
  end
81
80
 
82
- desc 'Install the latest verison of Redis from Github (requires git, duh)'
81
+ desc <<-DOC
82
+ Install the latest verison of Redis from Github (requires git, duh).
83
+ Use INSTALL_DIR env var like "rake redis:install INSTALL_DIR=~/tmp"
84
+ in order to get an alternate location for your install files.
85
+ DOC
86
+
83
87
  task :install => [:about, :download, :make] do
84
88
  bin_dir = '/usr/bin'
85
89
  conf_dir = '/etc'
@@ -93,33 +97,31 @@ namespace :redis do
93
97
  end
94
98
 
95
99
  %w(redis-benchmark redis-cli redis-server).each do |bin|
96
- sh "cp /tmp/redis/src/#{bin} #{bin_dir}"
100
+ sh "cp #{INSTALL_DIR}/src/#{bin} #{bin_dir}"
97
101
  end
98
102
 
99
103
  puts "Installed redis-benchmark, redis-cli and redis-server to #{bin_dir}"
100
104
 
101
105
  unless File.exists?("#{conf_dir}/redis.conf")
102
- sh "cp /tmp/redis/redis.conf #{conf_dir}/redis.conf"
106
+ sh "cp #{INSTALL_DIR}/redis.conf #{conf_dir}/redis.conf"
103
107
  puts "Installed redis.conf to #{conf_dir} \n You should look at this file!"
104
108
  end
105
109
  end
106
110
 
107
111
  task :make do
108
- sh "cd /tmp/redis/src && make clean"
109
- sh "cd /tmp/redis/src && make"
112
+ sh "cd #{INSTALL_DIR}/src && make clean"
113
+ sh "cd #{INSTALL_DIR}/src && make"
110
114
  end
111
115
 
112
116
  desc "Download package"
113
117
  task :download do
114
- sh 'rm -rf /tmp/redis/' if File.exists?("/tmp/redis/.svn")
115
- sh 'git clone git://github.com/antirez/redis.git /tmp/redis' unless File.exists?('/tmp/redis')
116
- sh "cd /tmp/redis && git pull" if File.exists?("/tmp/redis/.git")
118
+ sh "rm -rf #{INSTALL_DIR}/" if File.exists?("#{INSTALL_DIR}/.svn")
119
+ sh "git clone git://github.com/antirez/redis.git #{INSTALL_DIR}" unless File.exists?(INSTALL_DIR)
120
+ sh "cd #{INSTALL_DIR} && git pull" if File.exists?("#{INSTALL_DIR}/.git")
117
121
  end
118
-
119
122
  end
120
123
 
121
124
  namespace :dtach do
122
-
123
125
  desc 'About dtach'
124
126
  task :about do
125
127
  puts "\nSee http://dtach.sourceforge.net/ for information about dtach.\n\n"
@@ -130,30 +132,30 @@ namespace :dtach do
130
132
 
131
133
  bin_dir = "/usr/bin"
132
134
 
135
+
133
136
  if ENV['PREFIX']
134
137
  bin_dir = "#{ENV['PREFIX']}/bin"
135
138
  sh "mkdir -p #{bin_dir}" unless File.exists?("#{bin_dir}")
136
139
  end
137
140
 
138
- sh "cp /tmp/dtach-0.8/dtach #{bin_dir}"
141
+ sh "cp #{INSTALL_DIR}/dtach-0.8/dtach #{bin_dir}"
139
142
  end
140
143
 
141
144
  task :make do
142
- sh 'cd /tmp/dtach-0.8/ && ./configure && make'
145
+ sh "cd #{INSTALL_DIR}/dtach-0.8/ && ./configure && make"
143
146
  end
144
147
 
145
148
  desc "Download package"
146
149
  task :download do
147
- unless File.exists?('/tmp/dtach-0.8.tar.gz')
150
+ unless File.exists?("#{INSTALL_DIR}/dtach-0.8.tar.gz")
148
151
  require 'net/http'
149
152
 
150
153
  url = 'http://downloads.sourceforge.net/project/dtach/dtach/0.8/dtach-0.8.tar.gz'
151
- open('/tmp/dtach-0.8.tar.gz', 'wb') do |file| file.write(open(url).read) end
154
+ open("#{INSTALL_DIR}/dtach-0.8.tar.gz", 'wb') do |file| file.write(open(url).read) end
152
155
  end
153
156
 
154
- unless File.directory?('/tmp/dtach-0.8')
155
- sh 'cd /tmp && tar xzf dtach-0.8.tar.gz'
157
+ unless File.directory?("#{INSTALL_DIR}/dtach-0.8")
158
+ sh "cd #{INSTALL_DIR} && tar xzf dtach-0.8.tar.gz"
156
159
  end
157
160
  end
158
161
  end
159
-
data/test/test_helper.rb CHANGED
@@ -114,3 +114,17 @@ class BadJobWithSyntaxError
114
114
  raise SyntaxError, "Extra Bad job!"
115
115
  end
116
116
  end
117
+
118
+ class BadFailureBackend < Resque::Failure::Base
119
+ def save
120
+ raise Exception.new("Failure backend error")
121
+ end
122
+ end
123
+
124
+ def with_failure_backend(failure_backend, &block)
125
+ previous_backend = Resque::Failure.backend
126
+ Resque::Failure.backend = failure_backend
127
+ yield block
128
+ ensure
129
+ Resque::Failure.backend = previous_backend
130
+ end
data/test/worker_test.rb CHANGED
@@ -25,6 +25,13 @@ context "Resque::Worker" do
25
25
  assert_equal('Extra Bad job!', Resque::Failure.all['error'])
26
26
  end
27
27
 
28
+ test "does not allow exceptions from failure backend to escape" do
29
+ job = Resque::Job.new(:jobs, {})
30
+ with_failure_backend BadFailureBackend do
31
+ @worker.perform job
32
+ end
33
+ end
34
+
28
35
  test "fails uncompleted jobs on exit" do
29
36
  job = Resque::Job.new(:jobs, [GoodJob, "blah"])
30
37
  @worker.working_on(job)
@@ -57,6 +64,12 @@ context "Resque::Worker" do
57
64
  assert_equal 2, Resque::Failure.count
58
65
  end
59
66
 
67
+ test "strips whitespace from queue names" do
68
+ queues = "critical, high, low".split(',')
69
+ worker = Resque::Worker.new(*queues)
70
+ assert_equal %w( critical high low ), worker.queues
71
+ end
72
+
60
73
  test "can work on multiple queues" do
61
74
  Resque::Job.create(:high, GoodJob)
62
75
  Resque::Job.create(:critical, GoodJob)
@@ -299,4 +312,8 @@ context "Resque::Worker" do
299
312
  workerA.work(0)
300
313
  assert $AFTER_FORK_CALLED
301
314
  end
315
+
316
+ test "returns PID of running process" do
317
+ assert_equal Process.pid, @worker.pid
318
+ end
302
319
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resque
3
3
  version: !ruby/object:Gem::Version
4
- hash: 59
4
+ hash: 39
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
- - 11
8
+ - 12
9
9
  - 0
10
- version: 1.11.0
10
+ version: 1.12.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Chris Wanstrath