delayed_job_active_record 4.0.1 → 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 82f721fcfca5c638b74b7fb452ec3c18cac88c28
4
- data.tar.gz: 57081f4124787944eee874326349f48d4fbdf7fa
3
+ metadata.gz: 0ba9b64dfebf36a3cc8248ff10fff63af3a8b611
4
+ data.tar.gz: 506aba7854d7c39aa711c54e38c7a87e2fd7c00d
5
5
  SHA512:
6
- metadata.gz: 34e1dadd821019d0b14b69bde6266192b74f018ae97141cf6754bfe5fb201b838ee295698dff925583e8c2808790f73ca94832a6c32797f3a1b6b3cff44e0fe6
7
- data.tar.gz: 5c7866cc0d33e46433dff9d60444e046edf0fe0555cc9a114ec7a8aa517a61c19add09eac0b1334126450b0d97debd10276dee06916a531a7f29cb998a02d52e
6
+ metadata.gz: 7f1b5ad0fa88e075b988d4234654cfdbc0e63e8a32344d8cb1824ef7562f88b1aa7ad63952e3176df823daac164fda2bf34692735062961cb59896d10f0dec72
7
+ data.tar.gz: a4621ce576f0d7fb0458ccd3aa396ad79a5f5bd7ef85440c6aead1fcb8b6b11d11bc5610042b7da72f909a6fd5efeae0c1676427a80233d1d66cdc88a0f273e2
data/Rakefile CHANGED
@@ -1,10 +1,10 @@
1
1
  # -*- encoding: utf-8 -*-
2
- require "bundler/gem_helper"
2
+ require 'bundler/gem_helper'
3
3
  Bundler::GemHelper.install_tasks
4
4
 
5
- require "rspec/core/rake_task"
5
+ require 'rspec/core/rake_task'
6
6
 
7
- ADAPTERS = %w(mysql postgresql sqlite3)
7
+ ADAPTERS = %w[mysql postgresql sqlite3]
8
8
 
9
9
  ADAPTERS.each do |adapter|
10
10
  desc "Run RSpec code examples for #{adapter} adapter"
@@ -12,24 +12,27 @@ ADAPTERS.each do |adapter|
12
12
 
13
13
  namespace adapter do
14
14
  task :adapter do
15
- ENV["ADAPTER"] = adapter
15
+ ENV['ADAPTER'] = adapter
16
16
  end
17
17
  end
18
18
  end
19
19
 
20
20
  task :coverage do
21
- ENV["COVERAGE"] = "true"
21
+ ENV['COVERAGE'] = 'true'
22
22
  end
23
23
 
24
24
  task :adapter do
25
- ENV["ADAPTER"] = nil
25
+ ENV['ADAPTER'] = nil
26
26
  end
27
27
 
28
28
  Rake::Task[:spec].enhance do
29
- require "simplecov"
30
- require "coveralls"
29
+ require 'simplecov'
30
+ require 'coveralls'
31
31
 
32
32
  Coveralls::SimpleCov::Formatter.new.format(SimpleCov.result)
33
33
  end
34
34
 
35
- task default: ([:coverage] + ADAPTERS + [:adapter])
35
+ require 'rubocop/rake_task'
36
+ RuboCop::RakeTask.new
37
+
38
+ task :default => ([:coverage] + ADAPTERS + [:adapter] + [:rubocop])
@@ -1,19 +1,19 @@
1
1
  # coding: utf-8
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"]
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
7
  spec.description = 'ActiveRecord backend for Delayed::Job, originally authored by Tobias Lütke'
8
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/**/*")
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
12
  spec.homepage = 'http://github.com/collectiveidea/delayed_job_active_record'
13
13
  spec.licenses = ['MIT']
14
14
  spec.name = 'delayed_job_active_record'
15
15
  spec.require_paths = ['lib']
16
16
  spec.summary = 'ActiveRecord backend for DelayedJob'
