pax_global_header00006660000000000000000000000064124460507720014521gustar00rootroot0000000000000052 comment=270b06eef0879a7ea167eb41182336aa14fb762e delayed_job_active_record-4.0.3/000077500000000000000000000000001244605077200166575ustar00rootroot00000000000000delayed_job_active_record-4.0.3/.gitignore000066400000000000000000000000651244605077200206500ustar00rootroot00000000000000*.swp .bundle .rvmrc Gemfile.lock bin coverage pkg/* delayed_job_active_record-4.0.3/.rspec000066400000000000000000000000241244605077200177700ustar00rootroot00000000000000--color --fail-fast delayed_job_active_record-4.0.3/.rubocop.yml000066400000000000000000000024751244605077200211410ustar00rootroot00000000000000AllCops: RunRailsCops: true ################# # [i] Overrides # ################# CollectionMethods: # Mapping from undesired method to desired_method # e.g. to use `detect` over `find`: # # CollectionMethods: # PreferredMethods: # find: detect PreferredMethods: collect: 'map' collect!: 'map!' reduce: 'inject' find_all: 'select' find: 'detect' # Multi-line method chaining should be done with leading dots. DotPosition: EnforcedStyle: trailing # Align ends correctly. EndAlignment: AlignWith: variable IfUnlessModifier: MaxLineLength: 75 LineLength: Max: 200 SignalException: EnforcedStyle: only_raise SpaceInsideBlockBraces: SpaceBeforeBlockParameters: false SpaceInsideHashLiteralBraces: EnforcedStyle: no_space StringLiterals: EnforcedStyle: double_quotes ################# # Disabled cops # ################# AbcSize: Enabled: false ClassAndModuleChildren: Enabled: false ClassLength: Enabled: false CyclomaticComplexity: Enabled: false Documentation: Enabled: false EachWithObject: Enabled: false FormatString: Enabled: false Lambda: Enabled: false MethodLength: Enabled: false NegatedIf: Enabled: false Semicolon: Enabled: false SingleLineBlockParams: Enabled: false TrailingComma: Enabled: false WordArray: Enabled: false delayed_job_active_record-4.0.3/.travis.yml000066400000000000000000000027001244605077200207670ustar00rootroot00000000000000language: ruby before_script: - mysql -e 'create database delayed_job_test;' - psql -c 'create database delayed_job_test;' -U postgres script: bundle exec rspec env: global: - JRUBY_OPTS="$JRUBY_OPTS --debug" gemfile: - gemfiles/mysql/3-0.gemfile - gemfiles/mysql/3-1.gemfile - gemfiles/mysql/3-2.gemfile - gemfiles/mysql/4-0.gemfile - gemfiles/mysql/4-1.gemfile - gemfiles/mysql/4-2.gemfile - gemfiles/postgresql/3-0.gemfile - gemfiles/postgresql/3-1.gemfile - gemfiles/postgresql/3-2.gemfile - gemfiles/postgresql/4-0.gemfile - gemfiles/postgresql/4-1.gemfile - gemfiles/postgresql/4-2.gemfile - gemfiles/sqlite3/3-0.gemfile - gemfiles/sqlite3/3-1.gemfile - gemfiles/sqlite3/3-2.gemfile - gemfiles/sqlite3/4-0.gemfile - gemfiles/sqlite3/4-0-protected_attributes.gemfile - gemfiles/sqlite3/4-1.gemfile - gemfiles/sqlite3/4-2.gemfile rvm: - 1.9.3 - 2.0.0 - 2.1 - jruby-19mode - jruby-head - rbx-2 - ruby-head matrix: allow_failures: - rvm: jruby-19mode - rvm: jruby-head - rvm: rbx-2 - rvm: ruby-head exclude: - gemfile: gemfiles/mysql/4-1.gemfile rvm: 1.9.3 - gemfile: gemfiles/mysql/4-2.gemfile rvm: 1.9.3 - gemfile: gemfiles/postgresql/4-1.gemfile rvm: 1.9.3 - gemfile: gemfiles/postgresql/4-2.gemfile rvm: 1.9.3 - gemfile: gemfiles/sqlite3/4-1.gemfile rvm: 1.9.3 - gemfile: gemfiles/sqlite3/4-2.gemfile rvm: 1.9.3 sudo: false delayed_job_active_record-4.0.3/CONTRIBUTING.md000066400000000000000000000012331244605077200211070ustar00rootroot00000000000000## How to contribute If you find what looks like a bug: * Search the [mailing list](http://groups.google.com/group/delayed_job) to see if anyone else had the same issue. * Check the [GitHub issue tracker](http://github.com/collectiveidea/delayed_job_active_record/issues/) to see if anyone else has reported issue. * If you don't see anything, create an issue with information on how to reproduce it. If you want to contribute an enhancement or a fix: * Fork the project on github. * Make your changes with tests. * Commit the changes without making changes to the Rakefile or any other files that aren't related to your enhancement or fix * Send a pull request. delayed_job_active_record-4.0.3/Gemfile000066400000000000000000000010061244605077200201470ustar00rootroot00000000000000source "https://rubygems.org" gem "rake" group :test do platforms :jruby do gem "activerecord-jdbcmysql-adapter" gem "jdbc-mysql" gem "activerecord-jdbcpostgresql-adapter" gem "jdbc-postgres" gem "activerecord-jdbcsqlite3-adapter" gem "jdbc-sqlite3" end platforms :ruby, :mswin, :mingw do gem "mysql", "~> 2.9" gem "pg" gem "sqlite3" end gem "coveralls", require: false gem "rspec", ">= 3" gem "rubocop", ">= 0.23" gem "simplecov", require: false end gemspec delayed_job_active_record-4.0.3/LICENSE.md000066400000000000000000000020401244605077200202570ustar00rootroot00000000000000Copyright (c) 2005 Tobias Lütke Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOa AND NONINFRINGEMENT. IN NO EVENT SaALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. delayed_job_active_record-4.0.3/README.md000066400000000000000000000025431244605077200201420ustar00rootroot00000000000000# DelayedJob ActiveRecord Backend [![Gem Version](https://badge.fury.io/rb/delayed_job_active_record.png)](https://rubygems.org/gems/delayed_job_active_record) [![Build Status](https://travis-ci.org/collectiveidea/delayed_job_active_record.png)](https://travis-ci.org/collectiveidea/delayed_job_active_record) [![Dependency Status](https://gemnasium.com/collectiveidea/delayed_job_active_record.png)](https://gemnasium.com/collectiveidea/delayed_job_active_record) [![Code Climate](https://codeclimate.com/github/collectiveidea/delayed_job_active_record.png)](https://codeclimate.com/github/collectiveidea/delayed_job_active_record) [![Coverage Status](https://coveralls.io/repos/collectiveidea/delayed_job_active_record/badge.png?branch=master)](https://coveralls.io/r/collectiveidea/delayed_job_active_record) ## Installation Add the gem to your Gemfile: gem 'delayed_job_active_record' Run `bundle install`. If you're using Rails, run the generator to create the migration for the delayed_job table. rails g delayed_job:active_record rake db:migrate ## Upgrading from 2.x to 3.0.0 If you're upgrading from Delayed Job 2.x, run the upgrade generator to create a migration to add a column to your delayed_jobs table. rails g delayed_job:upgrade rake db:migrate That's it. Use [delayed_job as normal](http://github.com/collectiveidea/delayed_job). delayed_job_active_record-4.0.3/Rakefile000066400000000000000000000013301244605077200203210ustar00rootroot00000000000000require "bundler/gem_helper" Bundler::GemHelper.install_tasks require "rspec/core/rake_task" ADAPTERS = %w(mysql postgresql sqlite3) ADAPTERS.each do |adapter| desc "Run RSpec code examples for #{adapter} adapter" RSpec::Core::RakeTask.new(adapter => "#{adapter}:adapter") namespace adapter do task :adapter do ENV["ADAPTER"] = adapter end end end task :coverage do ENV["COVERAGE"] = "true" end task :adapter do ENV["ADAPTER"] = nil end Rake::Task[:spec].enhance do require "simplecov" require "coveralls" Coveralls::SimpleCov::Formatter.new.format(SimpleCov.result) end require "rubocop/rake_task" RuboCop::RakeTask.new task default: ([:coverage] + ADAPTERS + [:adapter] + [:rubocop]) delayed_job_active_record-4.0.3/delayed_job_active_record.gemspec000066400000000000000000000015151244605077200253600ustar00rootroot00000000000000Gem::Specification.new do |spec| spec.add_dependency "activerecord", [">= 3.0", "< 5.0"] spec.add_dependency "delayed_job", [">= 3.0", "< 4.1"] spec.authors = ["Brian Ryckbost", "Matt Griffin", "Erik Michaels-Ober"] spec.description = "ActiveRecord backend for Delayed::Job, originally authored by Tobias Lütke" spec.email = ["bryckbost@gmail.com", "matt@griffinonline.org", "sferik@gmail.com"] spec.files = %w(CONTRIBUTING.md LICENSE.md README.md delayed_job_active_record.gemspec) + Dir["lib/**/*.rb"] spec.homepage = "http://github.com/collectiveidea/delayed_job_active_record" spec.licenses = ["MIT"] spec.name = "delayed_job_active_record" spec.require_paths = ["lib"] spec.summary = "ActiveRecord backend for DelayedJob" spec.version = "4.0.3" end delayed_job_active_record-4.0.3/gemfiles/000077500000000000000000000000001244605077200204525ustar00rootroot00000000000000delayed_job_active_record-4.0.3/gemfiles/mysql/000077500000000000000000000000001244605077200216175ustar00rootroot00000000000000delayed_job_active_record-4.0.3/gemfiles/mysql/3-0.gemfile000066400000000000000000000006451244605077200234550ustar00rootroot00000000000000source 'https://rubygems.org' gem 'rake' group :test do platforms :jruby do gem 'activerecord-jdbc-adapter' gem 'activerecord-jdbcmysql-adapter' gem 'jdbc-mysql' end platforms :ruby, :mswin, :mingw do gem 'mysql', '~> 2.8.1' end gem 'coveralls', :require => false gem 'rspec', '>= 2.11' gem 'simplecov', :require => false gem 'activerecord', "~> 3.0.0" end gemspec :path => "../../" delayed_job_active_record-4.0.3/gemfiles/mysql/3-1.gemfile000066400000000000000000000006451244605077200234560ustar00rootroot00000000000000source 'https://rubygems.org' gem 'rake' group :test do platforms :jruby do gem 'activerecord-jdbc-adapter' gem 'activerecord-jdbcmysql-adapter' gem 'jdbc-mysql' end platforms :ruby, :mswin, :mingw do gem 'mysql', '~> 2.8.1' end gem 'coveralls', :require => false gem 'rspec', '>= 2.11' gem 'simplecov', :require => false gem 'activerecord', "~> 3.1.0" end gemspec :path => "../../" delayed_job_active_record-4.0.3/gemfiles/mysql/3-2.gemfile000066400000000000000000000006451244605077200234570ustar00rootroot00000000000000source 'https://rubygems.org' gem 'rake' group :test do platforms :jruby do gem 'activerecord-jdbc-adapter' gem 'activerecord-jdbcmysql-adapter' gem 'jdbc-mysql' end platforms :ruby, :mswin, :mingw do gem 'mysql', '~> 2.8.1' end gem 'coveralls', :require => false gem 'rspec', '>= 2.11' gem 'simplecov', :require => false gem 'activerecord', "~> 3.2.0" end gemspec :path => "../../" delayed_job_active_record-4.0.3/gemfiles/mysql/4-0.gemfile000066400000000000000000000006431244605077200234540ustar00rootroot00000000000000source 'https://rubygems.org' gem 'rake' group :test do platforms :jruby do gem 'activerecord-jdbc-adapter' gem 'activerecord-jdbcmysql-adapter' gem 'jdbc-mysql' end platforms :ruby, :mswin, :mingw do gem 'mysql', '~> 2.9' end gem 'coveralls', :require => false gem 'rspec', '>= 2.11' gem 'simplecov', :require => false gem 'activerecord', "~> 4.0.0" end gemspec :path => "../../" delayed_job_active_record-4.0.3/gemfiles/mysql/4-1.gemfile000066400000000000000000000006431244605077200234550ustar00rootroot00000000000000source 'https://rubygems.org' gem 'rake' group :test do platforms :jruby do gem 'activerecord-jdbc-adapter' gem 'activerecord-jdbcmysql-adapter' gem 'jdbc-mysql' end platforms :ruby, :mswin, :mingw do gem 'mysql', '~> 2.9' end gem 'coveralls', :require => false gem 'rspec', '>= 2.11' gem 'simplecov', :require => false gem 'activerecord', "~> 4.1.0" end gemspec :path => "../../" delayed_job_active_record-4.0.3/gemfiles/mysql/4-2.gemfile000066400000000000000000000006431244605077200234560ustar00rootroot00000000000000source 'https://rubygems.org' gem 'rake' group :test do platforms :jruby do gem 'activerecord-jdbc-adapter' gem 'activerecord-jdbcmysql-adapter' gem 'jdbc-mysql' end platforms :ruby, :mswin, :mingw do gem 'mysql', '~> 2.9' end gem 'coveralls', :require => false gem 'rspec', '>= 2.11' gem 'simplecov', :require => false gem 'activerecord', "~> 4.2.0" end gemspec :path => "../../" delayed_job_active_record-4.0.3/gemfiles/postgresql/000077500000000000000000000000001244605077200226555ustar00rootroot00000000000000delayed_job_active_record-4.0.3/gemfiles/postgresql/3-0.gemfile000066400000000000000000000006361244605077200245130ustar00rootroot00000000000000source 'https://rubygems.org' gem 'rake' group :test do platforms :jruby do gem 'activerecord-jdbc-adapter' gem 'activerecord-jdbcpostgresql-adapter' gem 'jdbc-postgres' end platforms :ruby, :mswin, :mingw do gem 'pg' end gem 'coveralls', :require => false gem 'rspec', '>= 2.11' gem 'simplecov', :require => false gem 'activerecord', "~> 3.0.0" end gemspec :path => "../../" delayed_job_active_record-4.0.3/gemfiles/postgresql/3-1.gemfile000066400000000000000000000006361244605077200245140ustar00rootroot00000000000000source 'https://rubygems.org' gem 'rake' group :test do platforms :jruby do gem 'activerecord-jdbc-adapter' gem 'activerecord-jdbcpostgresql-adapter' gem 'jdbc-postgres' end platforms :ruby, :mswin, :mingw do gem 'pg' end gem 'coveralls', :require => false gem 'rspec', '>= 2.11' gem 'simplecov', :require => false gem 'activerecord', "~> 3.1.0" end gemspec :path => "../../" delayed_job_active_record-4.0.3/gemfiles/postgresql/3-2.gemfile000066400000000000000000000006361244605077200245150ustar00rootroot00000000000000source 'https://rubygems.org' gem 'rake' group :test do platforms :jruby do gem 'activerecord-jdbc-adapter' gem 'activerecord-jdbcpostgresql-adapter' gem 'jdbc-postgres' end platforms :ruby, :mswin, :mingw do gem 'pg' end gem 'coveralls', :require => false gem 'rspec', '>= 2.11' gem 'simplecov', :require => false gem 'activerecord', "~> 3.2.0" end gemspec :path => "../../" delayed_job_active_record-4.0.3/gemfiles/postgresql/4-0.gemfile000066400000000000000000000006361244605077200245140ustar00rootroot00000000000000source 'https://rubygems.org' gem 'rake' group :test do platforms :jruby do gem 'activerecord-jdbc-adapter' gem 'activerecord-jdbcpostgresql-adapter' gem 'jdbc-postgres' end platforms :ruby, :mswin, :mingw do gem 'pg' end gem 'coveralls', :require => false gem 'rspec', '>= 2.11' gem 'simplecov', :require => false gem 'activerecord', "~> 4.0.0" end gemspec :path => "../../" delayed_job_active_record-4.0.3/gemfiles/postgresql/4-1.gemfile000066400000000000000000000006361244605077200245150ustar00rootroot00000000000000source 'https://rubygems.org' gem 'rake' group :test do platforms :jruby do gem 'activerecord-jdbc-adapter' gem 'activerecord-jdbcpostgresql-adapter' gem 'jdbc-postgres' end platforms :ruby, :mswin, :mingw do gem 'pg' end gem 'coveralls', :require => false gem 'rspec', '>= 2.11' gem 'simplecov', :require => false gem 'activerecord', "~> 4.1.0" end gemspec :path => "../../" delayed_job_active_record-4.0.3/gemfiles/postgresql/4-2.gemfile000066400000000000000000000006361244605077200245160ustar00rootroot00000000000000source 'https://rubygems.org' gem 'rake' group :test do platforms :jruby do gem 'activerecord-jdbc-adapter' gem 'activerecord-jdbcpostgresql-adapter' gem 'jdbc-postgres' end platforms :ruby, :mswin, :mingw do gem 'pg' end gem 'coveralls', :require => false gem 'rspec', '>= 2.11' gem 'simplecov', :require => false gem 'activerecord', "~> 4.2.0" end gemspec :path => "../../" delayed_job_active_record-4.0.3/gemfiles/sqlite3/000077500000000000000000000000001244605077200220365ustar00rootroot00000000000000delayed_job_active_record-4.0.3/gemfiles/sqlite3/3-0.gemfile000066400000000000000000000006401244605077200236670ustar00rootroot00000000000000source 'https://rubygems.org' gem 'rake' group :test do platforms :jruby do gem 'jruby-openssl' gem 'activerecord-jdbc-adapter' gem 'activerecord-jdbcsqlite3-adapter' end platforms :ruby, :mswin, :mingw do gem 'sqlite3' end gem 'coveralls', :require => false gem 'rspec', '>= 2.11' gem 'simplecov', :require => false gem 'activerecord', "~> 3.0.0" end gemspec :path => "../../" delayed_job_active_record-4.0.3/gemfiles/sqlite3/3-1.gemfile000066400000000000000000000006401244605077200236700ustar00rootroot00000000000000source 'https://rubygems.org' gem 'rake' group :test do platforms :jruby do gem 'jruby-openssl' gem 'activerecord-jdbc-adapter' gem 'activerecord-jdbcsqlite3-adapter' end platforms :ruby, :mswin, :mingw do gem 'sqlite3' end gem 'coveralls', :require => false gem 'rspec', '>= 2.11' gem 'simplecov', :require => false gem 'activerecord', "~> 3.1.0" end gemspec :path => "../../" delayed_job_active_record-4.0.3/gemfiles/sqlite3/3-2.gemfile000066400000000000000000000006401244605077200236710ustar00rootroot00000000000000source 'https://rubygems.org' gem 'rake' group :test do platforms :jruby do gem 'jruby-openssl' gem 'activerecord-jdbc-adapter' gem 'activerecord-jdbcsqlite3-adapter' end platforms :ruby, :mswin, :mingw do gem 'sqlite3' end gem 'coveralls', :require => false gem 'rspec', '>= 2.11' gem 'simplecov', :require => false gem 'activerecord', "~> 3.2.0" end gemspec :path => "../../" delayed_job_active_record-4.0.3/gemfiles/sqlite3/4-0-protected_attributes.gemfile000066400000000000000000000010501244605077200301210ustar00rootroot00000000000000source 'https://rubygems.org' gem 'rake' group :test do platforms :jruby do gem 'jruby-openssl' gem 'activerecord-jdbc-adapter' gem 'activerecord-jdbcsqlite3-adapter' end platforms :ruby, :mswin, :mingw do gem 'sqlite3' end gem 'coveralls', :require => false gem 'rspec', '>= 2.11', :require => false gem 'simplecov', :require => false gem 'activerecord', "~> 4.0.0.beta" gem 'protected_attributes' gem 'delayed_job', "~> 4.0.0.beta", :require => false end gemspec :path => "../../" delayed_job_active_record-4.0.3/gemfiles/sqlite3/4-0.gemfile000066400000000000000000000006401244605077200236700ustar00rootroot00000000000000source 'https://rubygems.org' gem 'rake' group :test do platforms :jruby do gem 'jruby-openssl' gem 'activerecord-jdbc-adapter' gem 'activerecord-jdbcsqlite3-adapter' end platforms :ruby, :mswin, :mingw do gem 'sqlite3' end gem 'coveralls', :require => false gem 'rspec', '>= 2.11' gem 'simplecov', :require => false gem 'activerecord', "~> 4.0.0" end gemspec :path => "../../" delayed_job_active_record-4.0.3/gemfiles/sqlite3/4-1.gemfile000066400000000000000000000006401244605077200236710ustar00rootroot00000000000000source 'https://rubygems.org' gem 'rake' group :test do platforms :jruby do gem 'jruby-openssl' gem 'activerecord-jdbc-adapter' gem 'activerecord-jdbcsqlite3-adapter' end platforms :ruby, :mswin, :mingw do gem 'sqlite3' end gem 'coveralls', :require => false gem 'rspec', '>= 2.11' gem 'simplecov', :require => false gem 'activerecord', "~> 4.1.0" end gemspec :path => "../../" delayed_job_active_record-4.0.3/gemfiles/sqlite3/4-2.gemfile000066400000000000000000000006401244605077200236720ustar00rootroot00000000000000source 'https://rubygems.org' gem 'rake' group :test do platforms :jruby do gem 'jruby-openssl' gem 'activerecord-jdbc-adapter' gem 'activerecord-jdbcsqlite3-adapter' end platforms :ruby, :mswin, :mingw do gem 'sqlite3' end gem 'coveralls', :require => false gem 'rspec', '>= 2.11' gem 'simplecov', :require => false gem 'activerecord', "~> 4.2.0" end gemspec :path => "../../" delayed_job_active_record-4.0.3/lib/000077500000000000000000000000001244605077200174255ustar00rootroot00000000000000delayed_job_active_record-4.0.3/lib/delayed/000077500000000000000000000000001244605077200210345ustar00rootroot00000000000000delayed_job_active_record-4.0.3/lib/delayed/backend/000077500000000000000000000000001244605077200224235ustar00rootroot00000000000000delayed_job_active_record-4.0.3/lib/delayed/backend/active_record.rb000066400000000000000000000134401244605077200255630ustar00rootroot00000000000000require "active_record/version" module Delayed module Backend module ActiveRecord # A job object that is persisted to the database. # Contains the work object as a YAML field. class Job < ::ActiveRecord::Base include Delayed::Backend::Base if ::ActiveRecord::VERSION::MAJOR < 4 || defined?(::ActiveRecord::MassAssignmentSecurity) attr_accessible :priority, :run_at, :queue, :payload_object, :failed_at, :locked_at, :locked_by, :handler end scope :by_priority, lambda { order("priority ASC, run_at ASC") } before_save :set_default_run_at def self.set_delayed_job_table_name delayed_job_table_name = "#{::ActiveRecord::Base.table_name_prefix}delayed_jobs" self.table_name = delayed_job_table_name end set_delayed_job_table_name def self.ready_to_run(worker_name, max_run_time) where("(run_at <= ? AND (locked_at IS NULL OR locked_at < ?) OR locked_by = ?) AND failed_at IS NULL", db_time_now, db_time_now - max_run_time, worker_name) end def self.before_fork ::ActiveRecord::Base.clear_all_connections! end def self.after_fork ::ActiveRecord::Base.establish_connection end # When a worker is exiting, make sure we don't have any locked jobs. def self.clear_locks!(worker_name) where(locked_by: worker_name).update_all(locked_by: nil, locked_at: nil) end def self.reserve(worker, max_run_time = Worker.max_run_time) # rubocop:disable CyclomaticComplexity # scope to filter to records that are "ready to run" ready_scope = ready_to_run(worker.name, max_run_time) # scope to filter to the single next eligible job ready_scope = ready_scope.where("priority >= ?", Worker.min_priority) if Worker.min_priority ready_scope = ready_scope.where("priority <= ?", Worker.max_priority) if Worker.max_priority ready_scope = ready_scope.where(queue: Worker.queues) if Worker.queues.any? ready_scope = ready_scope.by_priority reserve_with_scope(ready_scope, worker, db_time_now) end def self.reserve_with_scope(ready_scope, worker, now) # Optimizations for faster lookups on some common databases case connection.adapter_name when "PostgreSQL" # Custom SQL required for PostgreSQL because postgres does not support UPDATE...LIMIT # This locks the single record 'FOR UPDATE' in the subquery # http://www.postgresql.org/docs/9.0/static/sql-select.html#SQL-FOR-UPDATE-SHARE # Note: active_record would attempt to generate UPDATE...LIMIT like # SQL for Postgres if we use a .limit() filter, but it would not # use 'FOR UPDATE' and we would have many locking conflicts quoted_table_name = connection.quote_table_name(table_name) subquery_sql = ready_scope.limit(1).lock(true).select("id").to_sql reserved = find_by_sql(["UPDATE #{quoted_table_name} SET locked_at = ?, locked_by = ? WHERE id IN (#{subquery_sql}) RETURNING *", now, worker.name]) reserved[0] when "MySQL", "Mysql2" # Removing the millisecond precision from now(time object) # MySQL 5.6.4 onwards millisecond precision exists, but the # datetime object created doesn't have precision, so discarded # while updating. But during the where clause, for mysql(>=5.6.4), # it queries with precision as well. So removing the precision now = now.change(usec: 0) # This works on MySQL and possibly some other DBs that support # UPDATE...LIMIT. It uses separate queries to lock and return the job count = ready_scope.limit(1).update_all(locked_at: now, locked_by: worker.name) return nil if count == 0 where(locked_at: now, locked_by: worker.name, failed_at: nil).first when "MSSQL", "Teradata" # The MSSQL driver doesn't generate a limit clause when update_all # is called directly subsubquery_sql = ready_scope.limit(1).to_sql # select("id") doesn't generate a subquery, so force a subquery subquery_sql = "SELECT id FROM (#{subsubquery_sql}) AS x" quoted_table_name = connection.quote_table_name(table_name) sql = ["UPDATE #{quoted_table_name} SET locked_at = ?, locked_by = ? WHERE id IN (#{subquery_sql})", now, worker.name] count = connection.execute(sanitize_sql(sql)) return nil if count == 0 # MSSQL JDBC doesn't support OUTPUT INSERTED.* for returning a result set, so query locked row where(locked_at: now, locked_by: worker.name, failed_at: nil).first else reserve_with_scope_using_default_sql(ready_scope, worker, now) end end def self.reserve_with_scope_using_default_sql(ready_scope, worker, now) # This is our old fashion, tried and true, but slower lookup ready_scope.limit(worker.read_ahead).detect do |job| count = ready_scope.where(id: job.id).update_all(locked_at: now, locked_by: worker.name) count == 1 && job.reload end end # Get the current time (GMT or local depending on DB) # Note: This does not ping the DB to get the time, so all your clients # must have syncronized clocks. def self.db_time_now if Time.zone Time.zone.now elsif ::ActiveRecord::Base.default_timezone == :utc Time.now.utc else Time.now end end def reload(*args) reset super end end end end end delayed_job_active_record-4.0.3/lib/delayed_job_active_record.rb000066400000000000000000000002001244605077200250740ustar00rootroot00000000000000require "active_record" require "delayed_job" require "delayed/backend/active_record" Delayed::Worker.backend = :active_record delayed_job_active_record-4.0.3/lib/generators/000077500000000000000000000000001244605077200215765ustar00rootroot00000000000000delayed_job_active_record-4.0.3/lib/generators/delayed_job/000077500000000000000000000000001244605077200240375ustar00rootroot00000000000000delayed_job_active_record-4.0.3/lib/generators/delayed_job/active_record_generator.rb000066400000000000000000000013151244605077200312430ustar00rootroot00000000000000require "generators/delayed_job/delayed_job_generator" require "generators/delayed_job/next_migration_version" require "rails/generators/migration" require "rails/generators/active_record" # Extend the DelayedJobGenerator so that it creates an AR migration module DelayedJob class ActiveRecordGenerator < ::DelayedJobGenerator include Rails::Generators::Migration extend NextMigrationVersion source_paths << File.join(File.dirname(__FILE__), "templates") def create_migration_file migration_template "migration.rb", "db/migrate/create_delayed_jobs.rb" end def self.next_migration_number(dirname) ActiveRecord::Generators::Base.next_migration_number dirname end end end delayed_job_active_record-4.0.3/lib/generators/delayed_job/next_migration_version.rb000066400000000000000000000007431244605077200311640ustar00rootroot00000000000000module DelayedJob module NextMigrationVersion # while methods have moved around this has been the implementation # since ActiveRecord 3.0 def next_migration_number(dirname) next_migration_number = current_migration_number(dirname) + 1 if ActiveRecord::Base.timestamped_migrations [Time.now.utc.strftime("%Y%m%d%H%M%S"), format("%.14d", next_migration_number)].max else format("%.3d", next_migration_number) end end end end delayed_job_active_record-4.0.3/lib/generators/delayed_job/templates/000077500000000000000000000000001244605077200260355ustar00rootroot00000000000000delayed_job_active_record-4.0.3/lib/generators/delayed_job/templates/migration.rb000066400000000000000000000024251244605077200303560ustar00rootroot00000000000000class CreateDelayedJobs < ActiveRecord::Migration def self.up create_table :delayed_jobs, force: true do |table| table.integer :priority, default: 0, null: false # Allows some jobs to jump to the front of the queue table.integer :attempts, default: 0, null: false # Provides for retries, but still fail eventually. table.text :handler, null: false # YAML-encoded string of the object that will do work table.text :last_error # reason for last failure (See Note below) table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future. table.datetime :locked_at # Set when a client is working on this object table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead) table.string :locked_by # Who is working on this object (if locked) table.string :queue # The name of the queue this job is in table.timestamps null: true end add_index :delayed_jobs, [:priority, :run_at], name: "delayed_jobs_priority" end def self.down drop_table :delayed_jobs end end delayed_job_active_record-4.0.3/lib/generators/delayed_job/templates/upgrade_migration.rb000066400000000000000000000002731244605077200320640ustar00rootroot00000000000000class AddQueueToDelayedJobs < ActiveRecord::Migration def self.up add_column :delayed_jobs, :queue, :string end def self.down remove_column :delayed_jobs, :queue end end delayed_job_active_record-4.0.3/lib/generators/delayed_job/upgrade_generator.rb000066400000000000000000000013261244605077200300630ustar00rootroot00000000000000require "generators/delayed_job/delayed_job_generator" require "generators/delayed_job/next_migration_version" require "rails/generators/migration" require "rails/generators/active_record" # Extend the DelayedJobGenerator so that it creates an AR migration module DelayedJob class UpgradeGenerator < ::DelayedJobGenerator include Rails::Generators::Migration extend NextMigrationVersion source_paths << File.join(File.dirname(__FILE__), "templates") def create_migration_file migration_template "upgrade_migration.rb", "db/migrate/add_queue_to_delayed_jobs.rb" end def self.next_migration_number(dirname) ActiveRecord::Generators::Base.next_migration_number dirname end end end delayed_job_active_record-4.0.3/spec/000077500000000000000000000000001244605077200176115ustar00rootroot00000000000000delayed_job_active_record-4.0.3/spec/database.yml000066400000000000000000000003401244605077200220750ustar00rootroot00000000000000mysql: adapter: mysql database: delayed_job_test username: root encoding: utf8 postgresql: adapter: postgresql database: delayed_job_test username: postgres sqlite3: adapter: sqlite3 database: ":memory:" delayed_job_active_record-4.0.3/spec/delayed/000077500000000000000000000000001244605077200212205ustar00rootroot00000000000000delayed_job_active_record-4.0.3/spec/delayed/backend/000077500000000000000000000000001244605077200226075ustar00rootroot00000000000000delayed_job_active_record-4.0.3/spec/delayed/backend/active_record_spec.rb000066400000000000000000000070341244605077200267630ustar00rootroot00000000000000require "helper" require "delayed/backend/active_record" describe Delayed::Backend::ActiveRecord::Job do it_behaves_like "a delayed_job backend" describe "reserve_with_scope" do let(:worker) { double(name: "worker01", read_ahead: 1) } let(:scope) { double(limit: limit, where: double(update_all: nil)) } let(:limit) { double(job: job) } let(:job) { double(id: 1) } before do allow(Delayed::Backend::ActiveRecord::Job.connection).to receive(:adapter_name).at_least(:once).and_return(dbms) end context "for a dbms without a specific implementation" do let(:dbms) { "OtherDB" } it "uses the plain sql version" do expect(Delayed::Backend::ActiveRecord::Job).to receive(:reserve_with_scope_using_default_sql).once Delayed::Backend::ActiveRecord::Job.reserve_with_scope(scope, worker, Time.now) end end end context "db_time_now" do after do Time.zone = nil ActiveRecord::Base.default_timezone = :local end it "returns time in current time zone if set" do Time.zone = "Eastern Time (US & Canada)" expect(%(EST EDT)).to include(Delayed::Job.db_time_now.zone) end it "returns UTC time if that is the AR default" do Time.zone = nil ActiveRecord::Base.default_timezone = :utc expect(Delayed::Backend::ActiveRecord::Job.db_time_now.zone).to eq "UTC" end it "returns local time if that is the AR default" do Time.zone = "Central Time (US & Canada)" ActiveRecord::Base.default_timezone = :local expect(%w(CST CDT)).to include(Delayed::Backend::ActiveRecord::Job.db_time_now.zone) end end describe "after_fork" do it "calls reconnect on the connection" do expect(ActiveRecord::Base).to receive(:establish_connection) Delayed::Backend::ActiveRecord::Job.after_fork end end describe "enqueue" do it "allows enqueue hook to modify job at DB level" do later = described_class.db_time_now + 20.minutes job = Delayed::Backend::ActiveRecord::Job.enqueue payload_object: EnqueueJobMod.new expect(Delayed::Backend::ActiveRecord::Job.find(job.id).run_at).to be_within(1).of(later) end end if ::ActiveRecord::VERSION::MAJOR < 4 || defined?(::ActiveRecord::MassAssignmentSecurity) context "ActiveRecord::Base.send(:attr_accessible, nil)" do before do Delayed::Backend::ActiveRecord::Job.send(:attr_accessible, nil) end after do Delayed::Backend::ActiveRecord::Job.send(:attr_accessible, *Delayed::Backend::ActiveRecord::Job.new.attributes.keys) end it "is still accessible" do job = Delayed::Backend::ActiveRecord::Job.enqueue payload_object: EnqueueJobMod.new expect(Delayed::Backend::ActiveRecord::Job.find(job.id).handler).to_not be_blank end end end context "ActiveRecord::Base.table_name_prefix" do it "when prefix is not set, use 'delayed_jobs' as table name" do ::ActiveRecord::Base.table_name_prefix = nil Delayed::Backend::ActiveRecord::Job.set_delayed_job_table_name expect(Delayed::Backend::ActiveRecord::Job.table_name).to eq "delayed_jobs" end it "when prefix is set, prepend it before default table name" do ::ActiveRecord::Base.table_name_prefix = "custom_" Delayed::Backend::ActiveRecord::Job.set_delayed_job_table_name expect(Delayed::Backend::ActiveRecord::Job.table_name).to eq "custom_delayed_jobs" ::ActiveRecord::Base.table_name_prefix = nil Delayed::Backend::ActiveRecord::Job.set_delayed_job_table_name end end end delayed_job_active_record-4.0.3/spec/delayed/serialization/000077500000000000000000000000001244605077200240755ustar00rootroot00000000000000delayed_job_active_record-4.0.3/spec/delayed/serialization/active_record_spec.rb000066400000000000000000000005231244605077200302450ustar00rootroot00000000000000require "helper" describe ActiveRecord do it "loads classes with non-default primary key" do expect do YAML.load(Story.create.to_yaml) end.not_to raise_error end it "loads classes even if not in default scope" do expect do YAML.load(Story.create(scoped: false).to_yaml) end.not_to raise_error end end delayed_job_active_record-4.0.3/spec/helper.rb000066400000000000000000000031751244605077200214230ustar00rootroot00000000000000require "simplecov" require "coveralls" SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[ SimpleCov::Formatter::HTMLFormatter, Coveralls::SimpleCov::Formatter ] SimpleCov.start do add_filter "/spec/" minimum_coverage(73.33) end require "logger" require "rspec" begin require "protected_attributes" rescue LoadError # rubocop:disable HandleExceptions end require "delayed_job_active_record" require "delayed/backend/shared_spec" Delayed::Worker.logger = Logger.new("/tmp/dj.log") ENV["RAILS_ENV"] = "test" db_adapter, gemfile = ENV["ADAPTER"], ENV["BUNDLE_GEMFILE"] db_adapter ||= gemfile && gemfile[%r{gemfiles/(.*?)/}] && $1 # rubocop:disable PerlBackrefs db_adapter ||= "sqlite3" config = YAML.load(File.read("spec/database.yml")) ActiveRecord::Base.establish_connection config[db_adapter] ActiveRecord::Base.logger = Delayed::Worker.logger ActiveRecord::Migration.verbose = false require "generators/delayed_job/templates/migration" ActiveRecord::Schema.define do CreateDelayedJobs.up create_table :stories, primary_key: :story_id, force: true do |table| table.string :text table.boolean :scoped, default: true end end # Purely useful for test cases... class Story < ActiveRecord::Base if ::ActiveRecord::VERSION::MAJOR < 4 && ActiveRecord::VERSION::MINOR < 2 set_primary_key :story_id else self.primary_key = :story_id end def tell text end def whatever(n, _) tell * n end default_scope { where(scoped: true) } handle_asynchronously :whatever end # Add this directory so the ActiveSupport autoloading works ActiveSupport::Dependencies.autoload_paths << File.dirname(__FILE__)