Module: Resque
- Extended by:
- Resque
- Includes:
- Helpers
- Included in:
- Resque
- Defined in:
- lib/resque.rb,
lib/resque/job.rb,
lib/resque/stat.rb,
lib/resque/errors.rb,
lib/resque/plugin.rb,
lib/resque/server.rb,
lib/resque/worker.rb,
lib/resque/failure.rb,
lib/resque/helpers.rb,
lib/resque/version.rb,
lib/resque/failure/base.rb,
lib/resque/failure/mongo.rb,
lib/resque/failure/redis.rb,
lib/resque/failure/hoptoad.rb,
lib/resque/failure/multiple.rb,
lib/resque/server/test_helper.rb
Defined Under Namespace
Modules: Failure, Helpers, Plugin, Stat, TestHelper Classes: DirtyExit, Job, NoClassError, NoQueueError, QueueError, Server, Worker
Constant Summary collapse
- Version =
VERSION = '1.17.1'
Instance Method Summary collapse
-
#after_fork(&block) ⇒ Object
The ‘after_fork` hook will be run in the child process and is passed the current job.
-
#after_fork=(after_fork) ⇒ Object
Set the after_fork proc.
- #allows_delayed_jobs(klass) ⇒ Object
-
#before_first_fork(&block) ⇒ Object
The ‘before_first_fork` hook will be run in the parent process only once, before forking to run the first job.
-
#before_first_fork=(before_first_fork) ⇒ Object
Set a proc that will be called in the parent process before the worker forks for the first time.
-
#before_fork(&block) ⇒ Object
The ‘before_fork` hook will be run in the parent process before every job, so be careful- any changes you make will be permanent for the lifespan of the worker.
-
#before_fork=(before_fork) ⇒ Object
Set the before_fork proc.
-
#collection_for_queue(queue) ⇒ Object
Returns the mongo collection for a given queue.
- #delayed_size(queue) ⇒ Object
-
#dequeue(klass, *args) ⇒ Object
This method can be used to conveniently remove a job from a queue.
- #drop ⇒ Object
- #enable_delay(queue) ⇒ Object
-
#enqueue(klass, *args) ⇒ Object
This method can be used to conveniently add a job to a queue.
-
#info ⇒ Object
Returns a hash, similar to redis-rb’s #info, of interesting stats.
- #initialize_mongo ⇒ Object
- #inline=(inline) ⇒ Object
-
#inline? ⇒ Boolean
(also: #inline)
If ‘inline’ is true Resque will call #perform method inline without queuing it into Redis and without any Resque callbacks.
-
#keys ⇒ Object
Returns an array of all known Resque keys in Redis.
-
#list_range(key, start = 0, count = 1, mode = :ready) ⇒ Object
Does the dirty work of fetching a range of items from a Redis list and converting them into Ruby objects.
-
#mongo ⇒ Object
Returns the current Mongo::DB.
-
#mongo=(database) ⇒ Object
Set the queue database.
- #mongo_failures ⇒ Object
- #mongo_stats ⇒ Object
- #mongo_workers ⇒ Object
-
#peek(queue, start = 0, count = 1, mode = :ready) ⇒ Object
Returns an array of items currently queued.
-
#pop(queue) ⇒ Object
Pops a job off a queue.
-
#push(queue, item) ⇒ Object
Pushes a job onto a queue.
- #queue_allows_delayed(queue) ⇒ Object
-
#queue_from_class(klass) ⇒ Object
Given a class, try to extrapolate an appropriate queue based on a class instance variable or ‘queue` method.
-
#queues ⇒ Object
Returns an array of all known Resque queues as strings.
- #ready_size(queue) ⇒ Object
-
#remove_queue(queue) ⇒ Object
Given a queue name, completely deletes the queue.
-
#remove_worker(worker_id) ⇒ Object
A shortcut to unregister_worker useful for command line tool.
-
#reserve(queue) ⇒ Object
This method will return a ‘Resque::Job` object or a non-true value depending on whether a job can be obtained.
-
#size(queue) ⇒ Object
Returns an integer representing the size of a queue.
- #to_s ⇒ Object
-
#validate(klass, queue = nil) ⇒ Object
Validates if the given klass could be a valid Resque job.
-
#workers ⇒ Object
A shortcut to Worker.all.
-
#working ⇒ Object
A shortcut to Worker.working.
Methods included from Helpers
#classify, #constantize, #decode, #encode
Instance Method Details
#after_fork(&block) ⇒ Object
The ‘after_fork` hook will be run in the child process and is passed the current job. Any changes you make, therefore, will only live as long as the job currently being processed.
Call with a block to set the hook. Call with no arguments to return the hook.
103 104 105 |
# File 'lib/resque.rb', line 103 def after_fork(&block) block ? (@after_fork = block) : @after_fork end |
#after_fork=(after_fork) ⇒ Object
Set the after_fork proc.
108 109 110 |
# File 'lib/resque.rb', line 108 def after_fork=(after_fork) @after_fork = after_fork end |
#allows_delayed_jobs(klass) ⇒ Object
117 118 119 120 |
# File 'lib/resque.rb', line 117 def allows_delayed_jobs(klass) klass.instance_variable_get(:@delayed_jobs) || (klass.respond_to?(:delayed_jobs) and klass.delayed_jobs) end |
#before_first_fork(&block) ⇒ Object
The ‘before_first_fork` hook will be run in the parent process only once, before forking to run the first job. Be careful- any changes you make will be permanent for the lifespan of the worker.
Call with a block to set the hook. Call with no arguments to return the hook.
72 73 74 |
# File 'lib/resque.rb', line 72 def before_first_fork(&block) block ? (@before_first_fork = block) : @before_first_fork end |
#before_first_fork=(before_first_fork) ⇒ Object
Set a proc that will be called in the parent process before the worker forks for the first time.
78 79 80 |
# File 'lib/resque.rb', line 78 def before_first_fork=(before_first_fork) @before_first_fork = before_first_fork end |
#before_fork(&block) ⇒ Object
The ‘before_fork` hook will be run in the parent process before every job, so be careful- any changes you make will be permanent for the lifespan of the worker.
Call with a block to set the hook. Call with no arguments to return the hook.
88 89 90 |
# File 'lib/resque.rb', line 88 def before_fork(&block) block ? (@before_fork = block) : @before_fork end |
#before_fork=(before_fork) ⇒ Object
Set the before_fork proc.
93 94 95 |
# File 'lib/resque.rb', line 93 def before_fork=(before_fork) @before_fork = before_fork end |
#collection_for_queue(queue) ⇒ Object
Returns the mongo collection for a given queue
257 258 259 260 |
# File 'lib/resque.rb', line 257 def collection_for_queue(queue) queue = namespace_queue(queue) mongo[queue] end |
#delayed_size(queue) ⇒ Object
195 196 197 198 199 200 201 202 |
# File 'lib/resque.rb', line 195 def delayed_size(queue) queue = namespace_queue(queue) if queue_allows_delayed queue mongo[queue].find({'delay_until' => { '$gt' => Time.now }}).count else mongo[queue].count end end |
#dequeue(klass, *args) ⇒ Object
This method can be used to conveniently remove a job from a queue. It assumes the class you’re passing it is a real Ruby class (not a string or reference) which either:
a) has a @queue ivar set
b) responds to `queue`
If either of those conditions are met, it will use the value obtained from performing one of the above operations to determine the queue.
If no queue can be inferred this method will raise a ‘Resque::NoQueueError`
If no args are given, this method will dequeue all jobs matching the provided class. See ‘Resque::Job.destroy` for more information.
Returns the number of jobs destroyed.
Example:
# Removes all jobs of class `UpdateNetworkGraph`
Resque.dequeue(GitHub::Jobs::UpdateNetworkGraph)
# Removes all jobs of class `UpdateNetworkGraph` with matching args.
Resque.dequeue(GitHub::Jobs::UpdateNetworkGraph, 'repo:135325')
This method is considered part of the ‘stable` API.
320 321 322 |
# File 'lib/resque.rb', line 320 def dequeue(klass, *args) Job.destroy(queue_from_class(klass), klass, *args) end |
#drop ⇒ Object
403 404 405 406 |
# File 'lib/resque.rb', line 403 def drop mongo.collections.each{ |collection| collection.drop unless collection.name =~ /^system./ } @mongo = nil end |
#enable_delay(queue) ⇒ Object
127 128 129 130 131 132 133 |
# File 'lib/resque.rb', line 127 def enable_delay(queue) queue = namespace_queue(queue) unless queue_allows_delayed queue @delay_allowed << queue mongo_stats.update({:stat => 'Delayable Queues'}, { '$addToSet' => { 'value' => queue}}, { :upsert => true}) end end |
#enqueue(klass, *args) ⇒ Object
This method can be used to conveniently add a job to a queue. It assumes the class you’re passing it is a real Ruby class (not a string or reference) which either:
a) has a @queue ivar set
b) responds to `queue`
If either of those conditions are met, it will use the value obtained from performing one of the above operations to determine the queue.
If no queue can be inferred this method will raise a ‘Resque::NoQueueError`
This method is considered part of the ‘stable` API.
285 286 287 288 289 290 291 |
# File 'lib/resque.rb', line 285 def enqueue(klass, *args) Job.create(queue_from_class(klass), klass, *args) Plugin.after_enqueue_hooks(klass).each do |hook| klass.send(hook, *args) end end |
#info ⇒ Object
Returns a hash, similar to redis-rb’s #info, of interesting stats.
384 385 386 387 388 389 390 391 392 393 394 395 |
# File 'lib/resque.rb', line 384 def info return { :pending => queues.inject(0) { |m,k| m + size(k) }, :processed => Stat[:processed], :queues => queues.size, :workers => workers.size.to_i, :working => working.count, :failed => Stat[:failed], :servers => to_s, :environment => ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development' } end |
#initialize_mongo ⇒ Object
46 47 48 49 50 51 |
# File 'lib/resque.rb', line 46 def initialize_mongo mongo_workers.create_index :worker mongo_stats.create_index :stat delay_allowed = mongo_stats.find_one({ :stat => 'Delayable Queues'}, { :fields => ['value']}) @delay_allowed = delay_allowed['value'].map{ |queue| queue.to_sym} if delay_allowed end |
#inline=(inline) ⇒ Object
143 144 145 |
# File 'lib/resque.rb', line 143 def inline=(inline) @inline = inline end |
#inline? ⇒ Boolean Also known as: inline
If ‘inline’ is true Resque will call #perform method inline without queuing it into Redis and without any Resque callbacks. The ‘inline’ is false Resque jobs will be put in queue regularly.
138 139 140 |
# File 'lib/resque.rb', line 138 def inline? @inline end |
#keys ⇒ Object
Returns an array of all known Resque keys in Redis. Redis’ KEYS operation is O(N) for the keyspace, so be careful - this can be slow for big databases.
399 400 401 |
# File 'lib/resque.rb', line 399 def keys names = mongo.collection_names end |
#list_range(key, start = 0, count = 1, mode = :ready) ⇒ Object
Does the dirty work of fetching a range of items from a Redis list and converting them into Ruby objects.
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
# File 'lib/resque.rb', line 228 def list_range(key, start = 0, count = 1, mode = :ready) query = { } sort = [] if queue_allows_delayed(key) if mode == :ready query['delay_until'] = { '$not' => { '$gt' => Time.new}} elsif mode == :delayed query['delay_until'] = { '$gt' => Time.new} elsif mode == :delayed_sorted query['delay_until'] = { '$gt' => Time.new} sort << ['delay_until', 1] elsif mode == :all_sorted query = {} sort << ['delay_until', 1] end end queue = namespace_queue(key) items = mongo[queue].find(query, { :limit => count, :skip => start, :sort => sort}).to_a.map{ |i| i} count > 1 ? items : items.first end |
#mongo ⇒ Object
Returns the current Mongo::DB. If none has been created, it will create a new one called ‘resque’.
40 41 42 43 44 |
# File 'lib/resque.rb', line 40 def mongo return @mongo if @mongo self.mongo = Mongo::Connection.new.db("resque") @mongo end |
#mongo=(database) ⇒ Object
Set the queue database. Expects a Mongo::DB object.
29 30 31 32 33 34 35 36 |
# File 'lib/resque.rb', line 29 def mongo=(database) if database.is_a?(Mongo::DB) @mongo = database initialize_mongo else raise ArgumentError, "Resque.mongo= expects a Mongo::DB database, not a #{database.class}." end end |
#mongo_failures ⇒ Object
61 62 63 |
# File 'lib/resque.rb', line 61 def mongo_failures mongo['resque.failures'] end |
#mongo_stats ⇒ Object
57 58 59 |
# File 'lib/resque.rb', line 57 def mongo_stats mongo['resque.metrics'] end |
#mongo_workers ⇒ Object
53 54 55 |
# File 'lib/resque.rb', line 53 def mongo_workers mongo['resque.workers'] end |
#peek(queue, start = 0, count = 1, mode = :ready) ⇒ Object
Returns an array of items currently queued. Queue name should be a string.
start and count should be integer and can be used for pagination. start is the item to begin, count is how many items to return.
To get the 3rd page of a 30 item, paginatied list one would use:
Resque.peek('my_list', 59, 30)
222 223 224 |
# File 'lib/resque.rb', line 222 def peek(queue, start = 0, count = 1, mode = :ready) list_range(queue, start, count, mode) end |
#pop(queue) ⇒ Object
Pops a job off a queue. Queue name should be a string.
Returns a Ruby object.
175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/resque.rb', line 175 def pop(queue) queue = namespace_queue(queue) query = {} if queue_allows_delayed queue query['delay_until'] = { '$lt' => Time.now } end #sorting will result in significant performance penalties for large queues, you have been warned. item = mongo[queue].find_and_modify(:query => query, :remove => true, :sort => [[:_id, :asc]] ) rescue Mongo::OperationFailure => e return nil if e. =~ /No matching object/ raise e end |
#push(queue, item) ⇒ Object
Pushes a job onto a queue. Queue name should be a string and the item should be any JSON-able Ruby object.
Resque works generally expect the ‘item` to be a hash with the following keys:
class - The String name of the job to run.
args - An Array of arguments to pass the job. Usually passed
via `class.to_class.perform(*args)`.
Example
Resque.push('archive', :class => 'Archive', :args => [ 35, 'tar' ])
Returns nothing
166 167 168 169 170 |
# File 'lib/resque.rb', line 166 def push(queue, item) queue = namespace_queue(queue) item[:resque_enqueue_timestamp] = Time.now mongo[queue] << item end |
#queue_allows_delayed(queue) ⇒ Object
122 123 124 125 |
# File 'lib/resque.rb', line 122 def queue_allows_delayed(queue) queue = namespace_queue(queue) @delay_allowed.include?(queue.to_sym) || @delay_allowed.include?(queue.to_s) end |
#queue_from_class(klass) ⇒ Object
Given a class, try to extrapolate an appropriate queue based on a class instance variable or ‘queue` method.
326 327 328 329 |
# File 'lib/resque.rb', line 326 def queue_from_class(klass) klass.instance_variable_get(:@queue) || (klass.respond_to?(:queue) and klass.queue) end |
#queues ⇒ Object
Returns an array of all known Resque queues as strings.
250 251 252 253 254 |
# File 'lib/resque.rb', line 250 def queues mongo.collection_names. select { |name| name =~ /resque\.queues\./ }. collect { |name| name.split(".")[2..-1].join('.') } end |
#ready_size(queue) ⇒ Object
204 205 206 207 208 209 210 211 |
# File 'lib/resque.rb', line 204 def ready_size(queue) queue = namespace_queue(queue) if queue_allows_delayed queue mongo[queue].find({'delay_until' => { '$lt' => Time.now }}).count else mongo[queue].count end end |
#remove_queue(queue) ⇒ Object
Given a queue name, completely deletes the queue.
263 264 265 266 |
# File 'lib/resque.rb', line 263 def remove_queue(queue) queue = namespace_queue(queue) mongo[queue].drop end |
#remove_worker(worker_id) ⇒ Object
A shortcut to unregister_worker useful for command line tool
374 375 376 377 |
# File 'lib/resque.rb', line 374 def remove_worker(worker_id) worker = Resque::Worker.find(worker_id) worker.unregister_worker end |
#reserve(queue) ⇒ Object
This method will return a ‘Resque::Job` object or a non-true value depending on whether a job can be obtained. You should pass it the precise name of a queue: case matters.
This method is considered part of the ‘stable` API.
336 337 338 |
# File 'lib/resque.rb', line 336 def reserve(queue) Job.reserve(queue) end |
#size(queue) ⇒ Object
Returns an integer representing the size of a queue. Queue name should be a string.
190 191 192 193 |
# File 'lib/resque.rb', line 190 def size(queue) queue = namespace_queue(queue) mongo[queue].count end |
#to_s ⇒ Object
112 113 114 115 |
# File 'lib/resque.rb', line 112 def to_s connection_info = mongo.connection.primary_pool "Resque Client connected to #{connection_info.host}:#{connection_info.port}/#{mongo.name}" end |
#validate(klass, queue = nil) ⇒ Object
Validates if the given klass could be a valid Resque job
If no queue can be inferred this method will raise a ‘Resque::NoQueueError`
If given klass is nil this method will raise a ‘Resque::NoClassError`
345 346 347 348 349 350 351 352 353 354 355 |
# File 'lib/resque.rb', line 345 def validate(klass, queue = nil) queue ||= queue_from_class(klass) if !queue raise NoQueueError.new("Jobs must be placed onto a queue.") end if klass.to_s.empty? raise NoClassError.new("Jobs must be given a class.") end end |