17
- spec.test_files = Dir.glob("spec/**/*")
18
- spec.version = '4.0.1'
17
+ spec.test_files = Dir.glob('spec/**/*')
18
+ spec.version = '4.0.2'
19
19
  end
@@ -21,7 +21,7 @@ module Delayed
21
21
  self.table_name = delayed_job_table_name
22
22
  end
23
23
 
24
- self.set_delayed_job_table_name
24
+ set_delayed_job_table_name
25
25
 
26
26
  def self.ready_to_run(worker_name, max_run_time)
27
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)
@@ -40,9 +40,9 @@ module Delayed
40
40
  where(:locked_by => worker_name).update_all(:locked_by => nil, :locked_at => nil)
41
41
  end
42
42
 
43
- def self.reserve(worker, max_run_time = Worker.max_run_time)
43
+ def self.reserve(worker, max_run_time = Worker.max_run_time) # rubocop:disable CyclomaticComplexity
44
44
  # scope to filter to records that are "ready to run"
45
- ready_scope = self.ready_to_run(worker.name, max_run_time)
45
+ ready_scope = ready_to_run(worker.name, max_run_time)
46
46
 
47
47
  # scope to filter to the single next eligible job
48
48
  ready_scope = ready_scope.where('priority >= ?', Worker.min_priority) if Worker.min_priority
@@ -50,41 +50,47 @@ module Delayed
50
50
  ready_scope = ready_scope.where(:queue => Worker.queues) if Worker.queues.any?
51
51
  ready_scope = ready_scope.by_priority
52
52
 
53
- now = self.db_time_now
53
+ reserve_with_scope(ready_scope, worker, db_time_now)
54
+ end
54
55
 
56
+ def self.reserve_with_scope(ready_scope, worker, now)
55
57
  # Optimizations for faster lookups on some common databases
56
- case self.connection.adapter_name
57
- when "PostgreSQL"
58
+ case connection.adapter_name
59
+ when 'PostgreSQL'
58
60
  # Custom SQL required for PostgreSQL because postgres does not support UPDATE...LIMIT
59
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)
60
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
61
63
  # 'FOR UPDATE' and we would have many locking conflicts
62
- quoted_table_name = self.connection.quote_table_name(self.table_name)
64
+ quoted_table_name = connection.quote_table_name(table_name)
63
65
  subquery_sql = ready_scope.limit(1).lock(true).select('id').to_sql
64
- reserved = self.find_by_sql(["UPDATE #{quoted_table_name} SET locked_at = ?, locked_by = ? WHERE id IN (#{subquery_sql}) RETURNING *", now, worker.name])
66
+ reserved = find_by_sql(["UPDATE #{quoted_table_name} SET locked_at = ?, locked_by = ? WHERE id IN (#{subquery_sql}) RETURNING *", now, worker.name])
65
67
  reserved[0]
66
- when "MySQL", "Mysql2"
68
+ when 'MySQL', 'Mysql2'
67
69
  # This works on MySQL and possibly some other DBs that support UPDATE...LIMIT. It uses separate queries to lock and return the job
68
70
  count = ready_scope.limit(1).update_all(:locked_at => now, :locked_by => worker.name)
69
71
  return nil if count == 0
70
- self.where(:locked_at => now, :locked_by => worker.name, :failed_at => nil).first
71
- when "MSSQL", "Teradata"
72
+ where(:locked_at => now, :locked_by => worker.name, :failed_at => nil).first
73
+ when 'MSSQL', 'Teradata'
72
74
  # The MSSQL driver doesn't generate a limit clause when update_all is called directly
73
75
  subsubquery_sql = ready_scope.limit(1).to_sql
74
76
  # select("id") doesn't generate a subquery, so force a subquery
75
77
  subquery_sql = "SELECT id FROM (#{subsubquery_sql}) AS x"
