opengotham_resque 1.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. data/.gitignore +2 -0
  2. data/.kick +26 -0
  3. data/HISTORY.md +142 -0
  4. data/LICENSE +20 -0
  5. data/README.markdown +794 -0
  6. data/Rakefile +112 -0
  7. data/bin/resque +57 -0
  8. data/bin/resque-web +23 -0
  9. data/config.ru +14 -0
  10. data/deps.rip +7 -0
  11. data/docs/HOOKS.md +121 -0
  12. data/docs/PLUGINS.md +93 -0
  13. data/examples/async_helper.rb +31 -0
  14. data/examples/demo/README.markdown +71 -0
  15. data/examples/demo/Rakefile +8 -0
  16. data/examples/demo/app.rb +38 -0
  17. data/examples/demo/config.ru +19 -0
  18. data/examples/demo/job.rb +22 -0
  19. data/examples/god/resque.god +53 -0
  20. data/examples/god/stale.god +26 -0
  21. data/examples/instance.rb +11 -0
  22. data/examples/monit/resque.monit +6 -0
  23. data/examples/simple.rb +30 -0
  24. data/init.rb +1 -0
  25. data/lib/resque.rb +287 -0
  26. data/lib/resque/errors.rb +10 -0
  27. data/lib/resque/failure.rb +66 -0
  28. data/lib/resque/failure/base.rb +61 -0
  29. data/lib/resque/failure/hoptoad.rb +132 -0
  30. data/lib/resque/failure/multiple.rb +48 -0
  31. data/lib/resque/failure/redis.rb +40 -0
  32. data/lib/resque/helpers.rb +63 -0
  33. data/lib/resque/job.rb +207 -0
  34. data/lib/resque/plugin.rb +46 -0
  35. data/lib/resque/server.rb +201 -0
  36. data/lib/resque/server/public/idle.png +0 -0
  37. data/lib/resque/server/public/jquery-1.3.2.min.js +19 -0
  38. data/lib/resque/server/public/jquery.relatize_date.js +95 -0
  39. data/lib/resque/server/public/poll.png +0 -0
  40. data/lib/resque/server/public/ranger.js +67 -0
  41. data/lib/resque/server/public/reset.css +48 -0
  42. data/lib/resque/server/public/style.css +81 -0
  43. data/lib/resque/server/public/working.png +0 -0
  44. data/lib/resque/server/test_helper.rb +19 -0
  45. data/lib/resque/server/views/error.erb +1 -0
  46. data/lib/resque/server/views/failed.erb +53 -0
  47. data/lib/resque/server/views/key_sets.erb +20 -0
  48. data/lib/resque/server/views/key_string.erb +11 -0
  49. data/lib/resque/server/views/layout.erb +44 -0
  50. data/lib/resque/server/views/next_more.erb +10 -0
  51. data/lib/resque/server/views/overview.erb +4 -0
  52. data/lib/resque/server/views/queues.erb +49 -0
  53. data/lib/resque/server/views/stats.erb +62 -0
  54. data/lib/resque/server/views/workers.erb +78 -0
  55. data/lib/resque/server/views/working.erb +69 -0
  56. data/lib/resque/stat.rb +53 -0
  57. data/lib/resque/tasks.rb +39 -0
  58. data/lib/resque/version.rb +3 -0
  59. data/lib/resque/worker.rb +478 -0
  60. data/tasks/redis.rake +159 -0
  61. data/tasks/resque.rake +2 -0
  62. data/test/job_hooks_test.rb +302 -0
  63. data/test/job_plugins_test.rb +209 -0
  64. data/test/plugin_test.rb +116 -0
  65. data/test/redis-test.conf +132 -0
  66. data/test/resque-web_test.rb +54 -0
  67. data/test/resque_test.rb +225 -0
  68. data/test/test_helper.rb +111 -0
  69. data/test/worker_test.rb +302 -0
  70. metadata +199 -0
