resque 1.27.0 → 2.1.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.

Files changed (41) hide show
  1. checksums.yaml +5 -5
  2. data/HISTORY.md +97 -3
  3. data/README.markdown +437 -485
  4. data/bin/resque-web +1 -1
  5. data/lib/resque/data_store.rb +25 -19
  6. data/lib/resque/errors.rb +7 -1
  7. data/lib/resque/failure/airbrake.rb +19 -7
  8. data/lib/resque/failure/multiple.rb +6 -2
  9. data/lib/resque/failure/redis.rb +1 -1
  10. data/lib/resque/failure/redis_multi_queue.rb +3 -3
  11. data/lib/resque/failure.rb +1 -0
  12. data/lib/resque/job.rb +2 -2
  13. data/lib/resque/logging.rb +1 -1
  14. data/lib/resque/railtie.rb +10 -0
  15. data/lib/resque/server/public/jquery-3.6.0.min.js +2 -0
  16. data/lib/resque/server/public/main.js +3 -0
  17. data/lib/resque/server/public/ranger.js +7 -4
  18. data/lib/resque/server/public/style.css +5 -5
  19. data/lib/resque/server/test_helper.rb +1 -1
  20. data/lib/resque/server/views/failed.erb +2 -2
  21. data/lib/resque/server/views/failed_job.erb +3 -3
  22. data/lib/resque/server/views/job_class.erb +6 -0
  23. data/lib/resque/server/views/layout.erb +3 -2
  24. data/lib/resque/server/views/next_more.erb +14 -14
  25. data/lib/resque/server/views/processing.erb +2 -0
  26. data/lib/resque/server/views/queues.erb +7 -7
  27. data/lib/resque/server/views/stats.erb +1 -1
  28. data/lib/resque/server/views/workers.erb +2 -4
  29. data/lib/resque/server/views/working.erb +7 -8
  30. data/lib/resque/server.rb +7 -9
  31. data/lib/resque/stat.rb +12 -5
  32. data/lib/resque/tasks.rb +1 -9
  33. data/lib/resque/thread_signal.rb +13 -34
  34. data/lib/resque/vendor/utf8_util.rb +2 -8
  35. data/lib/resque/version.rb +1 -1
  36. data/lib/resque/worker.rb +91 -44
  37. data/lib/resque.rb +93 -19
  38. metadata +14 -13
  39. data/lib/resque/server/public/jquery-1.12.4.min.js +0 -5
  40. data/lib/resque/vendor/utf8_util/utf8_util_18.rb +0 -91
  41. data/lib/resque/vendor/utf8_util/utf8_util_19.rb +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: b5f0cb00378f55254a8f68c68fed023ea569e1a8
4
- data.tar.gz: bf7219b392370ef84f16ab57ff3646c64544a17d
2
+ SHA256:
3
+ metadata.gz: b930a952313756e06d51bb6daa493ebeed0c4498940e46d24300f7fafdac36b3
4
+ data.tar.gz: ea821158f150dbf5740dff8cb210be0f7507c1e183acd3a902308f0ef91e7f2c
5
5
  SHA512:
6
- metadata.gz: fd8e4634086ea6c5f5147799d35596924abb49a71fa1c99223017c4ade6b24b5afba32f2e70985b18af6493530fd554ecd76947a7f7ff04f32e5aeb43c707477
7
- data.tar.gz: 484db5ed7b0b3be036c9523a2720a16edaa43748a65d34a2add2932784fc37440e0922596529b229d471177c03599df65ab7d57b980b99850c39ab98dfe26e4f
6
+ metadata.gz: d266f8019b93add5de76d0d3e5a460c2a03c3fc04b3d71c65f296269c7e286875b6b1925d31d01699c952d14319164cab39062f9310314fed0b4229b92f47821
7
+ data.tar.gz: d375348987a655202483adb5eccb253ed07eea17d88749c04837e0ec05dad948805cb371500ac42b11650595327875f0af56e9c3501261e8223f6c1fbfff5f5f
data/HISTORY.md CHANGED
@@ -1,14 +1,108 @@
1
- ## 1.28.0 (TBD)
1
+ ## Unreleased
2
2
 
3
+ ### Added
3
4
 