76
- quoted_table_name = self.connection.quote_table_name(self.table_name)
78
+ quoted_table_name = connection.quote_table_name(table_name)
77
79
  sql = ["UPDATE #{quoted_table_name} SET locked_at = ?, locked_by = ? WHERE id IN (#{subquery_sql})", now, worker.name]
78
- count = self.connection.execute(sanitize_sql(sql))
80
+ count = connection.execute(sanitize_sql(sql))
79
81
  return nil if count == 0
80
82
  # MSSQL JDBC doesn't support OUTPUT INSERTED.* for returning a result set, so query locked row
81
- self.where(:locked_at => now, :locked_by => worker.name, :failed_at => nil).first
83
+ where(:locked_at => now, :locked_by => worker.name, :failed_at => nil).first
82
84
  else
83
- # This is our old fashion, tried and true, but slower lookup
84
- ready_scope.limit(worker.read_ahead).detect do |job|
85
- count = ready_scope.where(:id => job.id).update_all(:locked_at => now, :locked_by => worker.name)
86
- count == 1 && job.reload
87
- end
85
+ reserve_with_scope_using_default_sql(ready_scope, worker, now)
86
+ end
87
+ end
88
+
89
+ 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)
93
+ count == 1 && job.reload
88
94
  end
89
95
  end
90
96
 
@@ -9,13 +9,13 @@ module DelayedJob
9
9
  include Rails::Generators::Migration
10
10
  extend NextMigrationVersion
11
11
 
12
- self.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
15
  migration_template 'migration.rb', 'db/migrate/create_delayed_jobs.rb'
16
16
  end
17
17
 
18
- def self.next_migration_number dirname
18
+ def self.next_migration_number(dirname)
19
19
  ActiveRecord::Generators::Base.next_migration_number dirname
20
20
  end
21
21
  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"), "%.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
- "%.3d" % next_migration_number
10
+ format('%.3d', next_migration_number)
11
11
  end
12
12
  end
13
13
  end
@@ -1,15 +1,15 @@
1
1
  class CreateDelayedJobs < ActiveRecord::Migration
2
2
  def self.up
3
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
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
13
  table.timestamps
14
14
  end
15
15
 
@@ -9,13 +9,13 @@ module DelayedJob
9
9
  include Rails::Generators::Migration
10
10
  extend NextMigrationVersion
11
11
 
12
- self.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
15
  migration_template 'upgrade_migration.rb', 'db/migrate/add_queue_to_delayed_jobs.rb'
16
16
  end
17
17
 
18
- def self.next_migration_number dirname
18
+ def self.next_migration_number(dirname)
19
19
  ActiveRecord::Generators::Base.next_migration_number dirname
20
20
  end
21
21
  end
@@ -4,39 +4,59 @@ require 'delayed/backend/active_record'
4
4
  describe Delayed::Backend::ActiveRecord::Job do
5
5
  it_behaves_like 'a delayed_job backend'
6
6
 
7
- context "db_time_now" do
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
8
28
  after do
9
29
  Time.zone = nil
10
30
  ActiveRecord::Base.default_timezone = :local
11
31
  end
12
32
 
13
- it "returns time in current time zone if set" do
33
+ it 'returns time in current time zone if set' do
14
34
  Time.zone = 'Eastern Time (US & Canada)'
15
35
  expect(%(EST EDT)).to include(Delayed::Job.db_time_now.zone)
16
36
  end
17
37
 
18
- it "returns UTC time if that is the AR default" do
38
+ it 'returns UTC time if that is the AR default' do
19
39
  Time.zone = nil
20
40
  ActiveRecord::Base.default_timezone = :utc
21
41
  expect(Delayed::Backend::ActiveRecord::Job.db_time_now.zone).to eq 'UTC'
22
42
  end
23
43
 
24
- it "returns local time if that is the AR default" do
44
+ it 'returns local time if that is the AR default' do
25
45
  Time.zone = 'Central Time (US & Canada)'
