delayed_job_active_record 4.0.2 → 4.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 0ba9b64dfebf36a3cc8248ff10fff63af3a8b611
4
- data.tar.gz: 506aba7854d7c39aa711c54e38c7a87e2fd7c00d
2
+ SHA256:
3
+ metadata.gz: 3bdebcffb191581b743a334926d45c01184fbe0a58a906741b0f7f73118375bc
4
+ data.tar.gz: fdc7e1c5c74cd0f5beef00a61d62daaf3bf91d2ca631248a7a2a7382f3d420d9
5
5
  SHA512:
6
- metadata.gz: 7f1b5ad0fa88e075b988d4234654cfdbc0e63e8a32344d8cb1824ef7562f88b1aa7ad63952e3176df823daac164fda2bf34692735062961cb59896d10f0dec72
7
- data.tar.gz: a4621ce576f0d7fb0458ccd3aa396ad79a5f5bd7ef85440c6aead1fcb8b6b11d11bc5610042b7da72f909a6fd5efeae0c1676427a80233d1d66cdc88a0f273e2
6
+ metadata.gz: 443633226e38e35bf47be09f548b9bdc1aea188f7c74244b32d8cbbd6b18cac0fd04bffac8540f075e3cc18cd737937f7049a16cc39a363be4fea6cfc9097471
7
+ data.tar.gz: c479df41fa2326aef35d02771336c17ba5ce956aa1c006769b1a67f4282e716c161d723cfd479178f24bbc21b5fdf6183e656a867d3221cf8753d21c7b800cbd
data/README.md CHANGED
@@ -1,10 +1,15 @@
1
+ **If you're viewing this at https://github.com/collectiveidea/delayed_job_active_record,
2
+ you're reading the documentation for the master branch.
3
+ [View documentation for the latest release
4
+ (4.1.3).](https://github.com/collectiveidea/delayed_job_active_record/tree/v4.1.3)**
5
+
1
6
  # DelayedJob ActiveRecord Backend
2
7
 
3
- [![Gem Version](https://badge.fury.io/rb/delayed_job_active_record.png)](https://rubygems.org/gems/delayed_job_active_record)
4
- [![Build Status](https://travis-ci.org/collectiveidea/delayed_job_active_record.png)](https://travis-ci.org/collectiveidea/delayed_job_active_record)
5
- [![Dependency Status](https://gemnasium.com/collectiveidea/delayed_job_active_record.png)](https://gemnasium.com/collectiveidea/delayed_job_active_record)
6
- [![Code Climate](https://codeclimate.com/github/collectiveidea/delayed_job_active_record.png)](https://codeclimate.com/github/collectiveidea/delayed_job_active_record)
7
- [![Coverage Status](https://coveralls.io/repos/collectiveidea/delayed_job_active_record/badge.png?branch=master)](https://coveralls.io/r/collectiveidea/delayed_job_active_record)
8
+ [![Gem Version](https://img.shields.io/gem/v/delayed_job_active_record.svg)](https://rubygems.org/gems/delayed_job_active_record)
9
+ [![Build Status](https://img.shields.io/travis/collectiveidea/delayed_job_active_record.svg)](https://travis-ci.org/collectiveidea/delayed_job_active_record)
10
+ [![Dependency Status](https://img.shields.io/gemnasium/collectiveidea/delayed_job_active_record.svg)](https://gemnasium.com/collectiveidea/delayed_job_active_record)
11
+ [![Code Climate](https://img.shields.io/codeclimate/github/collectiveidea/delayed_job_active_record.svg)](https://codeclimate.com/github/collectiveidea/delayed_job_active_record)
12
+ [![Coverage Status](https://img.shields.io/coveralls/collectiveidea/delayed_job_active_record.svg)](https://coveralls.io/r/collectiveidea/delayed_job_active_record)
8
13
 
9
14
  ## Installation
10
15
 
@@ -20,6 +25,12 @@ delayed_job table.
20
25
  rails g delayed_job:active_record
21
26
  rake db:migrate
22
27
 
28
+ ## Problems locking jobs
29
+
30
+ You can try using the legacy locking code. It is usually slower but works better for certain people.
31
+
32
+ Delayed::Backend::ActiveRecord.configuration.reserve_sql_strategy = :default_sql
33
+
23
34
  ## Upgrading from 2.x to 3.0.0
24
35
 
25
36
  If you're upgrading from Delayed Job 2.x, run the upgrade generator to create a
@@ -1,19 +1,14 @@
1
- # coding: utf-8
2
-
3
1
  Gem::Specification.new do |spec|
4
- spec.add_dependency 'activerecord', ['>= 3.0', '< 4.2']
5
- spec.add_dependency 'delayed_job', ['>= 3.0', '< 4.1']
6
- spec.authors = ['Brian Ryckbost', 'Matt Griffin', 'Erik Michaels-Ober']
7
- spec.description = 'ActiveRecord backend for Delayed::Job, originally authored by Tobias Lütke'
8
- spec.email = ['bryckbost@gmail.com', 'matt@griffinonline.org', 'sferik@gmail.com']
9
- spec.files = %w[CONTRIBUTING.md LICENSE.md README.md Rakefile delayed_job_active_record.gemspec]
10
- spec.files += Dir.glob('lib/**/*.rb')
11
- spec.files += Dir.glob('spec/**/*')
12
- spec.homepage = 'http://github.com/collectiveidea/delayed_job_active_record'
13
- spec.licenses = ['MIT']
14
- spec.name = 'delayed_job_active_record'
15
- spec.require_paths = ['lib']
16
- spec.summary = 'ActiveRecord backend for DelayedJob'
17
- spec.test_files = Dir.glob('spec/**/*')
18
- spec.version = '4.0.2'
2
+ spec.add_dependency "activerecord", [">= 3.0", "< 5.3"]
3
+ spec.add_dependency "delayed_job", [">= 3.0", "< 5"]
4
+ spec.authors = ["Brian Ryckbost", "Matt Griffin", "Erik Michaels-Ober"]
5
+ spec.description = "ActiveRecord backend for Delayed::Job, originally authored by Tobias Lütke"
6
+ spec.email = ["bryckbost@gmail.com", "matt@griffinonline.org", "sferik@gmail.com"]
7
+ spec.files = %w[CONTRIBUTING.md LICENSE.md README.md delayed_job_active_record.gemspec] + Dir["lib/**/*.rb"]
8
+ spec.homepage = "http://github.com/collectiveidea/delayed_job_active_record"
9
+ spec.licenses = ["MIT"]
10
+ spec.name = "delayed_job_active_record"
11
+ spec.require_paths = ["lib"]
12
+ spec.summary = "ActiveRecord backend for DelayedJob"
13
+ spec.version = "4.1.3"
19
14
  end
@@ -1,7 +1,30 @@
1
- require 'active_record/version'
1
+ require "active_record/version"
2
2
  module Delayed
3
3
  module Backend
4
4
  module ActiveRecord
5
+ class Configuration
6
+ attr_reader :reserve_sql_strategy
7
+
8
+ def initialize
9
+ self.reserve_sql_strategy = :optimized_sql
10
+ end
11
+
12
+ def reserve_sql_strategy=(val)
13
+ if !(val == :optimized_sql || val == :default_sql)
14
+ raise ArgumentError, "allowed values are :optimized_sql or :default_sql"
15
+ end
16
+ @reserve_sql_strategy = val
17
+ end
18
+ end
19
+
20
+ def self.configuration
21
+ @configuration ||= Configuration.new
22
+ end
23
+
24
+ def self.configure
25
+ yield(configuration)
26
+ end
27
+
5
28
  # A job object that is persisted to the database.
6
29
  # Contains the work object as a YAML field.
7
30
  class Job < ::ActiveRecord::Base
@@ -12,7 +35,10 @@ module Delayed
12
35
  :failed_at, :locked_at, :locked_by, :handler
13
36
  end
14
37
 
15
- scope :by_priority, lambda { order('priority ASC, run_at ASC') }
38
+ scope :by_priority, lambda { order("priority ASC, run_at ASC") }
39
+ scope :min_priority, lambda { where("priority >= ?", Worker.min_priority) if Worker.min_priority }
40
+ scope :max_priority, lambda { where("priority <= ?", Worker.max_priority) if Worker.max_priority }
41
+ scope :for_queues, lambda { |queues = Worker.queues| where(queue: queues) if Array(queues).any? }
16
42
 
17
43
  before_save :set_default_run_at
18
44
 
@@ -24,7 +50,12 @@ module Delayed
24
50
  set_delayed_job_table_name
25
51
 
26
52
  def self.ready_to_run(worker_name, max_run_time)
27
- 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)
53
+ where(
54
+ "(run_at <= ? AND (locked_at IS NULL OR locked_at < ?) OR locked_by = ?) AND failed_at IS NULL",
55
+ db_time_now,
56
+ db_time_now - max_run_time,
57
+ worker_name
58
+ )
28
59
  end
29
60
 
30
61
  def self.before_fork
@@ -37,50 +68,41 @@ module Delayed
37
68
 
38
69
  # When a worker is exiting, make sure we don't have any locked jobs.
39
70
  def self.clear_locks!(worker_name)
40
- where(:locked_by => worker_name).update_all(:locked_by => nil, :locked_at => nil)
71
+ where(locked_by: worker_name).update_all(locked_by: nil, locked_at: nil)
41
72
  end
42
73
 
43
- def self.reserve(worker, max_run_time = Worker.max_run_time) # rubocop:disable CyclomaticComplexity
44
- # scope to filter to records that are "ready to run"
45
- ready_scope = ready_to_run(worker.name, max_run_time)
46
-
47
- # scope to filter to the single next eligible job
48
- ready_scope = ready_scope.where('priority >= ?', Worker.min_priority) if Worker.min_priority
49
- ready_scope = ready_scope.where('priority <= ?', Worker.max_priority) if Worker.max_priority
50
- ready_scope = ready_scope.where(:queue => Worker.queues) if Worker.queues.any?
51
- ready_scope = ready_scope.by_priority
74
+ def self.reserve(worker, max_run_time = Worker.max_run_time)
75
+ ready_scope =
76
+ ready_to_run(worker.name, max_run_time)
77
+ .min_priority
78
+ .max_priority
79
+ .for_queues
80
+ .by_priority
52
81
 
53
82
  reserve_with_scope(ready_scope, worker, db_time_now)
54
83
  end
55
84
 
56
85
  def self.reserve_with_scope(ready_scope, worker, now)
86
+ case Delayed::Backend::ActiveRecord.configuration.reserve_sql_strategy
57
87
  # Optimizations for faster lookups on some common databases
88
+ when :optimized_sql
89
+ reserve_with_scope_using_optimized_sql(ready_scope, worker, now)
90
+ # Slower but in some cases more unproblematic strategy to lookup records
91
+ # See https://github.com/collectiveidea/delayed_job_active_record/pull/89 for more details.
92
+ when :default_sql
93
+ reserve_with_scope_using_default_sql(ready_scope, worker, now)
94
+ end
95
+ end
96
+
97
+ def self.reserve_with_scope_using_optimized_sql(ready_scope, worker, now)
58
98
  case connection.adapter_name
59
- when 'PostgreSQL'
60
- # Custom SQL required for PostgreSQL because postgres does not support UPDATE...LIMIT
61
- # 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)
62
- # Note: active_record would attempt to generate UPDATE...LIMIT like sql for postgres if we use a .limit() filter, but it would not use
63
- # 'FOR UPDATE' and we would have many locking conflicts
64
- quoted_table_name = connection.quote_table_name(table_name)
65
- subquery_sql = ready_scope.limit(1).lock(true).select('id').to_sql
66
- reserved = find_by_sql(["UPDATE #{quoted_table_name} SET locked_at = ?, locked_by = ? WHERE id IN (#{subquery_sql}) RETURNING *", now, worker.name])
67
- reserved[0]
68
- when 'MySQL', 'Mysql2'
69
- # This works on MySQL and possibly some other DBs that support UPDATE...LIMIT. It uses separate queries to lock and return the job
70
- count = ready_scope.limit(1).update_all(:locked_at => now, :locked_by => worker.name)
71
- return nil if count == 0
72
- where(:locked_at => now, :locked_by => worker.name, :failed_at => nil).first
73
- when 'MSSQL', 'Teradata'
74
- # The MSSQL driver doesn't generate a limit clause when update_all is called directly
75
- subsubquery_sql = ready_scope.limit(1).to_sql
76
- # select("id") doesn't generate a subquery, so force a subquery
77
- subquery_sql = "SELECT id FROM (#{subsubquery_sql}) AS x"
78
- quoted_table_name = connection.quote_table_name(table_name)
79
- sql = ["UPDATE #{quoted_table_name} SET locked_at = ?, locked_by = ? WHERE id IN (#{subquery_sql})", now, worker.name]
80
- count = connection.execute(sanitize_sql(sql))
81
- return nil if count == 0
82
- # MSSQL JDBC doesn't support OUTPUT INSERTED.* for returning a result set, so query locked row
83
- where(:locked_at => now, :locked_by => worker.name, :failed_at => nil).first
99
+ when "PostgreSQL", "PostGIS"
100
+ reserve_with_scope_using_optimized_postgres(ready_scope, worker, now)
101
+ when "MySQL", "Mysql2"
102
+ reserve_with_scope_using_optimized_mysql(ready_scope, worker, now)
103
+ when "MSSQL", "Teradata"
104
+ reserve_with_scope_using_optimized_mssql(ready_scope, worker, now)
105
+ # Fallback for unknown / other DBMS
84
106
  else
85
107
  reserve_with_scope_using_default_sql(ready_scope, worker, now)
86
108
  end
@@ -89,11 +111,53 @@ module Delayed
89
111
  def self.reserve_with_scope_using_default_sql(ready_scope, worker, now)
90
112
  # This is our old fashion, tried and true, but slower lookup
91
113
  ready_scope.limit(worker.read_ahead).detect do |job|
92
- count = ready_scope.where(:id => job.id).update_all(:locked_at => now, :locked_by => worker.name)
114
+ count = ready_scope.where(id: job.id).update_all(locked_at: now, locked_by: worker.name)
93
115
  count == 1 && job.reload
94
116
  end
95
117
  end
96
118
 
119
+ def self.reserve_with_scope_using_optimized_postgres(ready_scope, worker, now)
120
+ # Custom SQL required for PostgreSQL because postgres does not support UPDATE...LIMIT
121
+ # This locks the single record 'FOR UPDATE' in the subquery
122
+ # http://www.postgresql.org/docs/9.0/static/sql-select.html#SQL-FOR-UPDATE-SHARE
123
+ # Note: active_record would attempt to generate UPDATE...LIMIT like
124
+ # SQL for Postgres if we use a .limit() filter, but it would not
125
+ # use 'FOR UPDATE' and we would have many locking conflicts
126
+ quoted_name = connection.quote_table_name(table_name)
127
+ subquery = ready_scope.limit(1).lock(true).select("id").to_sql
128
+ sql = "UPDATE #{quoted_name} SET locked_at = ?, locked_by = ? WHERE id IN (#{subquery}) RETURNING *"
129
+ reserved = find_by_sql([sql, now, worker.name])
130
+ reserved[0]
131
+ end
132
+
133
+ def self.reserve_with_scope_using_optimized_mysql(ready_scope, worker, now)
134
+ # Removing the millisecond precision from now(time object)
135
+ # MySQL 5.6.4 onwards millisecond precision exists, but the
136
+ # datetime object created doesn't have precision, so discarded
137
+ # while updating. But during the where clause, for mysql(>=5.6.4),
138
+ # it queries with precision as well. So removing the precision
139
+ now = now.change(usec: 0)
140
+ # This works on MySQL and possibly some other DBs that support
141
+ # UPDATE...LIMIT. It uses separate queries to lock and return the job
142
+ count = ready_scope.limit(1).update_all(locked_at: now, locked_by: worker.name)
143
+ return nil if count == 0
144
+ where(locked_at: now, locked_by: worker.name, failed_at: nil).first
145
+ end
146
+
147
+ def self.reserve_with_scope_using_optimized_mssql(ready_scope, worker, now)
148
+ # The MSSQL driver doesn't generate a limit clause when update_all
149
+ # is called directly
150
+ subsubquery_sql = ready_scope.limit(1).to_sql
151
+ # select("id") doesn't generate a subquery, so force a subquery
152
+ subquery_sql = "SELECT id FROM (#{subsubquery_sql}) AS x"
153
+ quoted_table_name = connection.quote_table_name(table_name)
154
+ sql = "UPDATE #{quoted_table_name} SET locked_at = ?, locked_by = ? WHERE id IN (#{subquery_sql})"
155
+ count = connection.execute(sanitize_sql([sql, now, worker.name]))
156
+ return nil if count == 0
157
+ # MSSQL JDBC doesn't support OUTPUT INSERTED.* for returning a result set, so query locked row
158
+ where(locked_at: now, locked_by: worker.name, failed_at: nil).first
159
+ end
160
+
97
161
  # Get the current time (GMT or local depending on DB)
98
162
  # Note: This does not ping the DB to get the time, so all your clients
99
163
  # must have syncronized clocks.
@@ -103,7 +167,7 @@ module Delayed
103
167
  elsif ::ActiveRecord::Base.default_timezone == :utc
104
168
  Time.now.utc
105
169
  else
106
- Time.now
170
+ Time.now # rubocop:disable Rails/TimeZone
107
171
  end
108
172
  end
109
173
 
@@ -1,5 +1,5 @@
1
- require 'active_record'
2
- require 'delayed_job'
3
- require 'delayed/backend/active_record'
1
+ require "active_record"
2
+ require "delayed_job"
3
+ require "delayed/backend/active_record"
4
4
 
5
5
  Delayed::Worker.backend = :active_record
@@ -1,7 +1,7 @@
1
- require 'generators/delayed_job/delayed_job_generator'
2
- require 'generators/delayed_job/next_migration_version'
3
- require 'rails/generators/migration'
4
- require 'rails/generators/active_record'
1
+ require "generators/delayed_job/delayed_job_generator"
2
+ require "generators/delayed_job/next_migration_version"
3
+ require "rails/generators/migration"
4
+ require "rails/generators/active_record"
5
5
 
6
6
  # Extend the DelayedJobGenerator so that it creates an AR migration
7
7
  module DelayedJob
@@ -9,14 +9,20 @@ module DelayedJob
9
9
  include Rails::Generators::Migration
10
10
  extend NextMigrationVersion
11
11
 
12
- source_paths << File.join(File.dirname(__FILE__), 'templates')
12
+ source_paths << File.join(File.dirname(__FILE__), "templates")
13
13
 
14
14
  def create_migration_file
15
- migration_template 'migration.rb', 'db/migrate/create_delayed_jobs.rb'
15
+ migration_template "migration.rb", "db/migrate/create_delayed_jobs.rb", migration_version: migration_version
16
16
  end
17
17
 
18
18
  def self.next_migration_number(dirname)
19
19
  ActiveRecord::Generators::Base.next_migration_number dirname
20
20
  end
21
+
22
+ private
23
+
24
+ def migration_version
25
+ "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]" if ActiveRecord::VERSION::MAJOR >= 5
26
+ end
21
27
  end
22
28
  end
@@ -5,9 +5,9 @@ module DelayedJob
5
5
  def next_migration_number(dirname)
6
6
  next_migration_number = current_migration_number(dirname) + 1
7
7
  if ActiveRecord::Base.timestamped_migrations
8
- [Time.now.utc.strftime('%Y%m%d%H%M%S'), format('%.14d', next_migration_number)].max
8
+ [Time.now.utc.strftime("%Y%m%d%H%M%S"), format("%.14d", next_migration_number)].max
9
9
  else
10
- format('%.3d', next_migration_number)
10
+ format("%.3d", next_migration_number)
11
11
  end
12
12
  end
13
13
  end
@@ -1,19 +1,19 @@
1
- class CreateDelayedJobs < ActiveRecord::Migration
1
+ class CreateDelayedJobs < ActiveRecord::Migration<%= migration_version %>
2
2
  def self.up
3
- create_table :delayed_jobs, :force => true do |table|
4
- table.integer :priority, :default => 0, :null => false # Allows some jobs to jump to the front of the queue
5
- table.integer :attempts, :default => 0, :null => false # Provides for retries, but still fail eventually.
6
- table.text :handler, :null => false # YAML-encoded string of the object that will do work
7
- table.text :last_error # reason for last failure (See Note below)
8
- table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future.
9
- table.datetime :locked_at # Set when a client is working on this object
10
- table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead)
11
- table.string :locked_by # Who is working on this object (if locked)
12
- table.string :queue # The name of the queue this job is in
13
- table.timestamps
3
+ create_table :delayed_jobs, force: true do |table|
4
+ table.integer :priority, default: 0, null: false # Allows some jobs to jump to the front of the queue
5
+ table.integer :attempts, default: 0, null: false # Provides for retries, but still fail eventually.
6
+ table.text :handler, null: false # YAML-encoded string of the object that will do work
7
+ table.text :last_error # reason for last failure (See Note below)
8
+ table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future.
9
+ table.datetime :locked_at # Set when a client is working on this object
10
+ table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead)
11
+ table.string :locked_by # Who is working on this object (if locked)
12
+ table.string :queue # The name of the queue this job is in
13
+ table.timestamps null: true
14
14
  end
15
15
 
16
- add_index :delayed_jobs, [:priority, :run_at], :name => 'delayed_jobs_priority'
16
+ add_index :delayed_jobs, [:priority, :run_at], name: "delayed_jobs_priority"
17
17
  end
18
18
 
19
19
  def self.down
@@ -1,4 +1,4 @@
1
- class AddQueueToDelayedJobs < ActiveRecord::Migration
1
+ class AddQueueToDelayedJobs < ActiveRecord::Migration<%= migration_version %>
2
2
  def self.up
3
3
  add_column :delayed_jobs, :queue, :string
4
4
  end
@@ -1,22 +1,17 @@
1
- require 'generators/delayed_job/delayed_job_generator'
2
- require 'generators/delayed_job/next_migration_version'
3
- require 'rails/generators/migration'
4
- require 'rails/generators/active_record'
1
+ require "generators/delayed_job/delayed_job_generator"
2
+ require "generators/delayed_job/next_migration_version"
3
+ require "rails/generators/migration"
4
+ require "rails/generators/active_record"
5
5
 
6
6
  # Extend the DelayedJobGenerator so that it creates an AR migration
7
7
  module DelayedJob
8
- class UpgradeGenerator < ::DelayedJobGenerator
9
- include Rails::Generators::Migration
10
- extend NextMigrationVersion
11
-
12
- source_paths << File.join(File.dirname(__FILE__), 'templates')
13
-
8
+ class UpgradeGenerator < ActiveRecordGenerator
14
9
  def create_migration_file
15
- migration_template 'upgrade_migration.rb', 'db/migrate/add_queue_to_delayed_jobs.rb'
16
- end
17
-
18
- def self.next_migration_number(dirname)
19
- ActiveRecord::Generators::Base.next_migration_number dirname
10
+ migration_template(
11
+ "upgrade_migration.rb",
12
+ "db/migrate/add_queue_to_delayed_jobs.rb",
13
+ migration_version: migration_version
14
+ )
20
15
  end
21
16
  end
22
17
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: delayed_job_active_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.2
4
+ version: 4.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Ryckbost
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2014-08-19 00:00:00.000000000 Z
13
+ date: 2018-04-13 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '3.0'
22
22
  - - "<"
23
23
  - !ruby/object:Gem::Version
24
- version: '4.2'
24
+ version: '5.3'
25
25
  type: :runtime
26
26
  prerelease: false
27
27
  version_requirements: !ruby/object:Gem::Requirement
@@ -31,7 +31,7 @@ dependencies:
31
31
  version: '3.0'
32
32
  - - "<"
33
33
  - !ruby/object:Gem::Version
34
- version: '4.2'
34
+ version: '5.3'
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: delayed_job
37
37
  requirement: !ruby/object:Gem::Requirement
@@ -41,7 +41,7 @@ dependencies:
41
41
  version: '3.0'
42
42
  - - "<"
43
43
  - !ruby/object:Gem::Version
44
- version: '4.1'
44
+ version: '5'
45
45
  type: :runtime
46
46
  prerelease: false
47
47
  version_requirements: !ruby/object:Gem::Requirement
@@ -51,7 +51,7 @@ dependencies:
51
51
  version: '3.0'
52
52
  - - "<"
53
53
  - !ruby/object:Gem::Version
54
- version: '4.1'
54
+ version: '5'
55
55
  description: ActiveRecord backend for Delayed::Job, originally authored by Tobias
56
56
  Lütke
57
57
  email:
@@ -65,7 +65,6 @@ files:
65
65
  - CONTRIBUTING.md
66
66
  - LICENSE.md
67
67
  - README.md
68
- - Rakefile
69
68
  - delayed_job_active_record.gemspec
70
69
  - lib/delayed/backend/active_record.rb
71
70
  - lib/delayed_job_active_record.rb
@@ -74,10 +73,6 @@ files:
74
73
  - lib/generators/delayed_job/templates/migration.rb
75
74
  - lib/generators/delayed_job/templates/upgrade_migration.rb
76
75
  - lib/generators/delayed_job/upgrade_generator.rb
77
- - spec/database.yml
78
- - spec/delayed/backend/active_record_spec.rb
79
- - spec/delayed/serialization/active_record_spec.rb
80
- - spec/helper.rb
81
76
  homepage: http://github.com/collectiveidea/delayed_job_active_record
82
77
  licenses:
83
78
  - MIT
@@ -98,12 +93,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
98
93
  version: '0'
99
94
  requirements: []
100
95
  rubyforge_project:
101
- rubygems_version: 2.4.1
96
+ rubygems_version: 2.7.6
102
97
  signing_key:
103
98
  specification_version: 4
104
99
  summary: ActiveRecord backend for DelayedJob
105
- test_files:
106
- - spec/database.yml
107
- - spec/delayed/backend/active_record_spec.rb
108
- - spec/delayed/serialization/active_record_spec.rb
109
- - spec/helper.rb
100
+ test_files: []
data/Rakefile DELETED
@@ -1,38 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- require 'bundler/gem_helper'
3
- Bundler::GemHelper.install_tasks
4
-
5
- require 'rspec/core/rake_task'
6
-
7
- ADAPTERS = %w[mysql postgresql sqlite3]
8
-
9
- ADAPTERS.each do |adapter|
10
- desc "Run RSpec code examples for #{adapter} adapter"
11
- RSpec::Core::RakeTask.new(adapter => "#{adapter}:adapter")
12
-
13
- namespace adapter do
14
- task :adapter do
15
- ENV['ADAPTER'] = adapter
16
- end
17
- end
18
- end
19
-
20
- task :coverage do
21
- ENV['COVERAGE'] = 'true'
22
- end
23
-
24
- task :adapter do
25
- ENV['ADAPTER'] = nil
26
- end
27
-
28
- Rake::Task[:spec].enhance do
29
- require 'simplecov'
30
- require 'coveralls'
31
-
32
- Coveralls::SimpleCov::Formatter.new.format(SimpleCov.result)
33
- end
34
-
35
- require 'rubocop/rake_task'
36
- RuboCop::RakeTask.new
37
-
38
- task :default => ([:coverage] + ADAPTERS + [:adapter] + [:rubocop])
data/spec/database.yml DELETED
@@ -1,14 +0,0 @@
1
- mysql:
2
- adapter: mysql
3
- database: delayed_job_test
4
- username: root
5
- encoding: utf8
6
-
7
- postgresql:
8
- adapter: postgresql
9
- database: delayed_job_test
10
- username: postgres
11
-
12
- sqlite3:
13
- adapter: sqlite3
14
- database: ":memory:"
@@ -1,101 +0,0 @@
1
- require 'helper'
2
- require 'delayed/backend/active_record'
3
-
4
- describe Delayed::Backend::ActiveRecord::Job do
5
- it_behaves_like 'a delayed_job backend'
6
-
7
- describe "reserve_with_scope" do
8
- let(:worker) { double(name: "worker01", read_ahead: 1) }
9
- let(:scope) { double(limit: limit, where: double(update_all: nil)) }
10
- let(:limit) { double(job: job) }
11
- let(:job) { double(id: 1) }
12
-
13
- before do
14
- allow(Delayed::Backend::ActiveRecord::Job.connection).to receive(:adapter_name).at_least(:once).and_return(dbms)
15
- end
16
-
17
- context "for a dbms without a specific implementation" do
18
- let(:dbms) { "OtherDB" }
19
-
20
- it "uses the plain sql version" do
21
- expect(Delayed::Backend::ActiveRecord::Job).to receive(:reserve_with_scope_using_default_sql).once
22
- Delayed::Backend::ActiveRecord::Job.reserve_with_scope(scope, worker, Time.now)
23
- end
24
- end
25
- end
26
-
27
- context 'db_time_now' do
28
- after do
29
- Time.zone = nil
30
- ActiveRecord::Base.default_timezone = :local
31
- end
32
-
33
- it 'returns time in current time zone if set' do
34
- Time.zone = 'Eastern Time (US & Canada)'
35
- expect(%(EST EDT)).to include(Delayed::Job.db_time_now.zone)
36
- end
37
-
38
- it 'returns UTC time if that is the AR default' do
39
- Time.zone = nil
40
- ActiveRecord::Base.default_timezone = :utc
41
- expect(Delayed::Backend::ActiveRecord::Job.db_time_now.zone).to eq 'UTC'
42
- end
43
-
44
- it 'returns local time if that is the AR default' do
45
- Time.zone = 'Central Time (US & Canada)'
46
- ActiveRecord::Base.default_timezone = :local
47
- expect(%w[CST CDT]).to include(Delayed::Backend::ActiveRecord::Job.db_time_now.zone)
48
- end
49
- end
50
-
51
- describe 'after_fork' do
52
- it 'calls reconnect on the connection' do
53
- allow(ActiveRecord::Base).to receive(:establish_connection)
54
- Delayed::Backend::ActiveRecord::Job.after_fork
55
- end
56
- end
57
-
58
- describe 'enqueue' do
59
- it 'allows enqueue hook to modify job at DB level' do
60
- later = described_class.db_time_now + 20.minutes
61
- job = Delayed::Backend::ActiveRecord::Job.enqueue :payload_object => EnqueueJobMod.new
62
- expect(Delayed::Backend::ActiveRecord::Job.find(job.id).run_at).to be_within(1).of(later)
63
- end
64
- end
65
-
66
- if ::ActiveRecord::VERSION::MAJOR < 4 || defined?(::ActiveRecord::MassAssignmentSecurity)
67
- context 'ActiveRecord::Base.send(:attr_accessible, nil)' do
68
- before do
69
- Delayed::Backend::ActiveRecord::Job.send(:attr_accessible, nil)
70
- end
71
-
72
- after do
73
- Delayed::Backend::ActiveRecord::Job.send(:attr_accessible, *Delayed::Backend::ActiveRecord::Job.new.attributes.keys)
74
- end
75
-
76
- it 'is still accessible' do
77
- job = Delayed::Backend::ActiveRecord::Job.enqueue :payload_object => EnqueueJobMod.new
78
- expect(Delayed::Backend::ActiveRecord::Job.find(job.id).handler).to_not be_blank
79
- end
80
- end
81
- end
82
-
83
- context 'ActiveRecord::Base.table_name_prefix' do
84
- it "when prefix is not set, use 'delayed_jobs' as table name" do
85
- ::ActiveRecord::Base.table_name_prefix = nil
86
- Delayed::Backend::ActiveRecord::Job.set_delayed_job_table_name
87
-
88
- expect(Delayed::Backend::ActiveRecord::Job.table_name).to eq 'delayed_jobs'
89
- end
90
-
91
- it 'when prefix is set, prepend it before default table name' do
92
- ::ActiveRecord::Base.table_name_prefix = 'custom_'
93
- Delayed::Backend::ActiveRecord::Job.set_delayed_job_table_name
94
-
95
- expect(Delayed::Backend::ActiveRecord::Job.table_name).to eq 'custom_delayed_jobs'
96
-
97
- ::ActiveRecord::Base.table_name_prefix = nil
98
- Delayed::Backend::ActiveRecord::Job.set_delayed_job_table_name
99
- end
100
- end
101
- end
@@ -1,15 +0,0 @@
1
- require 'helper'
2
-
3
- describe ActiveRecord do
4
- it 'loads classes with non-default primary key' do
5
- expect do
6
- YAML.load(Story.create.to_yaml)
7
- end.not_to raise_error
8
- end
9
-
10
- it 'loads classes even if not in default scope' do
11
- expect do
12
- YAML.load(Story.create(:scoped => false).to_yaml)
13
- end.not_to raise_error
14
- end
15
- end
data/spec/helper.rb DELETED
@@ -1,78 +0,0 @@
1
- require 'simplecov'
2
- require 'coveralls'
3
-
4
- SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
5
- SimpleCov::Formatter::HTMLFormatter,
6
- Coveralls::SimpleCov::Formatter
7
- ]
8
-
9
- SimpleCov.start do
10
- add_filter '/spec/'
11
- minimum_coverage(73.33)
12
- end
13
-
14
- require 'logger'
15
- require 'rspec'
16
-
17
- begin
18
- require 'protected_attributes'
19
- rescue LoadError # rubocop:disable HandleExceptions
20
- end
21
- require 'delayed_job_active_record'
22
- require 'delayed/backend/shared_spec'
23
-
24
- Delayed::Worker.logger = Logger.new('/tmp/dj.log')
25
- ENV['RAILS_ENV'] = 'test'
26
-
27
- db_adapter, gemfile = ENV['ADAPTER'], ENV['BUNDLE_GEMFILE']
28
- db_adapter ||= gemfile && gemfile[%r{gemfiles/(.*?)/}] && $1 # rubocop:disable PerlBackrefs
29
- db_adapter ||= 'sqlite3'
30
-
31
- config = YAML.load(File.read('spec/database.yml'))
32
- ActiveRecord::Base.establish_connection config[db_adapter]
33
- ActiveRecord::Base.logger = Delayed::Worker.logger
34
- ActiveRecord::Migration.verbose = false
35
-
36
- ActiveRecord::Schema.define do
37
- create_table :delayed_jobs, :force => true do |table|
38
- table.integer :priority, :default => 0
39
- table.integer :attempts, :default => 0
40
- table.text :handler
41
- table.text :last_error
42
- table.datetime :run_at
43
- table.datetime :locked_at
44
- table.datetime :failed_at
45
- table.string :locked_by
46
- table.string :queue
47
- table.timestamps
48
- end
49
-
50
- add_index :delayed_jobs, [:priority, :run_at], :name => 'delayed_jobs_priority'
51
-
52
- create_table :stories, :primary_key => :story_id, :force => true do |table|
53
- table.string :text
54
- table.boolean :scoped, :default => true
55
- end
56
- end
57
-
58
- # Purely useful for test cases...
59
- class Story < ActiveRecord::Base
60
- if ::ActiveRecord::VERSION::MAJOR < 4 && ActiveRecord::VERSION::MINOR < 2
61
- set_primary_key :story_id
62
- else
63
- self.primary_key = :story_id
64
- end
65
- def tell
66
- text
67
- end
68
-
69
- def whatever(n, _)
70
- tell * n
71
- end
72
- default_scope { where(:scoped => true) }
73
-
74
- handle_asynchronously :whatever
75
- end
76
-
77
- # Add this directory so the ActiveSupport autoloading works
78
- ActiveSupport::Dependencies.autoload_paths << File.dirname(__FILE__)