4
- ## 1.27.0 (2017-02-08)
5
+ *
6
+ *
7
+
8
+ ### Fixed
9
+
10
+ *
11
+ *
12
+
13
+ ## 2.1.0
14
+
15
+ ### Security
16
+
17
+ * Fix XSS via URL path in admin web UI queues view #1687
18
+ * Replace onclick handlers in server code to support Content Security Policies that don't allow 'unsafe-inline'
19
+ * Update jQuery from 1.12.4 to 3.6.0
20
+
21
+ ### Added
22
+
23
+ * Add requeue_queue method to Resque::Failure::Multiple #1659
24
+ * Confirmation prompt in admin front-end before submitting the retry of all failed jobs. #1753
25
+ * Railtie for default rake task setup when in Rails. #1715
26
+ * Added two new hooks.
27
+ - `queue_empty` when the job queue empties and the worker becomes idle
28
+ - `worker_exit` when the worker exits
29
+
30
+ See [docs/HOOKS.md](http://github.com/resque/resque/blob/master/docs/HOOKS.md) for
31
+ further details. (@jeremywadsack)
32
+
33
+ ### Fixed
34
+
35
+ * live poller shouldn't restart itself until it successds or fails. #1740
36
+ * Fix parsing worker_id when queue name includes colon. #1691
37
+ * Prune workers which haven't been registered but have set a heartbeat. #1751
38
+ * `Resque::Failure::Multiple.remove` did not pass on the queue parameter
39
+
40
+ ## 2.0.0 (2018-11-06)
41
+
42
+ ### Fixed
43
+ * Fix Airbrake failure backend
44
+ * Fix failed jobs page "argument out of range" error
5
45
 
6
- * Update jQuery from 1.3.2 to 1.12.4
46
+ ### Changed
47
+ * Remove support for Rubies < 2.3
48
+ * Remove support to Rails < 4
49
+ * Reduce the number of redis calls when trying to get the list of queues
50
+ * Only run `eager_load!` if `Rails.application.config.eager_load` is true
51
+ * Don't display log message if running without hooks
52
+ * Add Support to Redis 4.0
53
+ * Drop complex Redis identifier logic in favor of simple inspect
54
+ * When a child process is killed, report the signal it was terminated with
55
+ * Report a job that pruned worker was processing
56
+
57
+ ### Added
58
+
59
+ * Allow to configure statistic data store
60
+
61
+ ## 1.27.4 (2017-04-15)
62
+
63
+ ### Fixed
64
+ * Fix issue where removing a failure from Resque web didn't work when using `RedisMultiQueue` backend.
65
+
66
+ ## 1.27.3 (2017-04-10)
67
+
68
+ ### Fixed
69
+ * Fix issue where initializing a data store would attempt to hit Redis, even when Resque.inline = true
70
+
71
+ ## 1.27.2 (2017-02-20)
72
+
73
+ ### Fixed
74
+ * Require "redis/distributed" in worker.rb to allow proper rescuing
75
+ * Fallback to server time if Redis time won't work (restores Redis 2.4 support)
76
+
77
+ ## 1.27.1 (2017-02-13)
78
+
79
+ ### Fixed
80
+ * Show actual jobs names in web view using ActiveJob (@martnst)
81
+
82
+ ## 1.27.0 (2017-02-08)
7
83
 
84
+ ### Fixed
8
85
  * Fix issue where calling Worker.find, Worker.all, or Worker.working from withing
9
86
  a running job would rewrite the PID file with the PID of the forked worker.
10
87
  This causes a change to the Worker#new API that may affect plugin
11
88
  implementations. See Worker#new and Worker#prepare for details. (@jeremywadsack)
89
+ * Workers queried out now have the correct hostname (@crazymykl)
90
+ * Fix race condition on worker startup (@stevedomin)
91
+ * No longer triggers verbose logging if env variables are not set (@ldnunes)
92
+ * resque/failed/requeue/all when using Redis::Failure::Multiple no longer raises an exception (@ale7714)
93
+ * Improve forking to avoid having a child process escape its code (@dylanahsmith)
94
+ * Workers now use server time rather than their own time to maintain heartbeats (@fw42)
95
+ * Run eager load hooks for Rails applications versioned 4.x and up (@abhi-patel)
96
+ * Fix bug when encountering an error while pruning workers (Joakim Kolsjö and Tomas Skogberg)
97
+ * Children write to PIDFILE immediately after forking, fixing issues when reconnecting to Redis is slow (@fimmtiu)
98
+
99
+ ### Changed
100
+ * Update jQuery from 1.3.2 to 1.12.4 (@chrisccerami)
101
+ * No longer user Thread.kill to stop heartbeat (@Sinjo)
102
+
103
+ ### Added
104
+ * Resque Web UI now prompts for confirmation on clearing failed jobs (Markus Olsen)
105
+ * Adds process status to DirtyExit exception when job is killed via signal (@MishaConway)
12
106
 
13
107
  ## 1.26.0 (2016-03-10)
14
108
 
data/README.markdown CHANGED
@@ -2,13 +2,21 @@ Resque
2
2
  ======
3
3
 
4
4
  [![Gem Version](https://badge.fury.io/rb/resque.svg)](https://rubygems.org/gems/resque)
5
- [![Build Status](https://travis-ci.org/resque/resque.svg)](https://travis-ci.org/resque/resque)
6
- [![Coverage Status](https://coveralls.io/repos/github/resque/resque/badge.svg?branch=1-x-stable)](https://coveralls.io/r/resque/resque?branch=1-x-stable)
5
+ [![Build Status](https://github.com/resque/resque/actions/workflows/ci.yml/badge.svg)](https://github.com/resque/resque/actions/workflows/ci.yml)
7
6
 
8
7
  Resque (pronounced like "rescue") is a Redis-backed library for creating
9
8
  background jobs, placing those jobs on multiple queues, and processing
10
9
  them later.
11
10
 
11
+ ---------
12
+ ### Note on the future of this repo
13
+
14
+ Would you like to be involved in Resque? Do you have thoughts about what
15
+ Resque should be and do going forward? There's currently an [open discussion here](https://github.com/resque/resque/issues/1759)
16
+ on just that topic, so please feel free to join in. We'd love to hear your thoughts
17
+ and/or have people volunteer to be a part of the project!
18
+
19
+ ---------
12
20
  Background jobs can be any Ruby class or module that responds to
13
21
  `perform`. Your existing classes can easily be converted to background
14
22
  jobs or you can create new classes specifically to do work. Or, you
@@ -34,17 +42,43 @@ The Resque frontend tells you what workers are doing, what workers are
34
42
  not doing, what queues you're using, what's in those queues, provides
35
43
  general usage stats, and helps you track failures.
36
44
 
45
+ Resque now supports Ruby 2.3.0 and above.
46
+ We will also only be supporting Redis 3.0 and above going forward.
37
47
 
38
- The Blog Post
39
- -------------
40
48
 
41
- For the backstory, philosophy, and history of Resque's beginnings,
42
- please see [the blog post][0].
49
+ Table of Contents
50
+ -----------------
43
51
 
52
+ * [Overview](#overview)
53
+ * [Installation](#installation)
54
+ * [Running Workers](#running-workers)
55
+ * [The Front End](#the-front-end)
56
+ * [Jobs](#jobs)
57
+ * [Configuration](#configuration)
58
+ * * [Redis](#redis)
59
+ * * [Logging](#logging)
60
+ * * [Namespaces](#namespaces)
61
+ * * [Storing Statistics](#storing-statistics)
62
+ * [Plugins and Hooks](#plugins-and-hooks)
63
+ * [Additional Information](#additional-information)
64
+ * * [Resque vs DelayedJob](#resque-vs-delayedjob)
65
+ * * [Forking](#forking)
66
+ * * [Signals](#signals)
67
+ * * [Heroku](#heroku)
68
+ * * [Monitoring](#monitoring)
69
+ * * [Mysql::Error](#mysqlerror-mysql-server-has-gone-away)
70
+ * [Development](#development)
71
+ * * [Demo](#demo)
72
+ * * [Contributing](#contributing)
73
+ * [Questions](#questions)
74
+ * [Meta](#meta)
75
+ * [Author](#author)
44
76
 
45
77
  Overview
46
78
  --------
47
79
 
80
+ For the backstory, philosophy, and history of Resque's beginnings, please see [the blog post](http://github.com/blog/542-introducing-resque).
81
+
48
82
  Resque allows you to create jobs and place them on a queue, then,
49
83
  later, pull those jobs off the queue and process them.
50
84
 
@@ -110,6 +144,200 @@ Workers can be given multiple queues (a "queue list") and run on
110
144
  multiple machines. In fact they can be run anywhere with network
111
145
  access to the Redis server.
112
146
 
147
+ Installation
148
+ ------------
149
+
150
+ Add the gem to your Gemfile:
151
+
152
+ gem 'resque'
153
+
154
+ Next, install it with Bundler:
155
+
156
+ $ bundle
157
+
158
+ #### Rack
159
+
160
+ In your Rakefile, or some other file in `lib/tasks` (ex: `lib/tasks/resque.rake`), load the resque rake tasks:
161
+
162
+ ``` ruby
163
+ require 'resque'
164
+ require 'resque/tasks'
165
+ require 'your/app' # Include this line if you want your workers to have access to your application
166
+ ```
167
+
168
+ #### Rails 3+
169
+
170
+ To make resque specific changes, you can override the `resque:setup` job in `lib/tasks` (ex: `lib/tasks/resque.rake`). GitHub's setup task looks like this:
171
+
172
+ ``` ruby
173
+ task "resque:setup" => :environment do
174
+ Grit::Git.git_timeout = 10.minutes
175
+ end
176
+ ```
177
+
178
+ We don't want the `git_timeout` as high as 10 minutes in our web app,
179
+ but in the Resque workers it's fine.
180
+
181
+ Running Workers
182
+ ---------------
183
+
184
+ Resque workers are rake tasks that run forever. They basically do this:
185
+
186
+ ``` ruby
187
+ start
188
+ loop do
189
+ if job = reserve
190
+ job.process
191
+ else
192
+ sleep 5 # Polling frequency = 5
193
+ end
194
+ end
195
+ shutdown
196
+ ```
197
+
198
+ Starting a worker is simple:
199
+
200
+ $ QUEUE=* rake resque:work
201
+
202
+ Or, you can start multiple workers:
203
+
204
+ $ COUNT=2 QUEUE=* rake resque:workers
205
+
206
+ This will spawn two Resque workers, each in its own process. Hitting
207
+ ctrl-c should be sufficient to stop them all.
208
+
209
+ #### Priorities and Queue Lists
210
+
211
+ Resque doesn't support numeric priorities but instead uses the order
212
+ of queues you give it. We call this list of queues the "queue list."
213
+
214
+ Let's say we add a `warm_cache` queue in addition to our `file_serve`
215
+ queue. We'd now start a worker like so:
216
+
217
+ $ QUEUES=file_serve,warm_cache rake resque:work
218
+
219
+ When the worker looks for new jobs, it will first check
220
+ `file_serve`. If it finds a job, it'll process it then check
221
+ `file_serve` again. It will keep checking `file_serve` until no more
222
+ jobs are available. At that point, it will check `warm_cache`. If it
223
+ finds a job it'll process it then check `file_serve` (repeating the
224
+ whole process).
225
+
226
+ In this way you can prioritize certain queues. At GitHub we start our
227
+ workers with something like this:
228
+
229
+ $ QUEUES=critical,archive,high,low rake resque:work
230
+
231
+ Notice the `archive` queue - it is specialized and in our future
232
+ architecture will only be run from a single machine.
233
+
234
+ At that point we'll start workers on our generalized background
235
+ machines with this command:
236
+
237
+ $ QUEUES=critical,high,low rake resque:work
238
+
239
+ And workers on our specialized archive machine with this command:
240
+
241
+ $ QUEUE=archive rake resque:work
242
+
243
+ #### Running All Queues
244
+
245
+ If you want your workers to work off of every queue, including new
246
+ queues created on the fly, you can use a splat:
247
+
248
+ $ QUEUE=* rake resque:work
249
+
250
+ Queues will be processed in alphabetical order.
251
+
252
+ Or, prioritize some queues above `*`:
253
+
254
+ # QUEUE=critical,* rake resque:work
255
+
256
+ #### Process IDs (PIDs)
257
+
258
+ There are scenarios where it's helpful to record the PID of a resque
259
+ worker process. Use the PIDFILE option for easy access to the PID:
260
+
261
+ $ PIDFILE=./resque.pid QUEUE=file_serve rake resque:work
262
+
263
+ #### Running in the background
264
+
265
+ There are scenarios where it's helpful for
266
+ the resque worker to run itself in the background (usually in combination with
267
+ PIDFILE). Use the BACKGROUND option so that rake will return as soon as the
268
+ worker is started.
269
+
270
+ $ PIDFILE=./resque.pid BACKGROUND=yes QUEUE=file_serve rake resque:work
271
+
272
+ #### Polling frequency
273
+
274
+ You can pass an INTERVAL option which is a float representing the polling frequency.
275
+ The default is 5 seconds, but for a semi-active app you may want to use a smaller value.
276
+
277
+ $ INTERVAL=0.1 QUEUE=file_serve rake resque:work
278
+
279
+ The Front End
280
+ -------------
281
+
282
+ Resque comes with a Sinatra-based front end for seeing what's up with
283
+ your queue.
284
+
285
+ ![The Front End](https://camo.githubusercontent.com/64d150a243987ffbc33f588bd6d7722a0bb8d69a/687474703a2f2f7475746f7269616c732e6a756d7073746172746c61622e636f6d2f696d616765732f7265737175655f6f766572766965772e706e67)
286
+
287
+ #### Standalone
288
+
289
+ If you've installed Resque as a gem running the front end standalone is easy:
290
+
291
+ $ resque-web
292
+
293
+ It's a thin layer around `rackup` so it's configurable as well:
294
+
295
+ $ resque-web -p 8282
296
+
297
+ If you have a Resque config file you want evaluated just pass it to
298
+ the script as the final argument:
299
+
300
+ $ resque-web -p 8282 rails_root/config/initializers/resque.rb
301
+
302
+ You can also set the namespace directly using `resque-web`:
303
+
304
+ $ resque-web -p 8282 -N myapp
305
+
306
+ or set the Redis connection string if you need to do something like select a different database:
307
+
308
+ $ resque-web -p 8282 -r localhost:6379:2
309
+
310
+ #### Passenger
311
+
312
+ Using Passenger? Resque ships with a `config.ru` you can use. See
313
+ Phusion's guide:
314
+
315
+ Apache: <https://www.phusionpassenger.com/library/deploy/apache/deploy/ruby/>
316
+ Nginx: <https://www.phusionpassenger.com/library/deploy/nginx/deploy/ruby/>
317
+
318
+ #### Rack::URLMap
319
+
320
+ If you want to load Resque on a subpath, possibly alongside other
321
+ apps, it's easy to do with Rack's `URLMap`:
322
+
323
+ ``` ruby
324
+ require 'resque/server'
325
+
326
+ run Rack::URLMap.new \
327
+ "/" => Your::App.new,
328
+ "/resque" => Resque::Server.new
329
+ ```
330
+
331
+ Check `examples/demo/config.ru` for a functional example (including
332
+ HTTP basic auth).
333
+
334
+ #### Rails 3+
335
+
336
+ You can also mount Resque on a subpath in your existing Rails 3 app by adding `require 'resque/server'` to the top of your routes file or in an initializer then adding this to `routes.rb`:
337
+
338
+ ``` ruby
339
+ mount Resque::Server.new, :at => "/resque"
340
+ ```
113
341
 
114
342
  Jobs
115
343
  ----
@@ -136,8 +364,7 @@ mention "foreground" and "background" because they make conceptual
136
364
  sense. You could easily be spidering sites and sticking data which
137
365
  needs to be crunched later into a queue.
138
366
 
139
-
140
- ### Persistence
367
+ #### Persistence
141
368
 
142
369
  Jobs are persisted to queues as JSON objects. Let's take our `Archive`
143
370
  example from above. We'll run the following code to create a job:
@@ -182,7 +409,7 @@ If your jobs were run against marshaled objects, they could
182
409
  potentially be operating on a stale record with out-of-date information.
183
410
 
184
411
 
185
- ### send_later / async
412
+ #### send_later / async
186
413
 
187
414
  Want something like DelayedJob's `send_later` or the ability to use
188
415
  instance methods instead of just methods for jobs? See the `examples/`
@@ -191,11 +418,12 @@ directory for goodies.
191
418
  We plan to provide first class `async` support in a future release.
192
419
 
193
420
 
194
- ### Failure
421
+ #### Failure
195
422
 
196
423
  If a job raises an exception, it is logged and handed off to the
197
424
  `Resque::Failure` module. Failures are logged either locally in Redis
198
- or using some different backend.
425
+ or using some different backend. To see exceptions while developing,
426
+ see details below under Logging.
199
427
 
200
428
  For example, Resque ships with Airbrake support. To configure it, put
201
429
  the following into an initialisation file or into your rake job:
@@ -214,64 +442,98 @@ Keep this in mind when writing your jobs: you may want to throw
214
442
  exceptions you would not normally throw in order to assist debugging.
215
443
 
216
444
 
217
- Workers
218
- -------
445
+ #### Rails example
219
446
 
220
- Resque workers are rake tasks that run forever. They basically do this:
447
+ If you are using ActiveJob here's how your job definition will look:
221
448
 
222
449
  ``` ruby
223
- start
224
- loop do
225
- if job = reserve
226
- job.process
227
- else
228
- sleep 5 # Polling frequency = 5
450
+ class ArchiveJob < ApplicationJob
451
+ queue_as :file_serve
452
+
453
+ def perform(repo_id, branch = 'master')
454
+ repo = Repository.find(repo_id)
455
+ repo.create_archive(branch)
456
+ end
457
+ end
458
+ ```
459
+
460
+ ``` ruby
461
+ class Repository
462
+ def async_create_archive(branch)
463
+ ArchiveJob.perform_later(self.id, branch)
229
464
  end
230
465
  end
231
- shutdown
232
466
  ```
233
467
 
234
- Starting a worker is simple. Here's our example from earlier:
468
+ It is important to run `ArchiveJob.perform_later(self.id, branch)` rather than `Resque.enqueue(Archive, self.id, branch)`.
469
+ Otherwise Resque will process the job without actually doing anything.
470
+ Even if you put an obviously buggy line like `0/0` in the `perform` method,
471
+ the job will still succeed.
235
472
 
236
- $ QUEUE=file_serve rake resque:work
237
473
 
238
- By default Resque won't know about your application's
239
- environment. That is, it won't be able to find and run your jobs - it
240
- needs to load your application into memory.
474
+ Configuration
475
+ -------------
476
+
477
+ #### Redis
478
+
479
+ You may want to change the Redis host and port Resque connects to, or
480
+ set various other options at startup.
481
+
482
+ Resque has a `redis` setter which can be given a string or a Redis
483
+ object. This means if you're already using Redis in your app, Resque
484
+ can re-use the existing connection.
485
+
486
+ String: `Resque.redis = 'localhost:6379'`
487
+
488
+ Redis: `Resque.redis = $redis`
489
+
490
+ For our rails app we have a `config/initializers/resque.rb` file where
491
+ we load `config/resque.yml` by hand and set the Redis information
492
+ appropriately.
241
493
 
242
- If we've installed Resque as a Rails plugin, we might run this command
243
- from our RAILS_ROOT:
494
+ Here's our `config/resque.yml`:
244
495
 
245
- $ QUEUE=file_serve rake environment resque:work
496
+ development: localhost:6379
497
+ test: localhost:6379
498
+ staging: redis1.se.github.com:6379
499
+ fi: localhost:6379
500
+ production: <%= ENV['REDIS_URL'] %>
246
501
 
247
- This will load the environment before starting a worker. Alternately
248
- we can define a `resque:setup` task with a dependency on the
249
- `environment` rake task:
502
+ And our initializer:
250
503
 
251
504
  ``` ruby
252
- task "resque:setup" => :environment
505
+ rails_root = ENV['RAILS_ROOT'] || File.dirname(__FILE__) + '/../..'
506
+ rails_env = ENV['RAILS_ENV'] || 'development'
507
+ config_file = rails_root + '/config/resque.yml'
508
+
509
+ resque_config = YAML::load(ERB.new(IO.read(config_file)).result)
510
+ Resque.redis = resque_config[rails_env]
253
511
  ```
254
512
 
255
- GitHub's setup task looks like this:
513
+ Easy peasy! Why not just use `RAILS_ROOT` and `RAILS_ENV`? Because
514
+ this way we can tell our Sinatra app about the config file:
515
+
516
+ $ RAILS_ENV=production resque-web rails_root/config/initializers/resque.rb
517
+
518
+ Now everyone is on the same page.
519
+
520
+ Also, you could disable jobs queueing by setting 'inline' attribute.
521
+ For example, if you want to run all jobs in the same process for cucumber, try:
256
522
 
257
523
  ``` ruby
258
- task "resque:setup" => :environment do
259
- Grit::Git.git_timeout = 10.minutes
260
- end
524
+ Resque.inline = ENV['RAILS_ENV'] == "cucumber"
261
525
  ```
262
526
 
263
- We don't want the `git_timeout` as high as 10 minutes in our web app,
264
- but in the Resque workers it's fine.
527
+ #### Logging
265
528
 
529
+ Workers support basic logging to STDOUT.
266
530
 
267
- ### Logging
531
+ You can control the logging threshold using `Resque.logger.level`:
268
532
 
269
- Workers support basic logging to STDOUT. If you start them with the
270
- `VERBOSE` env variable set, they will print basic debugging
271
- information. You can also set the `VVERBOSE` (very verbose) env
272
- variable.
273
-
274
- $ VVERBOSE=1 QUEUE=file_serve rake environment resque:work
533
+ ```ruby
534
+ # config/initializers/resque.rb
535
+ Resque.logger.level = Logger::DEBUG
536
+ ```
275
537
 
276
538
  If you want Resque to log to a file, in Rails do:
277
539
 
@@ -280,91 +542,111 @@ If you want Resque to log to a file, in Rails do:
280
542
  Resque.logger = Logger.new(Rails.root.join('log', "#{Rails.env}_resque.log"))
281
543
  ```
282
544
 
283
- ### Process IDs (PIDs)
545
+ #### Namespaces
284
546
 
285
- There are scenarios where it's helpful to record the PID of a resque
286
- worker process. Use the PIDFILE option for easy access to the PID:
547
+ If you're running multiple, separate instances of Resque you may want
548
+ to namespace the keyspaces so they do not overlap. This is not unlike
549
+ the approach taken by many memcached clients.
287
550
 
288
- $ PIDFILE=./resque.pid QUEUE=file_serve rake environment resque:work
551
+ This feature is provided by the [redis-namespace](http://github.com/resque/redis-namespace) library, which
552
+ Resque uses by default to separate the keys it manages from other keys
553
+ in your Redis server.
289
554
 
290
- ### Running in the background
555
+ Simply use the `Resque.redis.namespace` accessor:
291
556
 
292
- (Only supported with ruby >= 1.9). There are scenarios where it's helpful for
293
- the resque worker to run itself in the background (usually in combination with
294
- PIDFILE). Use the BACKGROUND option so that rake will return as soon as the
295
- worker is started.
557
+ ``` ruby
558
+ Resque.redis.namespace = "resque:GitHub"
559
+ ```
296
560
 
297
- $ PIDFILE=./resque.pid BACKGROUND=yes QUEUE=file_serve \
298
- rake environment resque:work
561
+ We recommend sticking this in your initializer somewhere after Redis
562
+ is configured.
299
563
 
300
- ### Polling frequency
564
+ #### Storing Statistics
565
+ Resque allows to store count of processed and failed jobs.
301
566
 
302
- You can pass an INTERVAL option which is a float representing the polling frequency.
303
- The default is 5 seconds, but for a semi-active app you may want to use a smaller value.
567
+ By default it will store it in Redis using the keys `stats:processed` and `stats:failed`.
304
568
 
305
- $ INTERVAL=0.1 QUEUE=file_serve rake environment resque:work
569
+ Some apps would want another stats store, or even a null store:
306
570
 
307
- ### Priorities and Queue Lists
308
-
309
- Resque doesn't support numeric priorities but instead uses the order
310
- of queues you give it. We call this list of queues the "queue list."
311
-
312
- Let's say we add a `warm_cache` queue in addition to our `file_serve`
313
- queue. We'd now start a worker like so:
314
-
315
- $ QUEUES=file_serve,warm_cache rake resque:work
316
-
317
- When the worker looks for new jobs, it will first check
318
- `file_serve`. If it finds a job, it'll process it then check
319
- `file_serve` again. It will keep checking `file_serve` until no more
320
- jobs are available. At that point, it will check `warm_cache`. If it
321
- finds a job it'll process it then check `file_serve` (repeating the
322
- whole process).
323
-
324
- In this way you can prioritize certain queues. At GitHub we start our
325
- workers with something like this:
571
+ ```ruby
572
+ # config/initializers/resque.rb
573
+ class NullDataStore
574
+ def stat(stat)
575
+ 0
576
+ end
326
577
 
327
- $ QUEUES=critical,archive,high,low rake resque:work
578
+ def increment_stat(stat, by)
579
+ end
328
580
 
329
- Notice the `archive` queue - it is specialized and in our future
330
- architecture will only be run from a single machine.
581
+ def decrement_stat(stat, by)
582
+ end
331
583
 
332
- At that point we'll start workers on our generalized background
333
- machines with this command:
584
+ def clear_stat(stat)
585
+ end
586
+ end
334
587
 
335
- $ QUEUES=critical,high,low rake resque:work
588
+ Resque.stat_data_store = NullDataStore.new
589
+ ```
336
590
 
337
- And workers on our specialized archive machine with this command:
591
+ Plugins and Hooks
592
+ -----------------
338
593
 
339
- $ QUEUE=archive rake resque:work
594
+ For a list of available plugins see
595
+ <https://github.com/resque/resque/wiki/plugins>.
340
596
 
597
+ If you'd like to write your own plugin, or want to customize Resque
598
+ using hooks (such as `Resque.after_fork`), see
599
+ [docs/HOOKS.md](http://github.com/resque/resque/blob/master/docs/HOOKS.md).
341
600
 
342
- ### Running All Queues
343
601
 
344
- If you want your workers to work off of every queue, including new
345
- queues created on the fly, you can use a splat:
602
+ Additional Information
603
+ ----------------------
346
604
 
347
- $ QUEUE=* rake resque:work
605
+ #### Resque vs DelayedJob
348
606
 
349
- Queues will be processed in alphabetical order.
607
+ How does Resque compare to DelayedJob, and why would you choose one
608
+ over the other?
350
609
 
610
+ * Resque supports multiple queues
611
+ * DelayedJob supports finer grained priorities
612
+ * Resque workers are resilient to memory leaks / bloat
613
+ * DelayedJob workers are extremely simple and easy to modify
614
+ * Resque requires Redis
615
+ * DelayedJob requires ActiveRecord
616
+ * Resque can only place JSONable Ruby objects on a queue as arguments
617
+ * DelayedJob can place _any_ Ruby object on its queue as arguments
618
+ * Resque includes a Sinatra app for monitoring what's going on
619
+ * DelayedJob can be queried from within your Rails app if you want to
620
+ add an interface
351
621
 
352
- ### Running Multiple Workers
622
+ If you're doing Rails development, you already have a database and
623
+ ActiveRecord. DelayedJob is super easy to setup and works great.
624
+ GitHub used it for many months to process almost 200 million jobs.
353
625
 
354
- At GitHub we use god to start and stop multiple workers. A sample god
355
- configuration file is included under `examples/god`. We recommend this
356
- method.
626
+ Choose Resque if:
357
627
 
358
- If you'd like to run multiple workers in development mode, you can do
359
- so using the `resque:workers` rake task:
628
+ * You need multiple queues
629
+ * You don't care / dislike numeric priorities
630
+ * You don't need to persist every Ruby object ever
631
+ * You have potentially huge queues
632
+ * You want to see what's going on
633
+ * You expect a lot of failure / chaos
634
+ * You can setup Redis
635
+ * You're not running short on RAM
360
636
 
361
- $ COUNT=5 QUEUE=* rake resque:workers
637
+ Choose DelayedJob if:
362
638
 
363
- This will spawn five Resque workers, each in its own process. Hitting
364
- ctrl-c should be sufficient to stop them all.
639
+ * You like numeric priorities
640
+ * You're not doing a gigantic amount of jobs each day
641
+ * Your queue stays small and nimble
642
+ * There is not a lot failure / chaos
643
+ * You want to easily throw anything on the queue
644
+ * You don't want to setup Redis
365
645
 
646
+ In no way is Resque a "better" DelayedJob, so make sure you pick the
647
+ tool that's best for your app.
366
648
 
367
- ### Forking
649
+ #### Forking
368
650
 
369
651
  On certain platforms, when a Resque worker reserves a job it
370
652
  immediately forks a child process. The child processes the job then
@@ -405,8 +687,7 @@ complicated.
405
687
 
406
688
  Workers instead handle their own state.
407
689
 
408
-
409
- ### Parents and Children
690
+ #### Parents and Children
410
691
 
411
692
  Here's a parent / child pair doing some work:
412
693
 
@@ -427,7 +708,7 @@ waiting for work on:
427
708
  92099 resque: Waiting for file_serve,warm_cache
428
709
 
429
710
 
430
- ### Signals
711
+ #### Signals
431
712
 
432
713
  Resque workers respond to a few different signals:
433
714
 
@@ -449,11 +730,47 @@ If you want to stop processing jobs, but want to leave the worker running
449
730
  (for example, to temporarily alleviate load), use `USR2` to stop processing,
450
731
  then `CONT` to start it again.
451
732
 
452
- ### Mysql::Error: MySQL server has gone away
733
+ #### Heroku
734
+
735
+ When shutting down processes, Heroku sends every process a TERM signal at the
736
+ same time. By default this causes an immediate shutdown of any running job
737
+ leading to frequent `Resque::TermException` errors. For short running jobs, a simple
738
+ solution is to give a small amount of time for the job to finish
739
+ before killing it.
740
+
741
+ Resque doesn't handle this out of the box (for both cedar-14 and heroku-16), you need to
742
+ install the [`resque-heroku-signals`](https://github.com/iloveitaly/resque-heroku-signals)
743
+ addon which adds the required signal handling to make the behavior described above work.
744
+ Related issue: https://github.com/resque/resque/issues/1559
745
+
746
+ To accomplish this set the following environment variables:
747
+
748
+ * `RESQUE_PRE_SHUTDOWN_TIMEOUT` - The time between the parent receiving a shutdown signal (TERM by default) and it sending that signal on to the child process. Designed to give the child process
749
+ time to complete before being forced to die.
750
+
751
+ * `TERM_CHILD` - Must be set for `RESQUE_PRE_SHUTDOWN_TIMEOUT` to be used. After the timeout, if the child is still running it will raise a `Resque::TermException` and exit.
752
+
753
+ * `RESQUE_TERM_TIMEOUT` - By default you have a few seconds to handle `Resque::TermException` in your job. `RESQUE_TERM_TIMEOUT` and `RESQUE_PRE_SHUTDOWN_TIMEOUT` must be lower than the [heroku dyno timeout](https://devcenter.heroku.com/articles/limits#exit-timeout).
754
+
755
+ #### Monitoring
756
+
757
+ ##### god
758
+
759
+ If you're using god to monitor Resque, we have provided example
760
+ configs in `examples/god/`. One is for starting / stopping workers,
761
+ the other is for killing workers that have been running too long.
762
+
763
+ ##### monit
764
+
765
+ If you're using monit, `examples/monit/resque.monit` is provided free
766
+ of charge. This is **not** used by GitHub in production, so please
767
+ send patches for any tweaks or improvements you can make to it.
768
+
769
+ #### Mysql::Error: MySQL server has gone away
453
770
 
454
771
  If your workers remain idle for too long they may lose their MySQL connection. Depending on your version of Rails, we recommend the following:
455
772
 
456
- #### Rails 3.x
773
+ ##### Rails 3.x
457
774
  In your `perform` method, add the following line:
458
775
 
459
776
  ``` ruby
@@ -469,7 +786,7 @@ The Rails doc says the following about `verify_active_connections!`:
469
786
 
470
787
  Verify active connections and remove and disconnect connections associated with stale threads.
471
788
 
472
- #### Rails 4.x
789
+ ##### Rails 4.x
473
790
 
474
791
  In your `perform` method, instead of `verify_active_connections!`, use:
475
792
 
@@ -486,356 +803,6 @@ From the Rails docs on [`clear_active_connections!`](http://api.rubyonrails.org/
486
803
 
487
804
  Returns any connections in use by the current thread back to the pool, and also returns connections to the pool cached by threads that are no longer alive.
488
805
 
489
-
490
-
491
- The Front End
492
- -------------
493
-
494
- Resque comes with a Sinatra-based front end for seeing what's up with
495
- your queue.
496
-
497
- ![The Front End](https://camo.githubusercontent.com/64d150a243987ffbc33f588bd6d7722a0bb8d69a/687474703a2f2f7475746f7269616c732e6a756d7073746172746c61622e636f6d2f696d616765732f7265737175655f6f766572766965772e706e67)
498
-
499
- ### Standalone
500
-
501
- If you've installed Resque as a gem running the front end standalone is easy:
502
-
503
- $ resque-web
504
-
505
- It's a thin layer around `rackup` so it's configurable as well:
506
-
507
- $ resque-web -p 8282
508
-
509
- If you have a Resque config file you want evaluated just pass it to
510
- the script as the final argument:
511
-
512
- $ resque-web -p 8282 rails_root/config/initializers/resque.rb
513
-
514
- You can also set the namespace directly using `resque-web`:
515
-
516
- $ resque-web -p 8282 -N myapp
517
-
518
- or set the Redis connection string if you need to do something like select a different database:
519
-
520
- $ resque-web -p 8282 -r localhost:6379:2
521
-
522
- ### Passenger
523
-
524
- Using Passenger? Resque ships with a `config.ru` you can use. See
525
- Phusion's guide:
526
-
527
- Apache: <https://www.phusionpassenger.com/library/deploy/apache/deploy/ruby/>
528
- Nginx: <https://www.phusionpassenger.com/library/deploy/nginx/deploy/ruby/>
529
-
530
- ### Rack::URLMap
531
-
532
- If you want to load Resque on a subpath, possibly alongside other
533
- apps, it's easy to do with Rack's `URLMap`:
534
-
535
- ``` ruby
536
- require 'resque/server'
537
-
538
- run Rack::URLMap.new \
539
- "/" => Your::App.new,
540
- "/resque" => Resque::Server.new
541
- ```
542
-
543
- Check `examples/demo/config.ru` for a functional example (including
544
- HTTP basic auth).
545
-
546
- ### Rails 3
547
-
548
- You can also mount Resque on a subpath in your existing Rails 3 app by adding `require 'resque/server'` to the top of your routes file or in an initializer then adding this to `routes.rb`:
549
-
550
- ``` ruby
551
- mount Resque::Server.new, :at => "/resque"
552
- ```
553
-
554
-
555
- Resque vs DelayedJob
556
- --------------------
557
-
558
- How does Resque compare to DelayedJob, and why would you choose one
559
- over the other?
560
-
561
- * Resque supports multiple queues
562
- * DelayedJob supports finer grained priorities
563
- * Resque workers are resilient to memory leaks / bloat
564
- * DelayedJob workers are extremely simple and easy to modify
565
- * Resque requires Redis
566
- * DelayedJob requires ActiveRecord
567
- * Resque can only place JSONable Ruby objects on a queue as arguments
568
- * DelayedJob can place _any_ Ruby object on its queue as arguments
569
- * Resque includes a Sinatra app for monitoring what's going on
570
- * DelayedJob can be queried from within your Rails app if you want to
571
- add an interface
572
-
573
- If you're doing Rails development, you already have a database and
574
- ActiveRecord. DelayedJob is super easy to setup and works great.
575
- GitHub used it for many months to process almost 200 million jobs.
576
-
577
- Choose Resque if:
578
-
579
- * You need multiple queues
580
- * You don't care / dislike numeric priorities
581
- * You don't need to persist every Ruby object ever
582
- * You have potentially huge queues
583
- * You want to see what's going on
584
- * You expect a lot of failure / chaos
585
- * You can setup Redis
586
- * You're not running short on RAM
587
-
588
- Choose DelayedJob if:
589
-
590
- * You like numeric priorities
591
- * You're not doing a gigantic amount of jobs each day
592
- * Your queue stays small and nimble
593
- * There is not a lot failure / chaos
594
- * You want to easily throw anything on the queue
595
- * You don't want to setup Redis
596
-
597
- In no way is Resque a "better" DelayedJob, so make sure you pick the
598
- tool that's best for your app.
599
-
600
- Resque Dependencies
601
- -------------------
602
-
603
- $ gem install bundler
604
- $ bundle install
605
-
606
-
607
- Installing Resque
608
- -----------------
609
-
610
- ### In a Rack app, as a gem
611
-
612
- First install the gem.
613
-
614
- $ gem install resque
615
-
616
- Next include it in your application.
617
-
618
- ``` ruby
619
- require 'resque'
620
- ```
621
-
622
- Now start your application:
623
-
624
- rackup config.ru
625
-
626
- That's it! You can now create Resque jobs from within your app.
627
-
628
- To start a worker, create a Rakefile in your app's root (or add this
629
- to an existing Rakefile):
630
-
631
- ``` ruby
632
- require 'your/app'
633
- require 'resque/tasks'
634
- ```
635
-
636
- Now:
637
-
638
- $ QUEUE=* rake resque:work
639
-
640
- Alternately you can define a `resque:setup` hook in your Rakefile if you
641
- don't want to load your app every time rake runs.
642
-
643
-
644
- ### In a Rails 2.x app, as a gem
645
-
646
- First install the gem.
647
-
648
- $ gem install resque
649
-
650
- Next include it in your application.
651
-
652
- $ cat config/initializers/load_resque.rb
653
- require 'resque'
654
-
655
- Now start your application:
656
-
657
- $ ./script/server
658
-
659
- That's it! You can now create Resque jobs from within your app.
660
-
661
- To start a worker, add this to your Rakefile in `RAILS_ROOT`:
662
-
663
- ``` ruby
664
- require 'resque/tasks'
665
- ```
666
-
667
- Now:
668
-
669
- $ QUEUE=* rake environment resque:work
670
-
671
- Don't forget you can define a `resque:setup` hook in
672
- `lib/tasks/whatever.rake` that loads the `environment` task every time.
673
-
674
-
675
- ### In a Rails 2.x app, as a plugin
676
-
677
- $ ./script/plugin install git://github.com/resque/resque
678
-
679
- That's it! Resque will automatically be available when your Rails app
680
- loads.
681
-
682
- To start a worker:
683
-
684
- $ QUEUE=* rake environment resque:work
685
-
686
- Don't forget you can define a `resque:setup` hook in
687
- `lib/tasks/whatever.rake` that loads the `environment` task every time.
688
-
689
-
690
- ### In a Rails 3.x or 4.x app, as a gem
691
-
692
- First include it in your Gemfile.
693
-
694
- $ cat Gemfile
695
- ...
696
- gem 'resque'
697
- ...
698
-
699
- Next install it with Bundler.
700
-
701
- $ bundle install
702
-
703
- Now start your application:
704
-
705
- $ rails server
706
-
707
- That's it! You can now create Resque jobs from within your app.
708
-
709
- To start a worker, add this to a file in `lib/tasks` (ex:
710
- `lib/tasks/resque.rake`):
711
-
712
- ``` ruby
713
- require 'resque/tasks'
714
- ```
715
-
716
- Now:
717
-
718
- $ QUEUE=* rake environment resque:work
719
-
720
- Don't forget you can define a `resque:setup` hook in
721
- `lib/tasks/whatever.rake` that loads the `environment` task every time.
722
-
723
-
724
- Configuration
725
- -------------
726
-
727
- You may want to change the Redis host and port Resque connects to, or
728
- set various other options at startup.
729
-
730
- Resque has a `redis` setter which can be given a string or a Redis
731
- object. This means if you're already using Redis in your app, Resque
732
- can re-use the existing connection.
733
-
734
- String: `Resque.redis = 'localhost:6379'`
735
-
736
- Redis: `Resque.redis = $redis`
737
-
738
- For our rails app we have a `config/initializers/resque.rb` file where
739
- we load `config/resque.yml` by hand and set the Redis information
740
- appropriately.
741
-
742
- Here's our `config/resque.yml`:
743
-
744
- development: localhost:6379
745
- test: localhost:6379
746
- staging: redis1.se.github.com:6379
747
- fi: localhost:6379
748
- production: redis1.ae.github.com:6379
749
-
750
- And our initializer:
751
-
752
- ``` ruby
753
- rails_root = ENV['RAILS_ROOT'] || File.dirname(__FILE__) + '/../..'
754
- rails_env = ENV['RAILS_ENV'] || 'development'
755
-
756
- resque_config = YAML.load_file(rails_root + '/config/resque.yml')
757
- Resque.redis = resque_config[rails_env]
758
- ```
759
-
760
- Easy peasy! Why not just use `RAILS_ROOT` and `RAILS_ENV`? Because
761
- this way we can tell our Sinatra app about the config file:
762
-
763
- $ RAILS_ENV=production resque-web rails_root/config/initializers/resque.rb
764
-
765
- Now everyone is on the same page.
766
-
767
- Also, you could disable jobs queueing by setting 'inline' attribute.
768
- For example, if you want to run all jobs in the same process for cucumber, try:
769
-
770
- ``` ruby
771
- Resque.inline = ENV['RAILS_ENV'] == "cucumber"
772
- ```
773
-
774
-
775
- Plugins and Hooks
776
- -----------------
777
-
778
- For a list of available plugins see
779
- <http://wiki.github.com/resque/resque/plugins>.
780
-
781
- If you'd like to write your own plugin, or want to customize Resque
782
- using hooks (such as `Resque.after_fork`), see
783
- [docs/HOOKS.md](http://github.com/resque/resque/blob/master/docs/HOOKS.md).
784
-
785
-
786
- Namespaces
787
- ----------
788
-
789
- If you're running multiple, separate instances of Resque you may want
790
- to namespace the keyspaces so they do not overlap. This is not unlike
791
- the approach taken by many memcached clients.
792
-
793
- This feature is provided by the [redis-namespace][rs] library, which
794
- Resque uses by default to separate the keys it manages from other keys
795
- in your Redis server.
796
-
797
- Simply use the `Resque.redis.namespace` accessor:
798
-
799
- ``` ruby
800
- Resque.redis.namespace = "resque:GitHub"
801
- ```
802
-
803
- We recommend sticking this in your initializer somewhere after Redis
804
- is configured.
805
-
806
-
807
- Demo
808
- ----
809
-
810
- Resque ships with a demo Sinatra app for creating jobs that are later
811
- processed in the background.
812
-
813
- Try it out by looking at the README, found at `examples/demo/README.markdown`.
814
-
815
-
816
- Monitoring
817
- ----------
818
-
819
- ### god
820
-
821
- If you're using god to monitor Resque, we have provided example
822
- configs in `examples/god/`. One is for starting / stopping workers,
823
- the other is for killing workers that have been running too long.
824
-
825
- ### monit
826
-
827
- If you're using monit, `examples/monit/resque.monit` is provided free
828
- of charge. This is **not** used by GitHub in production, so please
829
- send patches for any tweaks or improvements you can make to it.
830
-
831
-
832
- Questions
833
- ---------
834
-
835
- Please add them to the [FAQ](https://github.com/resque/resque/wiki/FAQ) or
836
- ask on the Mailing List. The Mailing List is explained further below
837
-
838
-
839
806
  Development
840
807
  -----------
841
808
 
@@ -865,33 +832,27 @@ it:
865
832
  If you get an error requiring any of the dependencies, you may have
866
833
  failed to install them or be seeing load path issues.
867
834
 
868
- Feel free to ping the mailing list with your problem and we'll try to
869
- sort it out.
835
+ #### Demo
836
+ Resque ships with a demo Sinatra app for creating jobs that are later
837
+ processed in the background.
870
838
 
839
+ Try it out by looking at the README, found at `examples/demo/README.markdown`.
871
840
 
872
- Contributing
873
- ------------
841
+ #### Contributing
874
842
 
875
843
  Read [CONTRIBUTING.md](CONTRIBUTING.md) first.
876
844
 
877
845
  Once you've made your great commits:
878
846
 
879
- 1. [Fork][1] Resque
847
+ 1. [Fork](http://help.github.com/forking/) Resque
880
848
  2. Create a topic branch - `git checkout -b my_branch`
881
849
  3. Push to your branch - `git push origin my_branch`
882
850
  4. Create a [Pull Request](http://help.github.com/pull-requests/) from your branch
883
- 5. That's it!
884
-
885
-
886
- Mailing List
887
- ------------
888
-
889
- To join the list simply send an email to <resque@librelist.com>. This
890
- will subscribe you and send you information about your subscription,
891
- including unsubscribe information.
892
851
 
893
- The archive can be found at <http://librelist.com/browser/resque/>.
852
+ Questions
853
+ ---------
894
854
 
855
+ Please add them to the [FAQ](https://github.com/resque/resque/wiki/FAQ) or open an issue on this repo.
895
856
 
896
857
  Meta
897
858
  ----
@@ -900,21 +861,12 @@ Meta
900
861
  * Home: <http://github.com/resque/resque>
901
862
  * Docs: <http://rubydoc.info/gems/resque>
902
863
  * Bugs: <http://github.com/resque/resque/issues>
903
- * List: <resque@librelist.com>
904
864
  * Chat: <irc://irc.freenode.net/resque>
905
- * Gems: <http://gemcutter.org/gems/resque>
906
-
907
- This project uses [Semantic Versioning][sv].
865
+ * Gems: <https://rubygems.org/gems/resque>
908
866
 
867
+ This project uses [Semantic Versioning](http://semver.org/)
909
868
 
910
869
  Author
911
870
  ------
912
871
 
913
872
  Chris Wanstrath :: chris@ozmm.org :: @defunkt
914
-
915
- [0]: http://github.com/blog/542-introducing-resque
916
- [1]: http://help.github.com/forking/
917
- [2]: http://github.com/resque/resque/issues
918
- [sv]: http://semver.org/
919
- [rs]: http://github.com/resque/redis-namespace
920
- [cb]: http://wiki.github.com/resque/resque/contributing