delayed_job_active_record 4.0.2 → 4.1.8

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: 6f3787467e904817090ad112e500a855194661f9295623517cc73c0bbb930c57
4
+ data.tar.gz: 200346cb19ab7030a82e86c41499220a6aab7e76bec940b14a17b39a96f13490
5
5
  SHA512:
6
- metadata.gz: 7f1b5ad0fa88e075b988d4234654cfdbc0e63e8a32344d8cb1824ef7562f88b1aa7ad63952e3176df823daac164fda2bf34692735062961cb59896d10f0dec72
7
- data.tar.gz: a4621ce576f0d7fb0458ccd3aa396ad79a5f5bd7ef85440c6aead1fcb8b6b11d11bc5610042b7da72f909a6fd5efeae0c1676427a80233d1d66cdc88a0f273e2
6
+ metadata.gz: 96b163e6ddbd7dd28c1b8bfd33fcbc7c39ee3b7c66af76774e45f7cf60f88946b26c8afa994af786ce7b4960f33c41209bcc75a99c4c0fd8b023ad83bd737c52
7
+ data.tar.gz: f149d6efdc7b06935639ea8f57d39f32710f1961f285b9a1baf0afd95c8bd30553d2a2c7e59e9ced337d323008a173832c6724af12d4788976808bb9bfae6f60
data/README.md CHANGED
@@ -1,10 +1,13 @@
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.7).](https://github.com/collectiveidea/delayed_job_active_record/tree/v4.1.8)**
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
+ ![CI](https://github.com/collectiveidea/delayed_job_active_record/workflows/CI/badge.svg)
10
+ [![Coverage Status](https://img.shields.io/coveralls/collectiveidea/delayed_job_active_record.svg)](https://coveralls.io/r/collectiveidea/delayed_job_active_record)
8
11
 
9
12
  ## Installation
10
13
 
@@ -20,6 +23,12 @@ delayed_job table.
20
23
  rails g delayed_job:active_record
21
24
  rake db:migrate
22
25
 
26
+ ## Problems locking jobs
27
+
28
+ You can try using the legacy locking code. It is usually slower but works better for certain people.
29
+
30
+ Delayed::Backend::ActiveRecord.configuration.reserve_sql_strategy = :default_sql
31
+
23
32
  ## Upgrading from 2.x to 3.0.0
24
33
 
25
34
  If you're upgrading from Delayed Job 2.x, run the upgrade generator to create a
@@ -1,19 +1,17 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  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'
4
+ spec.add_dependency "activerecord", [">= 3.0", "< 8.0"]
5
+ spec.add_dependency "delayed_job", [">= 3.0", "< 5"]
6
+ spec.authors = ["David Genord II", "Brian Ryckbost", "Matt Griffin", "Erik Michaels-Ober"]
7
+ spec.description = "ActiveRecord backend for Delayed::Job, originally authored by Tobias Lütke"
8
+ spec.email = ["david@collectiveidea.com", "bryckbost@gmail.com", "matt@griffinonline.org", "sferik@gmail.com"]
9
+ spec.files = %w[CONTRIBUTING.md LICENSE.md README.md delayed_job_active_record.gemspec] + Dir["lib/**/*.rb"]
10
+ spec.homepage = "http://github.com/collectiveidea/delayed_job_active_record"
11
+ spec.licenses = ["MIT"]
12
+ spec.metadata = { "rubygems_mfa_required" => "true" }
13
+ spec.name = "delayed_job_active_record"
14
+ spec.require_paths = ["lib"]
15
+ spec.summary = "ActiveRecord backend for DelayedJob"
16
+ spec.version = "4.1.8"
19
17
  end
@@ -1,7 +1,33 @@
1
- require 'active_record/version'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record/version"
2
4
  module Delayed
3
5
  module Backend
4
6
  module ActiveRecord
7
+ class Configuration
8
+ attr_reader :reserve_sql_strategy
9
+
10
+ def initialize
11
+ self.reserve_sql_strategy = :optimized_sql
12
+ end
13
+
14
+ def reserve_sql_strategy=(val)
15
+ if !(val == :optimized_sql || val == :default_sql)
16
+ raise ArgumentError, "allowed values are :optimized_sql or :default_sql"
17
+ end
18
+
19
+ @reserve_sql_strategy = val
20
+ end
21
+ end
22
+
23
+ def self.configuration
24
+ @configuration ||= Configuration.new
25
+ end
26
+
27
+ def self.configure
28
+ yield(configuration)
29
+ end
30
+
5
31
  # A job object that is persisted to the database.
6
32
  # Contains the work object as a YAML field.
7
33
  class Job < ::ActiveRecord::Base
@@ -12,7 +38,10 @@ module Delayed
12
38
  :failed_at, :locked_at, :locked_by, :handler
13
39
  end
14
40
 
15
- scope :by_priority, lambda { order('priority ASC, run_at ASC') }
41
+ scope :by_priority, lambda { order("priority ASC, run_at ASC") }
42
+ scope :min_priority, lambda { where("priority >= ?", Worker.min_priority) if Worker.min_priority }
43
+ scope :max_priority, lambda { where("priority <= ?", Worker.max_priority) if Worker.max_priority }
44
+ scope :for_queues, lambda { |queues = Worker.queues| where(queue: queues) if Array(queues).any? }
16
45
 
17
46
  before_save :set_default_run_at
18
47
 
@@ -24,11 +53,16 @@ module Delayed
24
53
  set_delayed_job_table_name
25
54
 
26
55
  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)
56
+ where(
57
+ "((run_at <= ? AND (locked_at IS NULL OR locked_at < ?)) OR locked_by = ?) AND failed_at IS NULL",
58
+ db_time_now,
59
+ db_time_now - max_run_time,
60
+ worker_name
61
+ )
28
62
  end
29
63
 
30
64
  def self.before_fork
31
- ::ActiveRecord::Base.clear_all_connections!
65
+ ::ActiveRecord::Base.connection_handler.clear_all_connections!
32
66
  end
33
67
 
34
68
  def self.after_fork
@@ -37,73 +71,119 @@ module Delayed
37
71
 
38
72
  # When a worker is exiting, make sure we don't have any locked jobs.
39
73
  def self.clear_locks!(worker_name)
40
- where(:locked_by => worker_name).update_all(:locked_by => nil, :locked_at => nil)
74
+ where(locked_by: worker_name).update_all(locked_by: nil, locked_at: nil)
41
75
  end
42
76
 
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
77
+ def self.reserve(worker, max_run_time = Worker.max_run_time)
78
+ ready_scope =
79
+ ready_to_run(worker.name, max_run_time)
80
+ .min_priority
81
+ .max_priority
82
+ .for_queues
83
+ .by_priority
52
84
 
53
85
  reserve_with_scope(ready_scope, worker, db_time_now)
54
86
  end
55
87
 
56
88
  def self.reserve_with_scope(ready_scope, worker, now)
89
+ case Delayed::Backend::ActiveRecord.configuration.reserve_sql_strategy
57
90
  # Optimizations for faster lookups on some common databases
91
+ when :optimized_sql
92
+ reserve_with_scope_using_optimized_sql(ready_scope, worker, now)
93
+ # Slower but in some cases more unproblematic strategy to lookup records
94
+ # See https://github.com/collectiveidea/delayed_job_active_record/pull/89 for more details.
95
+ when :default_sql
96
+ reserve_with_scope_using_default_sql(ready_scope, worker, now)
97
+ end
98
+ end
99
+
100
+ def self.reserve_with_scope_using_optimized_sql(ready_scope, worker, now)
58
101
  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
102
+ when "PostgreSQL", "PostGIS"
103
+ reserve_with_scope_using_optimized_postgres(ready_scope, worker, now)
104
+ when "MySQL", "Mysql2"
105
+ reserve_with_scope_using_optimized_mysql(ready_scope, worker, now)
106
+ when "MSSQL", "Teradata"
107
+ reserve_with_scope_using_optimized_mssql(ready_scope, worker, now)
108
+ # Fallback for unknown / other DBMS
84
109
  else
85
110
  reserve_with_scope_using_default_sql(ready_scope, worker, now)
86
111
  end
87
112
  end
88
113
 
89
114
  def self.reserve_with_scope_using_default_sql(ready_scope, worker, now)
90
- # This is our old fashion, tried and true, but slower lookup
91
- 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)
115
+ # This is our old fashion, tried and true, but possibly slower lookup
116
+ # Instead of reading the entire job record for our detect loop, we select only the id,
117
+ # and only read the full job record after we've successfully locked the job.
118
+ # This can have a noticable impact on large read_ahead configurations and large payload jobs.
119
+ ready_scope.limit(worker.read_ahead).select(:id).detect do |job|
120
+ count = ready_scope.where(id: job.id).update_all(locked_at: now, locked_by: worker.name)
93
121
  count == 1 && job.reload
94
122
  end
95
123
  end
96
124
 
125
+ def self.reserve_with_scope_using_optimized_postgres(ready_scope, worker, now)
126
+ # Custom SQL required for PostgreSQL because postgres does not support UPDATE...LIMIT
127
+ # This locks the single record 'FOR UPDATE' in the subquery
128
+ # http://www.postgresql.org/docs/9.0/static/sql-select.html#SQL-FOR-UPDATE-SHARE
129
+ # Note: active_record would attempt to generate UPDATE...LIMIT like
130
+ # SQL for Postgres if we use a .limit() filter, but it would not
131
+ # use 'FOR UPDATE' and we would have many locking conflicts
132
+ quoted_name = connection.quote_table_name(table_name)
133
+ subquery = ready_scope.limit(1).lock(true).select("id").to_sql
134
+ sql = "UPDATE #{quoted_name} SET locked_at = ?, locked_by = ? WHERE id IN (#{subquery}) RETURNING *"
135
+ reserved = find_by_sql([sql, now, worker.name])
136
+ reserved[0]
137
+ end
138
+
139
+ def self.reserve_with_scope_using_optimized_mysql(ready_scope, worker, now)
140
+ # Removing the millisecond precision from now(time object)
141
+ # MySQL 5.6.4 onwards millisecond precision exists, but the
142
+ # datetime object created doesn't have precision, so discarded
143
+ # while updating. But during the where clause, for mysql(>=5.6.4),
144
+ # it queries with precision as well. So removing the precision
145
+ now = now.change(usec: 0)
146
+ # This works on MySQL and possibly some other DBs that support
147
+ # UPDATE...LIMIT. It uses separate queries to lock and return the job
148
+ count = ready_scope.limit(1).update_all(locked_at: now, locked_by: worker.name)
149
+ return nil if count == 0
150
+
151
+ where(locked_at: now, locked_by: worker.name, failed_at: nil).first
152
+ end
153
+
154
+ def self.reserve_with_scope_using_optimized_mssql(ready_scope, worker, now)
155
+ # The MSSQL driver doesn't generate a limit clause when update_all
156
+ # is called directly
157
+ subsubquery_sql = ready_scope.limit(1).to_sql
158
+ # select("id") doesn't generate a subquery, so force a subquery
159
+ subquery_sql = "SELECT id FROM (#{subsubquery_sql}) AS x"
160
+ quoted_table_name = connection.quote_table_name(table_name)
161
+ sql = "UPDATE #{quoted_table_name} SET locked_at = ?, locked_by = ? WHERE id IN (#{subquery_sql})"
162
+ count = connection.execute(sanitize_sql([sql, now, worker.name]))
163
+ return nil if count == 0
164
+
165
+ # MSSQL JDBC doesn't support OUTPUT INSERTED.* for returning a result set, so query locked row
166
+ where(locked_at: now, locked_by: worker.name, failed_at: nil).first
167
+ end
168
+
97
169
  # Get the current time (GMT or local depending on DB)
98
170
  # Note: This does not ping the DB to get the time, so all your clients
99
171
  # must have syncronized clocks.
100
172
  def self.db_time_now
101
173
  if Time.zone
102
174
  Time.zone.now
103
- elsif ::ActiveRecord::Base.default_timezone == :utc
175
+ elsif default_timezone == :utc
104
176
  Time.now.utc
105
177
  else
106
- Time.now
178
+ Time.now # rubocop:disable Rails/TimeZone
179
+ end
180
+ end
181
+
182
+ def self.default_timezone
183
+ if ::ActiveRecord.respond_to?(:default_timezone)
184
+ ::ActiveRecord.default_timezone
185
+ else
186
+ ::ActiveRecord::Base.default_timezone
107
187
  end
108
188
  end
109
189
 
@@ -1,5 +1,7 @@
1
- require 'active_record'
2
- require 'delayed_job'
3
- require 'delayed/backend/active_record'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record"
4
+ require "delayed_job"
5
+ require "delayed/backend/active_record"
4
6
 
5
7
  Delayed::Worker.backend = :active_record
@@ -1,7 +1,9 @@
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
+ # frozen_string_literal: true
2
+
3
+ require "generators/delayed_job/delayed_job_generator"
4
+ require "generators/delayed_job/next_migration_version"
5
+ require "rails/generators/migration"
6
+ require "rails/generators/active_record"
5
7
 
6
8
  # Extend the DelayedJobGenerator so that it creates an AR migration
7
9
  module DelayedJob
@@ -9,14 +11,20 @@ module DelayedJob
9
11
  include Rails::Generators::Migration
10
12
  extend NextMigrationVersion
11
13
 
12
- source_paths << File.join(File.dirname(__FILE__), 'templates')
14
+ source_paths << File.join(File.dirname(__FILE__), "templates")
13
15
 
14
16
  def create_migration_file
15
- migration_template 'migration.rb', 'db/migrate/create_delayed_jobs.rb'
17
+ migration_template "migration.rb", "db/migrate/create_delayed_jobs.rb", migration_version: migration_version
16
18
  end
17
19
 
18
20
  def self.next_migration_number(dirname)
19
21
  ActiveRecord::Generators::Base.next_migration_number dirname
20
22
  end
23
+
24
+ private
25
+
26
+ def migration_version
27
+ "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]" if ActiveRecord::VERSION::MAJOR >= 5
28
+ end
21
29
  end
22
30
  end
@@ -1,13 +1,22 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DelayedJob
2
4
  module NextMigrationVersion
3
5
  # while methods have moved around this has been the implementation
4
6
  # since ActiveRecord 3.0
5
7
  def next_migration_number(dirname)
6
8
  next_migration_number = current_migration_number(dirname) + 1
7
- if ActiveRecord::Base.timestamped_migrations
8
- [Time.now.utc.strftime('%Y%m%d%H%M%S'), format('%.14d', next_migration_number)].max
9
+ timestamped_migrations =
10
+ if ActiveRecord.respond_to?(:timestamped_migrations)
11
+ ActiveRecord.timestamped_migrations
12
+ else
13
+ ActiveRecord::Base.timestamped_migrations
14
+ end
15
+
16
+ if timestamped_migrations
17
+ [Time.now.utc.strftime("%Y%m%d%H%M%S"), format("%.14d", next_migration_number)].max
9
18
  else
10
- format('%.3d', next_migration_number)
19
+ format("%.3d", next_migration_number)
11
20
  end
12
21
  end
13
22
  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 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,19 @@
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
+ # frozen_string_literal: true
2
+
3
+ require "generators/delayed_job/delayed_job_generator"
4
+ require "generators/delayed_job/next_migration_version"
5
+ require "rails/generators/migration"
6
+ require "rails/generators/active_record"
5
7
 
6
8
  # Extend the DelayedJobGenerator so that it creates an AR migration
7
9
  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
-
10
+ class UpgradeGenerator < ActiveRecordGenerator
14
11
  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
12
+ migration_template(
13
+ "upgrade_migration.rb",
14
+ "db/migrate/add_queue_to_delayed_jobs.rb",
15
+ migration_version: migration_version
16
+ )
20
17
  end
21
18
  end
22
19
  end
metadata CHANGED
@@ -1,16 +1,17 @@
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.8
5
5
  platform: ruby
6
6
  authors:
7
+ - David Genord II
7
8
  - Brian Ryckbost
8
9
  - Matt Griffin
9
10
  - Erik Michaels-Ober
10
- autorequire:
11
+ autorequire:
11
12
  bindir: bin
12
13
  cert_chain: []
13
- date: 2014-08-19 00:00:00.000000000 Z
14
+ date: 2023-10-13 00:00:00.000000000 Z
14
15
  dependencies:
15
16
  - !ruby/object:Gem::Dependency
16
17
  name: activerecord
@@ -21,7 +22,7 @@ dependencies:
21
22
  version: '3.0'
22
23
  - - "<"
23
24
  - !ruby/object:Gem::Version
24
- version: '4.2'
25
+ version: '8.0'
25
26
  type: :runtime
26
27
  prerelease: false
27
28
  version_requirements: !ruby/object:Gem::Requirement
@@ -31,7 +32,7 @@ dependencies:
31
32
  version: '3.0'
32
33
  - - "<"
33
34
  - !ruby/object:Gem::Version
34
- version: '4.2'
35
+ version: '8.0'
35
36
  - !ruby/object:Gem::Dependency
36
37
  name: delayed_job
37
38
  requirement: !ruby/object:Gem::Requirement
@@ -41,7 +42,7 @@ dependencies:
41
42
  version: '3.0'
42
43
  - - "<"
43
44
  - !ruby/object:Gem::Version
44
- version: '4.1'
45
+ version: '5'
45
46
  type: :runtime
46
47
  prerelease: false
47
48
  version_requirements: !ruby/object:Gem::Requirement
@@ -51,10 +52,11 @@ dependencies:
51
52
  version: '3.0'
52
53
  - - "<"
53
54
  - !ruby/object:Gem::Version
54
- version: '4.1'
55
+ version: '5'
55
56
  description: ActiveRecord backend for Delayed::Job, originally authored by Tobias
56
57
  Lütke
57
58
  email:
59
+ - david@collectiveidea.com
58
60
  - bryckbost@gmail.com
59
61
  - matt@griffinonline.org
60
62
  - sferik@gmail.com
@@ -65,7 +67,6 @@ files:
65
67
  - CONTRIBUTING.md
66
68
  - LICENSE.md
67
69
  - README.md
68
- - Rakefile
69
70
  - delayed_job_active_record.gemspec
70
71
  - lib/delayed/backend/active_record.rb
71
72
  - lib/delayed_job_active_record.rb
@@ -74,15 +75,12 @@ files:
74
75
  - lib/generators/delayed_job/templates/migration.rb
75
76
  - lib/generators/delayed_job/templates/upgrade_migration.rb
76
77
  - 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
78
  homepage: http://github.com/collectiveidea/delayed_job_active_record
82
79
  licenses:
83
80
  - MIT
84
- metadata: {}
85
- post_install_message:
81
+ metadata:
82
+ rubygems_mfa_required: 'true'
83
+ post_install_message:
86
84
  rdoc_options: []
87
85
  require_paths:
88
86
  - lib
@@ -97,13 +95,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
97
95
  - !ruby/object:Gem::Version
98
96
  version: '0'
99
97
  requirements: []
100
- rubyforge_project:
101
- rubygems_version: 2.4.1
102
- signing_key:
98
+ rubygems_version: 3.4.20
99
+ signing_key:
103
100
  specification_version: 4
104
101
  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
102
+ 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__)