resque_sqs 1.25.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. checksums.yaml +7 -0
  2. data/HISTORY.md +467 -0
  3. data/LICENSE +20 -0
  4. data/README.markdown +866 -0
  5. data/Rakefile +70 -0
  6. data/bin/resque-sqs +81 -0
  7. data/bin/resque-sqs-web +27 -0
  8. data/lib/resque_sqs/errors.rb +13 -0
  9. data/lib/resque_sqs/failure/airbrake.rb +33 -0
  10. data/lib/resque_sqs/failure/base.rb +73 -0
  11. data/lib/resque_sqs/failure/multiple.rb +59 -0
  12. data/lib/resque_sqs/failure/redis.rb +108 -0
  13. data/lib/resque_sqs/failure/redis_multi_queue.rb +89 -0
  14. data/lib/resque_sqs/failure.rb +113 -0
  15. data/lib/resque_sqs/helpers.rb +107 -0
  16. data/lib/resque_sqs/job.rb +346 -0
  17. data/lib/resque_sqs/log_formatters/quiet_formatter.rb +7 -0
  18. data/lib/resque_sqs/log_formatters/verbose_formatter.rb +7 -0
  19. data/lib/resque_sqs/log_formatters/very_verbose_formatter.rb +8 -0
  20. data/lib/resque_sqs/logging.rb +18 -0
  21. data/lib/resque_sqs/plugin.rb +66 -0
  22. data/lib/resque_sqs/server/helpers.rb +52 -0
  23. data/lib/resque_sqs/server/public/favicon.ico +0 -0
  24. data/lib/resque_sqs/server/public/idle.png +0 -0
  25. data/lib/resque_sqs/server/public/jquery-1.3.2.min.js +19 -0
  26. data/lib/resque_sqs/server/public/jquery.relatize_date.js +95 -0
  27. data/lib/resque_sqs/server/public/poll.png +0 -0
  28. data/lib/resque_sqs/server/public/ranger.js +78 -0
  29. data/lib/resque_sqs/server/public/reset.css +44 -0
  30. data/lib/resque_sqs/server/public/style.css +91 -0
  31. data/lib/resque_sqs/server/public/working.png +0 -0
  32. data/lib/resque_sqs/server/test_helper.rb +19 -0
  33. data/lib/resque_sqs/server/views/error.erb +1 -0
  34. data/lib/resque_sqs/server/views/failed.erb +29 -0
  35. data/lib/resque_sqs/server/views/failed_job.erb +50 -0
  36. data/lib/resque_sqs/server/views/failed_queues_overview.erb +24 -0
  37. data/lib/resque_sqs/server/views/key_sets.erb +19 -0
  38. data/lib/resque_sqs/server/views/key_string.erb +11 -0
  39. data/lib/resque_sqs/server/views/layout.erb +44 -0
  40. data/lib/resque_sqs/server/views/next_more.erb +22 -0
  41. data/lib/resque_sqs/server/views/overview.erb +4 -0
  42. data/lib/resque_sqs/server/views/queues.erb +58 -0
  43. data/lib/resque_sqs/server/views/stats.erb +62 -0
  44. data/lib/resque_sqs/server/views/workers.erb +109 -0
  45. data/lib/resque_sqs/server/views/working.erb +72 -0
  46. data/lib/resque_sqs/server.rb +271 -0
  47. data/lib/resque_sqs/stat.rb +57 -0
  48. data/lib/resque_sqs/tasks.rb +83 -0
  49. data/lib/resque_sqs/vendor/utf8_util/utf8_util_18.rb +91 -0
  50. data/lib/resque_sqs/vendor/utf8_util/utf8_util_19.rb +5 -0
  51. data/lib/resque_sqs/vendor/utf8_util.rb +20 -0
  52. data/lib/resque_sqs/version.rb +3 -0
  53. data/lib/resque_sqs/worker.rb +779 -0
  54. data/lib/resque_sqs.rb +479 -0
  55. data/lib/tasks/redis_sqs.rake +161 -0
  56. data/lib/tasks/resque_sqs.rake +2 -0
  57. data/test/airbrake_test.rb +27 -0
  58. data/test/failure_base_test.rb +15 -0
  59. data/test/job_hooks_test.rb +465 -0
  60. data/test/job_plugins_test.rb +230 -0
  61. data/test/logging_test.rb +24 -0
  62. data/test/plugin_test.rb +116 -0
  63. data/test/redis-test-cluster.conf +115 -0
  64. data/test/redis-test.conf +115 -0
  65. data/test/resque-web_test.rb +59 -0
  66. data/test/resque_failure_redis_test.rb +19 -0
  67. data/test/resque_hook_test.rb +165 -0
  68. data/test/resque_test.rb +278 -0
  69. data/test/stdout +42 -0
  70. data/test/test_helper.rb +228 -0
  71. data/test/worker_test.rb +1080 -0
  72. metadata +202 -0