26
46
  ActiveRecord::Base.default_timezone = :local
27
- expect(%w(CST CDT)).to include(Delayed::Backend::ActiveRecord::Job.db_time_now.zone)
47
+ expect(%w[CST CDT]).to include(Delayed::Backend::ActiveRecord::Job.db_time_now.zone)
28
48
  end
29
49
  end
30
50
 
31
- describe "after_fork" do
32
- it "calls reconnect on the connection" do
33
- ActiveRecord::Base.should_receive(:establish_connection)
51
+ describe 'after_fork' do
52
+ it 'calls reconnect on the connection' do
53
+ allow(ActiveRecord::Base).to receive(:establish_connection)
34
54
  Delayed::Backend::ActiveRecord::Job.after_fork
35
55
  end
36
56
  end
37
57
 
38
- describe "enqueue" do
39
- it "allows enqueue hook to modify job at DB level" do
58
+ describe 'enqueue' do
59
+ it 'allows enqueue hook to modify job at DB level' do
40
60
  later = described_class.db_time_now + 20.minutes
41
61
  job = Delayed::Backend::ActiveRecord::Job.enqueue :payload_object => EnqueueJobMod.new
42
62
  expect(Delayed::Backend::ActiveRecord::Job.find(job.id).run_at).to be_within(1).of(later)
@@ -44,7 +64,7 @@ describe Delayed::Backend::ActiveRecord::Job do
44
64
  end
45
65
 
46
66
  if ::ActiveRecord::VERSION::MAJOR < 4 || defined?(::ActiveRecord::MassAssignmentSecurity)
47
- context "ActiveRecord::Base.send(:attr_accessible, nil)" do
67
+ context 'ActiveRecord::Base.send(:attr_accessible, nil)' do
48
68
  before do
49
69
  Delayed::Backend::ActiveRecord::Job.send(:attr_accessible, nil)
50
70
  end
@@ -53,14 +73,14 @@ describe Delayed::Backend::ActiveRecord::Job do
53
73
  Delayed::Backend::ActiveRecord::Job.send(:attr_accessible, *Delayed::Backend::ActiveRecord::Job.new.attributes.keys)
54
74
  end
55
75
 
56
- it "is still accessible" do
76
+ it 'is still accessible' do
57
77
  job = Delayed::Backend::ActiveRecord::Job.enqueue :payload_object => EnqueueJobMod.new
58
78
  expect(Delayed::Backend::ActiveRecord::Job.find(job.id).handler).to_not be_blank
59
79
  end
60
80
  end
61
81
  end
62
82
 
63
- context "ActiveRecord::Base.table_name_prefix" do
83
+ context 'ActiveRecord::Base.table_name_prefix' do
64
84
  it "when prefix is not set, use 'delayed_jobs' as table name" do
65
85
  ::ActiveRecord::Base.table_name_prefix = nil
66
86
  Delayed::Backend::ActiveRecord::Job.set_delayed_job_table_name
@@ -68,7 +88,7 @@ describe Delayed::Backend::ActiveRecord::Job do
68
88
  expect(Delayed::Backend::ActiveRecord::Job.table_name).to eq 'delayed_jobs'
69
89
  end
70
90
 
71
- it "when prefix is set, prepend it before default table name" do
91
+ it 'when prefix is set, prepend it before default table name' do
72
92
  ::ActiveRecord::Base.table_name_prefix = 'custom_'
73
93
  Delayed::Backend::ActiveRecord::Job.set_delayed_job_table_name
74
94
 
@@ -1,15 +1,15 @@
1
1
  require 'helper'
2
2
 
3
3
  describe ActiveRecord do
4
- it "loads classes with non-default primary key" do
5
- expect {
4
+ it 'loads classes with non-default primary key' do
5
+ expect do
6
6
  YAML.load(Story.create.to_yaml)
7
- }.not_to raise_error
7
+ end.not_to raise_error
8
8
  end
