0
-Delated_job (or DJ) encapsulates the common pattern of asynchronously executing longer tasks in the background.
0
-It is a direct extraction from Shopify where the job table is responsible for a multitude of core tasks. Amongst those tasks are:
0
-* sending massive newsletters
0
-* updating smart collections
0
-* updating solr, our search server, after product changes
0
-1.5 Job runners can now be run in parallel. Two new database columns are needed: locked_until and locked_by. This allows us
0
- to use pessimistic locking, which enables us to run as many worker processes as we need to speed up queue processing.
0
-The library evolves around a delayed_jobs table which looks as follows:
0
- create_table :delayed_jobs, :force => true do |table|
0
- table.integer :priority, :default => 0
0
- table.integer :attempts, :default => 0
0
- table.string :last_error
0
- table.datetime :run_at
0
- table.datetime :locked_until
0
- table.string :locked_by
0
-Jobs are simple ruby objects with a method called perform. Any object which responds to perform can be stuffed into the jobs table.
0
-Job objects are serialized to yaml so that they can later be resurrected by the job runner.
0
- class NewsletterJob < Struct.new(:text, :emails)
0
- emails.each { |e| NewsletterMailer.deliver_text_to_email(text, e) }
0
- Delayed::Job.enqueue NewsletterJob.new('lorem ipsum...', Customers.find(:all).collect(&:email))
0
-There is also a second way to get jobs in the queue: send_later.
0
- BatchImporter.new(Shop.find(1)).send_later(:import_massive_csv, massive_csv)
0
-This will simply create a Delayed::PerformableMethod job in the jobs table which serializes all the parameters you pass to it. There are some special smarts for active record objects
0
-which are stored as their text representation and loaded from the database fresh when the job is actually run later.
0
-== Running the tasks ==
0
-You can invoke rake jobs:work which will start working off jobs. You can cancel the rake task by CTRL-C.
0
-At Shopify we run the the tasks from a simple script/job_runner which is being invoked by runnit:
0
- require File.dirname(__FILE__) + '/../config/environment'
0
- trap('TERM') { puts 'Exiting...'; $exit = true }
0
- trap('INT') { puts 'Exiting...'; $exit = true }
0
- puts "*** Staring job worker #{Delayed::Job.worker_name}"
0
- realtime = Benchmark.realtime do
0
- result = Delayed::Job.work_off
0
- puts 'Waiting for more jobs...'
0
- status = "#{count} jobs processed at %.4f j/s, %d failed ..." % [count / realtime, result.last]
0
- RAILS_DEFAULT_LOGGER.info status
0
- Delayed::Job.clear_locks!
Comments
No one has commented yet.