data/lib/resque_sqs.rb ADDED
@@ -0,0 +1,479 @@
1
+ require 'mono_logger'
2
+ require 'redis/namespace'
3
+ require 'forwardable'
4
+
5
+ require 'resque_sqs/version'
6
+
7
+ require 'resque_sqs/errors'
8
+
9
+ require 'resque_sqs/failure'
10
+ require 'resque_sqs/failure/base'
11
+
12
+ require 'resque_sqs/helpers'
13
+ require 'resque_sqs/stat'
14
+ require 'resque_sqs/logging'
15
+ require 'resque_sqs/log_formatters/quiet_formatter'
16
+ require 'resque_sqs/log_formatters/verbose_formatter'
17
+ require 'resque_sqs/log_formatters/very_verbose_formatter'
18
+ require 'resque_sqs/job'
19
+ require 'resque_sqs/worker'
20
+ require 'resque_sqs/plugin'
21
+
22
+ require 'resque_sqs/vendor/utf8_util'
23
+
24
+ module ResqueSqs
25
+ extend self
26
+
27
+ # Given a Ruby object, returns a string suitable for storage in a
28
+ # queue.
29
+ def encode(object)
30
+ if MultiJson.respond_to?(:dump) && MultiJson.respond_to?(:load)
31
+ MultiJson.dump object
32
+ else
33
+ MultiJson.encode object
34
+ end
35
+ end
36
+
37
+ # Given a string, returns a Ruby object.
38
+ def decode(object)
39
+ return unless object
40
+
41
+ begin
42
+ if MultiJson.respond_to?(:dump) && MultiJson.respond_to?(:load)
43
+ MultiJson.load object
44
+ else
45
+ MultiJson.decode object
46
+ end
47
+ rescue ::MultiJson::DecodeError => e
48
+ raise Helpers::DecodeException, e.message, e.backtrace
49
+ end
50
+ end
51
+
52
+ extend ::Forwardable
53
+
54
+ def self.config=(options = {})
55
+ @config = Config.new(options)
56
+ end
57
+
58
+ def self.config
59
+ @config ||= Config.new
60
+ end
61
+
62
+ def self.configure
63
+ yield config
64
+ end
65
+
66
+ # Accepts:
67
+ # 1. A 'hostname:port' String
68
+ # 2. A 'hostname:port:db' String (to select the Redis db)
69
+ # 3. A 'hostname:port/namespace' String (to set the Redis namespace)
70
+ # 4. A Redis URL String 'redis://host:port'
71
+ # 5. An instance of `Redis`, `Redis::Client`, `Redis::DistRedis`,
72
+ # or `Redis::Namespace`.
73
+ # 6. An Hash of a redis connection {:host => 'localhost', :port => 6379, :db => 0}
74
+ def redis=(server)
75
+ case server
76
+ when String
77
+ if server =~ /redis\:\/\//
78
+ redis = Redis.connect(:url => server, :thread_safe => true)
79
+ else
80
+ server, namespace = server.split('/', 2)
81
+ host, port, db = server.split(':')
82
+ redis = Redis.new(:host => host, :port => port,
83
+ :thread_safe => true, :db => db)
84
+ end
85
+ namespace ||= :resque
86
+
87
+ @redis = Redis::Namespace.new(namespace, :redis => redis)
88
+ when Redis::Namespace
89
+ @redis = server
90
+ when Hash
91
+ @redis = Redis::Namespace.new(:resque, :redis => Redis.new(server))
92
+ else
93
+ @redis = Redis::Namespace.new(:resque, :redis => server)
94
+ end
95
+ end
96
+
97
+ # Returns the current Redis connection. If none has been created, will
98
+ # create a new one.
99
+ def redis
100
+ return @redis if @redis
101
+ self.redis = Redis.respond_to?(:connect) ? Redis.connect : "localhost:6379"
102
+ self.redis
103
+ end
104
+
105
+ def redis_id
106
+ # support 1.x versions of redis-rb
107
+ if redis.respond_to?(:server)
108
+ redis.server
109
+ elsif redis.respond_to?(:nodes) # distributed
110
+ redis.nodes.map { |n| n.id }.join(', ')
111
+ else
112
+ redis.client.id
113
+ end
114
+ end
115
+
116
+ # Set or retrieve the current logger object
117
+ attr_accessor :logger
118
+
119
+ # The `before_first_fork` hook will be run in the **parent** process
120
+ # only once, before forking to run the first job. Be careful- any
121
+ # changes you make will be permanent for the lifespan of the
122
+ # worker.
123
+ #
124
+ # Call with a block to register a hook.
125
+ # Call with no arguments to return all registered hooks.
126
+ def before_first_fork(&block)
127
+ block ? register_hook(:before_first_fork, block) : hooks(:before_first_fork)
128
+ end
129
+
130
+ # Register a before_first_fork proc.
131
+ def before_first_fork=(block)
132
+ register_hook(:before_first_fork, block)
133
+ end
134
+
135
+ # The `before_fork` hook will be run in the **parent** process
136
+ # before every job, so be careful- any changes you make will be
137
+ # permanent for the lifespan of the worker.
138
+ #
139
+ # Call with a block to register a hook.
140
+ # Call with no arguments to return all registered hooks.
141
+ def before_fork(&block)
142
+ block ? register_hook(:before_fork, block) : hooks(:before_fork)
143
+ end
144
+
145
+ # Register a before_fork proc.
146
+ def before_fork=(block)
147
+ register_hook(:before_fork, block)
148
+ end
149
+
150
+ # The `after_fork` hook will be run in the child process and is passed
151
+ # the current job. Any changes you make, therefore, will only live as
152
+ # long as the job currently being processed.
153
+ #
154
+ # Call with a block to register a hook.
155
+ # Call with no arguments to return all registered hooks.
156
+ def after_fork(&block)
157
+ block ? register_hook(:after_fork, block) : hooks(:after_fork)
158
+ end
159
+
160
+ # Register an after_fork proc.
161
+ def after_fork=(block)
162
+ register_hook(:after_fork, block)
163
+ end
164
+
165
+ # The `before_pause` hook will be run in the parent process before the
166
+ # worker has paused processing (via #pause_processing or SIGUSR2).
167
+ def before_pause(&block)
168
+ block ? register_hook(:before_pause, block) : hooks(:before_pause)
169
+ end
170
+
171
+ # Set the after_pause proc.
172
+ attr_writer :before_pause
173
+
174
+ # The `after_pause` hook will be run in the parent process after the
175
+ # worker has paused (via SIGCONT).
176
+ def after_pause(&block)
177
+ block ? register_hook(:after_pause, block) : hooks(:after_pause)
178
+ end
179
+
180
+ # Set the after_continue proc.
181
+ attr_writer :after_pause
182
+
183
+ def to_s
184
+ "Resque Client connected to #{redis_id}"
185
+ end
186
+
187
+ attr_accessor :inline
188
+
189
+ # If 'inline' is true Resque will call #perform method inline
190
+ # without queuing it into Redis and without any Resque callbacks.
191
+ # The 'inline' is false Resque jobs will be put in queue regularly.
192
+ alias :inline? :inline
193
+
194
+ #
195
+ # queue manipulation
196
+ #
197
+
198
+ # Pushes a job onto a queue. Queue name should be a string and the
199
+ # item should be any JSON-able Ruby object.
200
+ #
201
+ # Resque works generally expect the `item` to be a hash with the following
202
+ # keys:
203
+ #
204
+ # class - The String name of the job to run.
205
+ # args - An Array of arguments to pass the job. Usually passed
206
+ # via `class.to_class.perform(*args)`.
207
+ #
208
+ # Example
209
+ #
210
+ # ResqueSqs.push('archive', :class => 'Archive', :args => [ 35, 'tar' ])
211
+ #
212
+ # Returns nothing
213
+ def push(queue, item)
214
+ redis.pipelined do
215
+ watch_queue(queue)
216
+ redis.rpush "queue:#{queue}", encode(item)
217
+ end
218
+ end
219
+
220
+ # Pops a job off a queue. Queue name should be a string.
221
+ #
222
+ # Returns a Ruby object.
223
+ def pop(queue)
224
+ decode redis.lpop("queue:#{queue}")
225
+ end
226
+
227
+ # Returns an integer representing the size of a queue.
228
+ # Queue name should be a string.
229
+ def size(queue)
230
+ redis.llen("queue:#{queue}").to_i
231
+ end
232
+
233
+ # Returns an array of items currently queued. Queue name should be
234
+ # a string.
235
+ #
236
+ # start and count should be integer and can be used for pagination.
237
+ # start is the item to begin, count is how many items to return.
238
+ #
239
+ # To get the 3rd page of a 30 item, paginatied list one would use:
240
+ # ResqueSqs.peek('my_list', 59, 30)
241
+ def peek(queue, start = 0, count = 1)
242
+ list_range("queue:#{queue}", start, count)
243
+ end
244
+
245
+ # Does the dirty work of fetching a range of items from a Redis list
246
+ # and converting them into Ruby objects.
247
+ def list_range(key, start = 0, count = 1)
248
+ if count == 1
249
+ decode redis.lindex(key, start)
250
+ else
251
+ Array(redis.lrange(key, start, start+count-1)).map do |item|
252
+ decode item
253
+ end
254
+ end
255
+ end
256
+
257
+ # Returns an array of all known Resque queues as strings.
258
+ def queues
259
+ Array(redis.smembers(:queues))
260
+ end
261
+
262
+ # Given a queue name, completely deletes the queue.
263
+ def remove_queue(queue)
264
+ redis.pipelined do
265
+ redis.srem(:queues, queue.to_s)
266
+ redis.del("queue:#{queue}")
267
+ end
268
+ end
269
+
270
+ # Used internally to keep track of which queues we've created.
271
+ # Don't call this directly.
272
+ def watch_queue(queue)
273
+ redis.sadd(:queues, queue.to_s)
274
+ end
275
+
276
+
277
+ #
278
+ # job shortcuts
279
+ #
280
+
281
+ # This method can be used to conveniently add a job to a queue.
282
+ # It assumes the class you're passing it is a real Ruby class (not
283
+ # a string or reference) which either:
284
+ #
285
+ # a) has a @queue ivar set
286
+ # b) responds to `queue`
287
+ #
288
+ # If either of those conditions are met, it will use the value obtained
289
+ # from performing one of the above operations to determine the queue.
290
+ #
291
+ # If no queue can be inferred this method will raise a `ResqueSqs::NoQueueError`
292
+ #
293
+ # Returns true if the job was queued, nil if the job was rejected by a
294
+ # before_enqueue hook.
295
+ #
296
+ # This method is considered part of the `stable` API.
297
+ def enqueue(klass, *args)
298
+ enqueue_to(queue_from_class(klass), klass, *args)
299
+ end
300
+
301
+ # Just like `enqueue` but allows you to specify the queue you want to
302
+ # use. Runs hooks.
303
+ #
304
+ # `queue` should be the String name of the queue you're targeting.
305
+ #
306
+ # Returns true if the job was queued, nil if the job was rejected by a
307
+ # before_enqueue hook.
308
+ #
309
+ # This method is considered part of the `stable` API.
310
+ def enqueue_to(queue, klass, *args)
311
+ # Perform before_enqueue hooks. Don't perform enqueue if any hook returns false
312
+ before_hooks = Plugin.before_enqueue_hooks(klass).collect do |hook|
313
+ klass.send(hook, *args)
314
+ end
315
+ return nil if before_hooks.any? { |result| result == false }
316
+
317
+ Job.create(queue, klass, *args)
318
+
319
+ Plugin.after_enqueue_hooks(klass).each do |hook|
320
+ klass.send(hook, *args)
321
+ end
322
+
323
+ return true
324
+ end
325
+
326
+ # This method can be used to conveniently remove a job from a queue.
327
+ # It assumes the class you're passing it is a real Ruby class (not
328
+ # a string or reference) which either:
329
+ #
330
+ # a) has a @queue ivar set
331
+ # b) responds to `queue`
332
+ #
333
+ # If either of those conditions are met, it will use the value obtained
334
+ # from performing one of the above operations to determine the queue.
335
+ #
336
+ # If no queue can be inferred this method will raise a `ResqueSqs::NoQueueError`
337
+ #
338
+ # If no args are given, this method will dequeue *all* jobs matching
339
+ # the provided class. See `ResqueSqs::Job.destroy` for more
340
+ # information.
341
+ #
342
+ # Returns the number of jobs destroyed.
343
+ #
344
+ # Example:
345
+ #
346
+ # # Removes all jobs of class `UpdateNetworkGraph`
347
+ # ResqueSqs.dequeue(GitHub::Jobs::UpdateNetworkGraph)
348
+ #
349
+ # # Removes all jobs of class `UpdateNetworkGraph` with matching args.
350
+ # ResqueSqs.dequeue(GitHub::Jobs::UpdateNetworkGraph, 'repo:135325')
351
+ #
352
+ # This method is considered part of the `stable` API.
353
+ def dequeue(klass, *args)
354
+ # Perform before_dequeue hooks. Don't perform dequeue if any hook returns false
355
+ before_hooks = Plugin.before_dequeue_hooks(klass).collect do |hook|
356
+ klass.send(hook, *args)
357
+ end
358
+ return if before_hooks.any? { |result| result == false }
359
+
360
+ destroyed = Job.destroy(queue_from_class(klass), klass, *args)
361
+
362
+ Plugin.after_dequeue_hooks(klass).each do |hook|
363
+ klass.send(hook, *args)
364
+ end
365
+
366
+ destroyed
367
+ end
368
+
369
+ # Given a class, try to extrapolate an appropriate queue based on a
370
+ # class instance variable or `queue` method.
371
+ def queue_from_class(klass)
372
+ klass.instance_variable_get(:@queue) ||
373
+ (klass.respond_to?(:queue) and klass.queue)
374
+ end
375
+
376
+ # This method will return a `ResqueSqs::Job` object or a non-true value
377
+ # depending on whether a job can be obtained. You should pass it the
378
+ # precise name of a queue: case matters.
379
+ #
380
+ # This method is considered part of the `stable` API.
381
+ def reserve(queue)
382
+ Job.reserve(queue)
383
+ end
384
+
385
+ # Validates if the given klass could be a valid Resque job
386
+ #
387
+ # If no queue can be inferred this method will raise a `ResqueSqs::NoQueueError`
388
+ #
389
+ # If given klass is nil this method will raise a `ResqueSqs::NoClassError`
390
+ def validate(klass, queue = nil)
391
+ queue ||= queue_from_class(klass)
392
+
393
+ if !queue
394
+ raise NoQueueError.new("Jobs must be placed onto a queue.")
395
+ end
396
+
397
+ if klass.to_s.empty?
398
+ raise NoClassError.new("Jobs must be given a class.")
399
+ end
400
+ end
401
+
402
+
403
+ #
404
+ # worker shortcuts
405
+ #
406
+
407
+ # A shortcut to Worker.all
408
+ def workers
409
+ Worker.all
410
+ end
411
+
412
+ # A shortcut to Worker.working
413
+ def working
414
+ Worker.working
415
+ end
416
+
417
+ # A shortcut to unregister_worker
418
+ # useful for command line tool
419
+ def remove_worker(worker_id)
420
+ worker = ResqueSqs::Worker.find(worker_id)
421
+ worker.unregister_worker
422
+ end
423
+
424
+ #
425
+ # stats
426
+ #
427
+
428
+ # Returns a hash, similar to redis-rb's #info, of interesting stats.
429
+ def info
430
+ return {
431
+ :pending => queues.inject(0) { |m,k| m + size(k) },
432
+ :processed => Stat[:processed],
433
+ :queues => queues.size,
434
+ :workers => workers.size.to_i,
435
+ :working => working.size,
436
+ :failed => ResqueSqs.redis.llen(:failed).to_i,
437
+ :servers => [redis_id],
438
+ :environment => ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
439
+ }
440
+ end
441
+
442
+ # Returns an array of all known Resque keys in Redis. Redis' KEYS operation
443
+ # is O(N) for the keyspace, so be careful - this can be slow for big databases.
444
+ def keys
445
+ redis.keys("*").map do |key|
446
+ key.sub("#{redis.namespace}:", '')
447
+ end
448
+ end
449
+
450
+ private
451
+
452
+ # Register a new proc as a hook. If the block is nil this is the
453
+ # equivalent of removing all hooks of the given name.
454
+ #
455
+ # `name` is the hook that the block should be registered with.
456
+ def register_hook(name, block)
457
+ return clear_hooks(name) if block.nil?
458
+
459
+ @hooks ||= {}
460
+ @hooks[name] ||= []
461
+
462
+ block = Array(block)
463
+ @hooks[name].concat(block)
464
+ end
465
+
466
+ # Clear all hooks given a hook name.
467
+ def clear_hooks(name)
468
+ @hooks && @hooks[name] = []
469
+ end
470
+
471
+ # Retrieve all hooks of a given name.
472
+ def hooks(name)
473
+ (@hooks && @hooks[name]) || []
474
+ end
475
+ end
476
+
477
+ # Log to STDOUT by default
478
+ ResqueSqs.logger = MonoLogger.new(STDOUT)
479
+ ResqueSqs.logger.formatter = ResqueSqs::QuietFormatter.new
@@ -0,0 +1,161 @@
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 RedisSqsRunner
7
+ def self.redis_dir
8
+ @redis_dir ||= if ENV['PREFIX']
9
+ Pathname.new(ENV['PREFIX'])
10
+ else
11
+ Pathname.new(`which redis-server`) + '..' + '..'
12
+ end
13
+ end
14
+
15
+ def self.bin_dir
16
+ redis_dir + 'bin'
17
+ end
18
+
19
+ def self.config
20
+ @config ||= if File.exists?(redis_dir + 'etc/redis.conf')
21
+ redis_dir + 'etc/redis.conf'
22
+ else
23
+ redis_dir + '../etc/redis.conf'
24
+ end
25
+ end
26
+
27
+ def self.dtach_socket
28
+ '/tmp/redis.dtach'
29
+ end
30
+
31
+ # Just check for existance of dtach socket
32
+ def self.running?
33
+ File.exists? dtach_socket
34
+ end
35
+
36
+ def self.start
37
+ puts 'Detach with Ctrl+\ Re-attach with rake redis_sqs:attach'
38
+ sleep 1
39
+ command = "#{bin_dir}/dtach -A #{dtach_socket} #{bin_dir}/redis-server #{config}"
40
+ sh command
41
+ end
42
+
43
+ def self.attach
44
+ exec "#{bin_dir}/dtach -a #{dtach_socket}"
45
+ end
46
+
47
+ def self.stop
48
+ sh 'echo "SHUTDOWN" | nc localhost 6379'
49
+ end
50
+ end
51
+
52
+ INSTALL_DIR = ENV['INSTALL_DIR'] || '/tmp/redis'
53
+
54
+ namespace :sqs_redis do
55
+ desc 'About redis'
56
+ task :about do
57
+ puts "\nSee http://code.google.com/p/redis/ for information about redis.\n\n"
58
+ end
59
+
60
+ desc 'Start redis'
61
+ task :start do
62
+ RedisSqsRunner.start
63
+ end
64
+
65
+ desc 'Stop redis'
66
+ task :stop do
67
+ RedisSqsRunner.stop
68
+ end
69
+
70
+ desc 'Restart redis'
71
+ task :restart do
72
+ RedisSqsRunner.stop
73
+ RedisSqsRunner.start
74
+ end
75
+
76
+ desc 'Attach to redis dtach socket'
77
+ task :attach do
78
+ RedisSqsRunner.attach
79
+ end
80
+
81
+ desc <<-DOC
82
+ Install the latest verison of Redis from Github (requires git, duh).
83
+ Use INSTALL_DIR env var like "rake redis_sqs:install INSTALL_DIR=~/tmp"
84
+ in order to get an alternate location for your install files.
85
+ DOC
86
+
87
+ task :install => [:about, :download, :make] do
88
+ bin_dir = '/usr/bin'
89
+ conf_dir = '/etc'
90
+
91
+ if ENV['PREFIX']
92
+ bin_dir = "#{ENV['PREFIX']}/bin"
93
+ sh "mkdir -p #{bin_dir}" unless File.exists?("#{bin_dir}")
94
+
95
+ conf_dir = "#{ENV['PREFIX']}/etc"
96
+ sh "mkdir -p #{conf_dir}" unless File.exists?("#{conf_dir}")
97
+ end
98
+
99
+ %w(redis-benchmark redis-cli redis-server).each do |bin|
100
+ sh "cp #{INSTALL_DIR}/src/#{bin} #{bin_dir}"
101
+ end
102
+
103
+ puts "Installed redis-benchmark, redis-cli and redis-server to #{bin_dir}"
104
+
105
+ unless File.exists?("#{conf_dir}/redis.conf")
106
+ sh "cp #{INSTALL_DIR}/redis.conf #{conf_dir}/redis.conf"
107
+ puts "Installed redis.conf to #{conf_dir} \n You should look at this file!"
108
+ end
109
+ end
110
+
111
+ task :make do
112
+ sh "cd #{INSTALL_DIR}/src && make clean"
113
+ sh "cd #{INSTALL_DIR}/src && make"
114
+ end
115
+
116
+ desc "Download package"
117
+ task :download do
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")
121
+ end
122
+ end
123
+
124
+ namespace :dtach_sqs do
125
+ desc 'About dtach'
126
+ task :about do
127
+ puts "\nSee http://dtach.sourceforge.net/ for information about dtach.\n\n"
128
+ end
129
+
130
+ desc 'Install dtach 0.8 from source'
131
+ task :install => [:about, :download, :make] do
132
+
133
+ bin_dir = "/usr/bin"
134
+
135
+
136
+ if ENV['PREFIX']
137
+ bin_dir = "#{ENV['PREFIX']}/bin"
138
+ sh "mkdir -p #{bin_dir}" unless File.exists?("#{bin_dir}")
139
+ end
140
+
141
+ sh "cp #{INSTALL_DIR}/dtach-0.8/dtach #{bin_dir}"
142
+ end
143
+
144
+ task :make do
145
+ sh "cd #{INSTALL_DIR}/dtach-0.8/ && ./configure && make"
146
+ end
147
+
148
+ desc "Download package"
149
+ task :download do
150
+ unless File.exists?("#{INSTALL_DIR}/dtach-0.8.tar.gz")
151
+ require 'net/http'
152
+
153
+ url = 'http://downloads.sourceforge.net/project/dtach/dtach/0.8/dtach-0.8.tar.gz'
154
+ open("#{INSTALL_DIR}/dtach-0.8.tar.gz", 'wb') do |file| file.write(open(url).read) end
155
+ end
156
+
157
+ unless File.directory?("#{INSTALL_DIR}/dtach-0.8")
158
+ sh "cd #{INSTALL_DIR} && tar xzf dtach-0.8.tar.gz"
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,2 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../../lib'
2
+ require 'resque_sqs/tasks'
@@ -0,0 +1,27 @@
1
+
2
+ require 'test_helper'
3
+
4
+ begin
5
+ require 'airbrake'
6
+ rescue LoadError
7
+ warn "Install airbrake gem to run Airbrake tests."
8
+ end
9
+
10
+ if defined? Airbrake
11
+ require 'resque_sqs/failure/airbrake'
12
+ context "Airbrake" do
13
+ test "should be notified of an error" do
14
+ exception = StandardError.new("BOOM")
15
+ worker = ResqueSqs::Worker.new(:test)
16
+ queue = "test"
17
+ payload = {'class' => Object, 'args' => 66}
18
+
19
+ Airbrake.expects(:notify_or_ignore).with(
20
+ exception,
21
+ :parameters => {:payload_class => 'Object', :payload_args => '66'})
22
+
23
+ backend = ResqueSqs::Failure::Airbrake.new(exception, worker, queue, payload)
24
+ backend.save
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,15 @@
1
+ require 'test_helper'
2
+ require 'minitest/mock'
3
+
4
+ require 'resque_sqs/failure/base'
5
+
6
+ class TestFailure < ResqueSqs::Failure::Base
7
+ end
8
+
9
+ describe "Base failure class" do
10
+ it "allows calling all without throwing" do
11
+ with_failure_backend TestFailure do
12
+ assert_empty ResqueSqs::Failure.all
13
+ end
14
+ end
15
+ end