@@ -0,0 +1,159 @@
1
+ # Inspired by rabbitmq.rake the Redbox project at http://github.com/rick/redbox/tree/master
2
+ require 'fileutils'
3
+ require 'open-uri'
4
+ require 'pathname'
5
+
6
+ class RedisRunner
7
+
8
+ def self.redis_dir
9
+ @redis_dir ||= if ENV['PREFIX']
10
+ Pathname.new(ENV['PREFIX'])
11
+ else
12
+ Pathname.new(`which redis-server`) + '..' + '..'
13
+ end
14
+ end
15
+
16
+ def self.bin_dir
17
+ redis_dir + 'bin'
18
+ end
19
+
20
+ def self.config
21
+ @config ||= if File.exists?(redis_dir + 'etc/redis.conf')
22
+ redis_dir + 'etc/redis.conf'
23
+ else
24
+ redis_dir + '../etc/redis.conf'
25
+ end
26
+ end
27
+
28
+ def self.dtach_socket
29
+ '/tmp/redis.dtach'
30
+ end
31
+
32
+ # Just check for existance of dtach socket
33
+ def self.running?
34
+ File.exists? dtach_socket
35
+ end
36
+
37
+ def self.start
38
+ puts 'Detach with Ctrl+\ Re-attach with rake redis:attach'
39
+ sleep 1
40
+ command = "#{bin_dir}/dtach -A #{dtach_socket} #{bin_dir}/redis-server #{config}"
41
+ sh command
42
+ end
43
+
44
+ def self.attach
45
+ exec "#{bin_dir}/dtach -a #{dtach_socket}"
46
+ end
47
+
48
+ def self.stop
49
+ sh 'echo "SHUTDOWN" | nc localhost 6379'
50
+ end
51
+
52
+ end
53
+
54
+ namespace :redis do
55
+
56
+ desc 'About redis'
57
+ task :about do
58
+ puts "\nSee http://code.google.com/p/redis/ for information about redis.\n\n"
59
+ end
60
+
61
+ desc 'Start redis'
62
+ task :start do
63
+ RedisRunner.start
64
+ end
65
+
66
+ desc 'Stop redis'
67
+ task :stop do
68
+ RedisRunner.stop
69
+ end
70
+
71
+ desc 'Restart redis'
72
+ task :restart do
73
+ RedisRunner.stop
74
+ RedisRunner.start
75
+ end
76
+
77
+ desc 'Attach to redis dtach socket'
78
+ task :attach do
79
+ RedisRunner.attach
80
+ end
81
+
82
+ desc 'Install the latest verison of Redis from Github (requires git, duh)'
83
+ task :install => [:about, :download, :make] do
84
+ bin_dir = '/usr/bin'
85
+ conf_dir = '/etc'
86
+
87
+ if ENV['PREFIX']
88
+ bin_dir = "#{ENV['PREFIX']}/bin"
89
+ sh "mkdir -p #{bin_dir}" unless File.exists?("#{bin_dir}")
90
+
91
+ conf_dir = "#{ENV['PREFIX']}/etc"
92
+ sh "mkdir -p #{conf_dir}" unless File.exists?("#{conf_dir}")
93
+ end
94
+
95
+ %w(redis-benchmark redis-cli redis-server).each do |bin|
96
+ sh "cp /tmp/redis/#{bin} #{bin_dir}"
97
+ end
98
+
99
+ puts "Installed redis-benchmark, redis-cli and redis-server to #{bin_dir}"
100
+
101
+ unless File.exists?("#{conf_dir}/redis.conf")
102
+ sh "cp /tmp/redis/redis.conf #{conf_dir}/redis.conf"
103
+ puts "Installed redis.conf to #{conf_dir} \n You should look at this file!"
104
+ end
105
+ end
106
+
107
+ task :make do
108
+ sh "cd /tmp/redis && make clean"
109
+ sh "cd /tmp/redis && make"
110
+ end
111
+
112
+ desc "Download package"
113
+ 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")
117
+ end
118
+
119
+ end
120
+
121
+ namespace :dtach do
122
+
123
+ desc 'About dtach'
124
+ task :about do
125
+ puts "\nSee http://dtach.sourceforge.net/ for information about dtach.\n\n"
126
+ end
127
+
128
+ desc 'Install dtach 0.8 from source'
129
+ task :install => [:about, :download, :make] do
130
+
131
+ bin_dir = "/usr/bin"
132
+
133
+ if ENV['PREFIX']
134
+ bin_dir = "#{ENV['PREFIX']}/bin"
135
+ sh "mkdir -p #{bin_dir}" unless File.exists?("#{bin_dir}")
136
+ end
137
+
138
+ sh "cp /tmp/dtach-0.8/dtach #{bin_dir}"
139
+ end
140
+
141
+ task :make do
142
+ sh 'cd /tmp/dtach-0.8/ && ./configure && make'
143
+ end
144
+
145
+ desc "Download package"
146
+ task :download do
147
+ unless File.exists?('/tmp/dtach-0.8.tar.gz')
148
+ require 'net/http'
149
+
150
+ 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
152
+ end
153
+
154
+ unless File.directory?('/tmp/dtach-0.8')
155
+ sh 'cd /tmp && tar xzf dtach-0.8.tar.gz'
156
+ end
157
+ end
158
+ end
159
+
@@ -0,0 +1,2 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ require 'resque/tasks'
@@ -0,0 +1,302 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ context "Resque::Job before_perform" do
4
+ include PerformJob
5
+
6
+ class BeforePerformJob
7
+ def self.before_perform_record_history(history)
8
+ history << :before_perform
9
+ end
10
+
11
+ def self.perform(history)
12
+ history << :perform
13
+ end
14
+ end
15
+
16
+ test "it runs before_perform before perform" do
17
+ result = perform_job(BeforePerformJob, history=[])
18
+ assert_equal true, result, "perform returned true"
19
+ assert_equal history, [:before_perform, :perform]
20
+ end
21
+
22
+ class BeforePerformJobFails
23
+ def self.before_perform_fail_job(history)
24
+ history << :before_perform
25
+ raise StandardError
26
+ end
27
+ def self.perform(history)
28
+ history << :perform
29
+ end
30
+ end
31
+
32
+ test "raises an error and does not perform if before_perform fails" do
33
+ history = []
34
+ assert_raises StandardError do
35
+ perform_job(BeforePerformJobFails, history)
36
+ end
37
+ assert_equal history, [:before_perform], "Only before_perform was run"
38
+ end
39
+
40
+ class BeforePerformJobAborts
41
+ def self.before_perform_abort(history)
42
+ history << :before_perform
43
+ raise Resque::Job::DontPerform
44
+ end
45
+ def self.perform(history)
46
+ history << :perform
47
+ end
48
+ end
49
+
50
+ test "does not perform if before_perform raises Resque::Job::DontPerform" do
51
+ result = perform_job(BeforePerformJobAborts, history=[])
52
+ assert_equal false, result, "perform returned false"
53
+ assert_equal history, [:before_perform], "Only before_perform was run"
54
+ end
55
+ end
56
+
57
+ context "Resque::Job after_perform" do
58
+ include PerformJob
59
+
60
+ class AfterPerformJob
61
+ def self.perform(history)
62
+ history << :perform
63
+ end
64
+ def self.after_perform_record_history(history)
65
+ history << :after_perform
66
+ end
67
+ end
68
+
69
+ test "it runs after_perform after perform" do
70
+ result = perform_job(AfterPerformJob, history=[])
71
+ assert_equal true, result, "perform returned true"
72
+ assert_equal history, [:perform, :after_perform]
73
+ end
74
+
75
+ class AfterPerformJobFails
76
+ def self.perform(history)
77
+ history << :perform
78
+ end
79
+ def self.after_perform_fail_job(history)
80
+ history << :after_perform
81
+ raise StandardError
82
+ end
83
+ end
84
+
85
+ test "raises an error but has already performed if after_perform fails" do
86
+ history = []
87
+ assert_raises StandardError do
88
+ perform_job(AfterPerformJobFails, history)
89
+ end
90
+ assert_equal history, [:perform, :after_perform], "Only after_perform was run"
91
+ end
92
+ end
93
+
94
+ context "Resque::Job around_perform" do
95
+ include PerformJob
96
+
97
+ class AroundPerformJob
98
+ def self.perform(history)
99
+ history << :perform
100
+ end
101
+ def self.around_perform_record_history(history)
102
+ history << :start_around_perform
103
+ yield
104
+ history << :finish_around_perform
105
+ end
106
+ end
107
+
108
+ test "it runs around_perform then yields in order to perform" do
109
+ result = perform_job(AroundPerformJob, history=[])
110
+ assert_equal true, result, "perform returned true"
111
+ assert_equal history, [:start_around_perform, :perform, :finish_around_perform]
112
+ end
113
+
114
+ class AroundPerformJobFailsBeforePerforming
115
+ def self.perform(history)
116
+ history << :perform
117
+ end
118
+ def self.around_perform_fail(history)
119
+ history << :start_around_perform
120
+ raise StandardError
121
+ yield
122
+ history << :finish_around_perform
123
+ end
124
+ end
125
+
126
+ test "raises an error and does not perform if around_perform fails before yielding" do
127
+ history = []
128
+ assert_raises StandardError do
129
+ perform_job(AroundPerformJobFailsBeforePerforming, history)
130
+ end
131
+ assert_equal history, [:start_around_perform], "Only part of around_perform was run"
132
+ end
133
+
134
+ class AroundPerformJobFailsWhilePerforming
135
+ def self.perform(history)
136
+ history << :perform
137
+ raise StandardError
138
+ end
139
+ def self.around_perform_fail_in_yield(history)
140
+ history << :start_around_perform
141
+ begin
142
+ yield
143
+ ensure
144
+ history << :ensure_around_perform
145
+ end
146
+ history << :finish_around_perform
147
+ end
148
+ end
149
+
150
+ test "raises an error but may handle exceptions if perform fails" do
151
+ history = []
152
+ assert_raises StandardError do
153
+ perform_job(AroundPerformJobFailsWhilePerforming, history)
154
+ end
155
+ assert_equal history, [:start_around_perform, :perform, :ensure_around_perform], "Only part of around_perform was run"
156
+ end
157
+
158
+ class AroundPerformJobDoesNotHaveToYield
159
+ def self.perform(history)
160
+ history << :perform
161
+ end
162
+ def self.around_perform_dont_yield(history)
163
+ history << :start_around_perform
164
+ history << :finish_around_perform
165
+ end
166
+ end
167
+
168
+ test "around_perform is not required to yield" do
169
+ history = []
170
+ result = perform_job(AroundPerformJobDoesNotHaveToYield, history)
171
+ assert_equal false, result, "perform returns false"
172
+ assert_equal history, [:start_around_perform, :finish_around_perform], "perform was not run"
173
+ end
174
+ end
175
+
176
+ context "Resque::Job on_failure" do
177
+ include PerformJob
178
+
179
+ class FailureJobThatDoesNotFail
180
+ def self.perform(history)
181
+ history << :perform
182
+ end
183
+ def self.on_failure_record_failure(exception, history)
184
+ history << exception.message
185
+ end
186
+ end
187
+
188
+ test "it does not call on_failure if no failures occur" do
189
+ result = perform_job(FailureJobThatDoesNotFail, history=[])
190
+ assert_equal true, result, "perform returned true"
191
+ assert_equal history, [:perform]
192
+ end
193
+
194
+ class FailureJobThatFails
195
+ def self.perform(history)
196
+ history << :perform
197
+ raise StandardError, "oh no"
198
+ end
199
+ def self.on_failure_record_failure(exception, history)
200
+ history << exception.message
201
+ end
202
+ end
203
+
204
+ test "it calls on_failure with the exception and then re-raises the exception" do
205
+ history = []
206
+ assert_raises StandardError do
207
+ perform_job(FailureJobThatFails, history)
208
+ end
209
+ assert_equal history, [:perform, "oh no"]
210
+ end
211
+
212
+ class FailureJobThatFailsBadly
213
+ def self.perform(history)
214
+ history << :perform
215
+ raise SyntaxError, "oh no"
216
+ end
217
+ def self.on_failure_record_failure(exception, history)
218
+ history << exception.message
219
+ end
220
+ end
221
+
222
+ test "it calls on_failure even with bad exceptions" do
223
+ history = []
224
+ assert_raises SyntaxError do
225
+ perform_job(FailureJobThatFailsBadly, history)
226
+ end
227
+ assert_equal history, [:perform, "oh no"]
228
+ end
229
+ end
230
+
231
+ context "Resque::Job all hooks" do
232
+ include PerformJob
233
+
234
+ class VeryHookyJob
235
+ def self.before_perform_record_history(history)
236
+ history << :before_perform
237
+ end
238
+ def self.around_perform_record_history(history)
239
+ history << :start_around_perform
240
+ yield
241
+ history << :finish_around_perform
242
+ end
243
+ def self.perform(history)
244
+ history << :perform
245
+ end
246
+ def self.after_perform_record_history(history)
247
+ history << :after_perform
248
+ end
249
+ def self.on_failure_record_history(exception, history)
250
+ history << exception.message
251
+ end
252
+ end
253
+
254
+ test "the complete hook order" do
255
+ result = perform_job(VeryHookyJob, history=[])
256
+ assert_equal true, result, "perform returned true"
257
+ assert_equal history, [
258
+ :before_perform,
259
+ :start_around_perform,
260
+ :perform,
261
+ :finish_around_perform,
262
+ :after_perform
263
+ ]
264
+ end
265
+
266
+ class VeryHookyJobThatFails
267
+ def self.before_perform_record_history(history)
268
+ history << :before_perform
269
+ end
270
+ def self.around_perform_record_history(history)
271
+ history << :start_around_perform
272
+ yield
273
+ history << :finish_around_perform
274
+ end
275
+ def self.perform(history)
276
+ history << :perform
277
+ end
278
+ def self.after_perform_record_history(history)
279
+ history << :after_perform
280
+ raise StandardError, "oh no"
281
+ end
282
+ def self.on_failure_record_history(exception, history)
283
+ history << exception.message
284
+ end
285
+ end
286
+
287
+ test "the complete hook order with a failure at the last minute" do
288
+ history = []
289
+ assert_raises StandardError do
290
+ perform_job(VeryHookyJobThatFails, history)
291
+ end
292
+ assert_equal history, [
293
+ :before_perform,
294
+ :start_around_perform,
295
+ :perform,
296
+ :finish_around_perform,
297
+ :after_perform,
298
+ "oh no"
299
+ ]
300
+ end
301
+ end
302
+