9
9
 
10
- it "loads classes even if not in default scope" do
11
- expect {
10
+ it 'loads classes even if not in default scope' do
11
+ expect do
12
12
  YAML.load(Story.create(:scoped => false).to_yaml)
13
- }.not_to raise_error
13
+ end.not_to raise_error
14
14
  end
15
15
  end
data/spec/helper.rb CHANGED
@@ -3,16 +3,20 @@ require 'coveralls'
3
3
 
4
4
  SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
5
5
  SimpleCov::Formatter::HTMLFormatter,
6
- Coveralls::SimpleCov::Formatter
6
+ Coveralls::SimpleCov::Formatter
7
7
  ]
8
- SimpleCov.start
8
+
9
+ SimpleCov.start do
10
+ add_filter '/spec/'
11
+ minimum_coverage(73.33)
12
+ end
9
13
 
10
14
  require 'logger'
11
15
  require 'rspec'
12
16
 
13
17
  begin
14
18
  require 'protected_attributes'
15
- rescue LoadError
19
+ rescue LoadError # rubocop:disable HandleExceptions
16
20
  end
17
21
  require 'delayed_job_active_record'
18
22
  require 'delayed/backend/shared_spec'
@@ -20,8 +24,8 @@ require 'delayed/backend/shared_spec'
20
24
  Delayed::Worker.logger = Logger.new('/tmp/dj.log')
21
25
  ENV['RAILS_ENV'] = 'test'
22
26
 
23
- db_adapter, gemfile = ENV["ADAPTER"], ENV["BUNDLE_GEMFILE"]
24
- db_adapter ||= gemfile && gemfile[%r(gemfiles/(.*?)/)] && $1
27
+ db_adapter, gemfile = ENV['ADAPTER'], ENV['BUNDLE_GEMFILE']
28
+ db_adapter ||= gemfile && gemfile[%r{gemfiles/(.*?)/}] && $1 # rubocop:disable PerlBackrefs
25
29
  db_adapter ||= 'sqlite3'
26
30
 
27
31
  config = YAML.load(File.read('spec/database.yml'))
@@ -31,15 +35,15 @@ ActiveRecord::Migration.verbose = false
31
35
 
32
36
  ActiveRecord::Schema.define do
33
37
  create_table :delayed_jobs, :force => true do |table|
34
- table.integer :priority, :default => 0
35
- table.integer :attempts, :default => 0
36
- table.text :handler
37
- table.text :last_error
38
+ table.integer :priority, :default => 0
39
+ table.integer :attempts, :default => 0
40
+ table.text :handler
41
+ table.text :last_error
38
42
  table.datetime :run_at
39
43
  table.datetime :locked_at
40
44
  table.datetime :failed_at
41
- table.string :locked_by
42
- table.string :queue
45
+ table.string :locked_by
46
+ table.string :queue
43
47
  table.timestamps
44
48
  end
45
49
 
@@ -58,8 +62,13 @@ class Story < ActiveRecord::Base
58
62
  else
59
63
  self.primary_key = :story_id
60
64
  end
61
- def tell; text; end
62
- def whatever(n, _); tell*n; end
65
+ def tell
66
+ text
67
+ end
68
+
69
+ def whatever(n, _)
70
+ tell * n
71
+ end
63
72
  default_scope { where(:scoped => true) }
64
73
 
65
74
  handle_asynchronously :whatever
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.1
4
+ version: 4.0.2
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-04-12 00:00:00.000000000 Z
13
+ date: 2014-08-19 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -98,7 +98,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
98
98
  version: '0'
99
99
  requirements: []
100
100
  rubyforge_project:
101
- rubygems_version: 2.2.2
101
+ rubygems_version: 2.4.1
102
102
  signing_key:
103
103
  specification_version: 4
104
104
  summary: ActiveRecord backend for DelayedJob