delayed_job_active_record 0.3.3 → 0.4.0

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.
@@ -0,0 +1,14 @@
1
+ ## How to contribute
2
+
3
+ If you find what looks like a bug:
4
+
5
+ * Search the [mailing list](http://groups.google.com/group/delayed_job) to see if anyone else had the same issue.
6
+ * Check the [GitHub issue tracker](http://github.com/collectiveidea/delayed_job_active_record/issues/) to see if anyone else has reported issue.
7
+ * If you don't see anything, create an issue with information on how to reproduce it.
8
+
9
+ If you want to contribute an enhancement or a fix:
10
+
11
+ * Fork the project on github.
12
+ * Make your changes with tests.
13
+ * Commit the changes without making changes to the Rakefile or any other files that aren't related to your enhancement or fix
14
+ * Send a pull request.
@@ -1,4 +1,4 @@
1
- Copyright (c) 2005 Tobias Luetke
1
+ Copyright (c) 2005 Tobias Lütke
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # DelayedJob ActiveRecord Backend [![Build Status](http://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)
1
+ # DelayedJob ActiveRecord Backend [![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)
2
2
 
3
3
  ## Installation
4
4
 
@@ -12,7 +12,7 @@ If you're using Rails, run the generator to create the migration for the delayed
12
12
 
13
13
  rails g delayed_job:active_record
14
14
  rake db:migrate
15
-
15
+
16
16
  ## Upgrading from 2.x to 3.0.0
17
17
 
18
18
  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.
@@ -21,18 +21,3 @@ If you're upgrading from Delayed Job 2.x, run the upgrade generator to create a
21
21
  rake db:migrate
22
22
 
23
23
  That's it. Use [delayed_job as normal](http://github.com/collectiveidea/delayed_job).
24
-
25
- ## How to contribute
26
-
27
- If you find what looks like a bug:
28
-
29
- * Search the [mailing list](http://groups.google.com/group/delayed_job) to see if anyone else had the same issue.
30
- * Check the [GitHub issue tracker](http://github.com/collectiveidea/delayed_job_active_record/issues/) to see if anyone else has reported issue.
31
- * If you don't see anything, create an issue with information on how to reproduce it.
32
-
33
- If you want to contribute an enhancement or a fix:
34
-
35
- * Fork the project on github.
36
- * Make your changes with tests.
37
- * Commit the changes without making changes to the Rakefile or any other files that aren't related to your enhancement or fix
38
- * Send a pull request.
@@ -0,0 +1,12 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'rubygems'
3
+ require 'bundler/setup'
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ require 'rspec/core/rake_task'
7
+ desc 'Run the specs'
8
+ RSpec::Core::RakeTask.new do |r|
9
+ r.verbose = false
10
+ end
11
+
12
+ task :default => :spec
@@ -0,0 +1,19 @@
1
+ # coding: utf-8
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.add_dependency 'activerecord', ['>= 2.1.0', '< 4']
5
+ spec.add_dependency 'delayed_job', '~> 3.0'
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 = '0.4.0'
19
+ end
@@ -12,26 +12,19 @@ module Delayed
12
12
 
13
13
  before_save :set_default_run_at
14
14
 
15
- def self.rails3?
16
- ::ActiveRecord::VERSION::MAJOR == 3
15
+ def self.set_delayed_job_table_name
16
+ delayed_job_table_name = "#{::ActiveRecord::Base.table_name_prefix}delayed_jobs"
17
+ self.table_name = delayed_job_table_name
17
18
  end
18
19
 
19
- delayed_job_table_name = "#{::ActiveRecord::Base.table_name_prefix}delayed_jobs"
20
+ self.set_delayed_job_table_name
20
21
 
21
- if rails3?
22
- self.table_name = delayed_job_table_name
23
- def self.ready_to_run(worker_name, max_run_time)
24
- 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)
25
- end
26
- def self.by_priority
27
- order('priority ASC, run_at ASC')
28
- end
29
- else
30
- set_table_name delayed_job_table_name
31
- named_scope :ready_to_run, lambda {|worker_name, max_run_time|
32
- { :conditions => ['(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] }
33
- }
34
- named_scope :by_priority, :order => 'priority ASC, run_at ASC'
22
+ def self.ready_to_run(worker_name, max_run_time)
23
+ 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)
24
+ end
25
+
26
+ def self.by_priority
27
+ order('priority ASC, run_at ASC')
35
28
  end
36
29
 
37
30
  def self.before_fork
@@ -47,15 +40,32 @@ module Delayed
47
40
  update_all("locked_by = null, locked_at = null", ["locked_by = ?", worker_name])
48
41
  end
49
42
 
50
- # Find a few candidate jobs to run (in case some immediately get locked by others).
51
- def self.find_available(worker_name, limit = 5, max_run_time = Worker.max_run_time)
52
- scope = self.ready_to_run(worker_name, max_run_time)
53
- scope = scope.scoped(:conditions => ['priority >= ?', Worker.min_priority]) if Worker.min_priority
54
- scope = scope.scoped(:conditions => ['priority <= ?', Worker.max_priority]) if Worker.max_priority
55
- scope = scope.scoped(:conditions => ["queue IN (?)", Worker.queues]) if Worker.queues.any?
43
+ def self.reserve(worker, max_run_time = Worker.max_run_time)
44
+ # scope to filter to records that are "ready to run"
45
+ readyScope = self.ready_to_run(worker.name, max_run_time)
46
+
47
+ # scope to filter to the single next eligible job (locking it for update http://www.postgresql.org/docs/9.0/static/sql-select.html#SQL-FOR-UPDATE-SHARE)
48
+ nextScope = readyScope.scoped
49
+ nextScope = nextScope.scoped(:conditions => ['priority >= ?', Worker.min_priority]) if Worker.min_priority
50
+ nextScope = nextScope.scoped(:conditions => ['priority <= ?', Worker.max_priority]) if Worker.max_priority
51
+ nextScope = nextScope.scoped(:conditions => ["queue IN (?)", Worker.queues]) if Worker.queues.any?
52
+ nextScope = nextScope.scoped.by_priority.limit(1).lock(true)
53
+ nextScope = nextScope.scoped.select('id')
56
54
 
57
- ::ActiveRecord::Base.silence do
58
- scope.by_priority.all(:limit => limit)
55
+ now = self.db_time_now
56
+
57
+ if ::ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
58
+ # This works on PostgreSQL and uses 1 less query, but uses SQL not supported nativly through ActiveRecord
59
+ quotedTableName = ::ActiveRecord::Base.connection.quote_column_name(self.table_name)
60
+ reserved = self.find_by_sql(["UPDATE #{quotedTableName} SET locked_at = ?, locked_by = ? WHERE id IN (#{nextScope.to_sql}) RETURNING *",now,worker.name])
61
+ return reserved[0]
62
+ else
63
+ # This works on any database and uses seperate queries to lock and return the job
64
+ # Databases like PostgreSQL and MySQL that support "SELECT .. FOR UPDATE" (ActiveRecord Pessimistic locking) don't need the second application
65
+ # of 'readyScope' but it doesn't hurt and it ensures that the job being locked still meets ready_to_run criteria.
66
+ count = readyScope.where(:id => nextScope).update_all(:locked_at => now, :locked_by => worker.name)
67
+ return nil if count == 0
68
+ return self.where(:locked_at => now, :locked_by => worker.name).first
59
69
  end
60
70
  end
61
71
 
@@ -74,8 +84,7 @@ module Delayed
74
84
  if affected_rows == 1
75
85
  self.locked_at = now
76
86
  self.locked_by = worker
77
- self.locked_at_will_change!
78
- self.locked_by_will_change!
87
+ self.changed_attributes.clear
79
88
  return true
80
89
  else
81
90
  return false
@@ -2,43 +2,44 @@ require 'spec_helper'
2
2
  require 'delayed/backend/active_record'
3
3
 
4
4
  describe Delayed::Backend::ActiveRecord::Job do
5
- after do
6
- Time.zone = nil
7
- end
8
-
9
- it_should_behave_like 'a delayed_job backend'
5
+ it_behaves_like 'a delayed_job backend'
10
6
 
11
7
  context "db_time_now" do
12
- it "should return time in current time zone if set" do
8
+ after do
9
+ Time.zone = nil
10
+ ActiveRecord::Base.default_timezone = :local
11
+ end
12
+
13
+ it "returns time in current time zone if set" do
13
14
  Time.zone = 'Eastern Time (US & Canada)'
14
- %w(EST EDT).should include(Delayed::Job.db_time_now.zone)
15
+ expect(%(EST EDT)).to include(Delayed::Job.db_time_now.zone)
15
16
  end
16
17
 
17
- it "should return UTC time if that is the AR default" do
18
+ it "returns UTC time if that is the AR default" do
18
19
  Time.zone = nil
19
20
  ActiveRecord::Base.default_timezone = :utc
20
- Delayed::Backend::ActiveRecord::Job.db_time_now.zone.should == 'UTC'
21
+ expect(Delayed::Backend::ActiveRecord::Job.db_time_now.zone).to eq 'UTC'
21
22
  end
22
23
 
23
- it "should return local time if that is the AR default" do
24
+ it "returns local time if that is the AR default" do
24
25
  Time.zone = 'Central Time (US & Canada)'
25
26
  ActiveRecord::Base.default_timezone = :local
26
- %w(CST CDT).should include(Delayed::Backend::ActiveRecord::Job.db_time_now.zone)
27
+ expect(%w(CST CDT)).to include(Delayed::Backend::ActiveRecord::Job.db_time_now.zone)
27
28
  end
28
29
  end
29
30
 
30
31
  describe "after_fork" do
31
- it "should call reconnect on the connection" do
32
+ it "calls reconnect on the connection" do
32
33
  ActiveRecord::Base.should_receive(:establish_connection)
33
34
  Delayed::Backend::ActiveRecord::Job.after_fork
34
35
  end
35
36
  end
36
37
 
37
38
  describe "enqueue" do
38
- it "should allow enqueue hook to modify job at DB level" do
39
+ it "allows enqueue hook to modify job at DB level" do
39
40
  later = described_class.db_time_now + 20.minutes
40
41
  job = Delayed::Backend::ActiveRecord::Job.enqueue :payload_object => EnqueueJobMod.new
41
- Delayed::Backend::ActiveRecord::Job.find(job.id).run_at.should be_within(1).of(later)
42
+ expect(Delayed::Backend::ActiveRecord::Job.find(job.id).run_at).to be_within(1).of(later)
42
43
  end
43
44
  end
44
45
 
@@ -51,28 +52,28 @@ describe Delayed::Backend::ActiveRecord::Job do
51
52
  Delayed::Backend::ActiveRecord::Job.send(:attr_accessible, *Delayed::Backend::ActiveRecord::Job.new.attributes.keys)
52
53
  end
53
54
 
54
- it "should still be accessible" do
55
+ it "is still accessible" do
55
56
  job = Delayed::Backend::ActiveRecord::Job.enqueue :payload_object => EnqueueJobMod.new
56
- Delayed::Backend::ActiveRecord::Job.find(job.id).handler.should_not be_blank
57
+ expect(Delayed::Backend::ActiveRecord::Job.find(job.id).handler).to_not be_blank
57
58
  end
58
59
  end
59
60
 
60
61
  context "ActiveRecord::Base.table_name_prefix" do
61
- def reload_job_class_definition
62
- # If this can be done in a more sane manner, please fix it
63
- load File.join File.dirname(__FILE__), '..', '..', '..', 'lib', 'delayed', 'backend', 'active_record.rb'
64
- end
65
-
66
- it "when prefix is not set, should use 'delayed_jobs' as table name" do
62
+ it "when prefix is not set, use 'delayed_jobs' as table name" do
67
63
  ::ActiveRecord::Base.table_name_prefix = nil
68
- reload_job_class_definition
69
- Delayed::Backend::ActiveRecord::Job.table_name.should eq 'delayed_jobs'
64
+ Delayed::Backend::ActiveRecord::Job.set_delayed_job_table_name
65
+
66
+ expect(Delayed::Backend::ActiveRecord::Job.table_name).to eq 'delayed_jobs'
70
67
  end
71
68
 
72
- it "when prefix is set, should prepend it before default table name" do
69
+ it "when prefix is set, prepend it before default table name" do
73
70
  ::ActiveRecord::Base.table_name_prefix = 'custom_'
74
- reload_job_class_definition
75
- Delayed::Backend::ActiveRecord::Job.table_name.should eq 'custom_delayed_jobs'
71
+ Delayed::Backend::ActiveRecord::Job.set_delayed_job_table_name
72
+
73
+ expect(Delayed::Backend::ActiveRecord::Job.table_name).to eq 'custom_delayed_jobs'
74
+
75
+ ::ActiveRecord::Base.table_name_prefix = nil
76
+ Delayed::Backend::ActiveRecord::Job.set_delayed_job_table_name
76
77
  end
77
78
  end
78
79
  end
@@ -1,15 +1,15 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe ActiveRecord do
4
- it 'should load classes with non-default primary key' do
5
- lambda {
4
+ it "loads classes with non-default primary key" do
5
+ expect {
6
6
  YAML.load(Story.create.to_yaml)
7
- }.should_not raise_error
7
+ }.not_to raise_error
8
8
  end
9
9
 
10
- it 'should load classes even if not in default scope' do
11
- lambda {
10
+ it "loads classes even if not in default scope" do
11
+ expect {
12
12
  YAML.load(Story.create(:scoped => false).to_yaml)
13
- }.should_not raise_error
13
+ }.not_to raise_error
14
14
  end
15
15
  end
@@ -40,7 +40,7 @@ end
40
40
 
41
41
  # Purely useful for test cases...
42
42
  class Story < ActiveRecord::Base
43
- set_primary_key :story_id
43
+ self.primary_key = :story_id
44
44
  def tell; text; end
45
45
  def whatever(n, _); tell*n; end
46
46
  default_scope where(:scoped => true)
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: 0.3.3
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-09-30 00:00:00.000000000 Z
14
+ date: 2013-02-10 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activerecord
@@ -51,64 +51,21 @@ dependencies:
51
51
  - - ~>
52
52
  - !ruby/object:Gem::Version
53
53
  version: '3.0'
54
- - !ruby/object:Gem::Dependency
55
- name: rake
56
- requirement: !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - ! '>='
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- none: false
66
- requirements:
67
- - - ! '>='
68
- - !ruby/object:Gem::Version
69
- version: '0'
70
- - !ruby/object:Gem::Dependency
71
- name: rspec
72
- requirement: !ruby/object:Gem::Requirement
73
- none: false
74
- requirements:
75
- - - ! '>='
76
- - !ruby/object:Gem::Version
77
- version: '0'
78
- type: :development
79
- prerelease: false
80
- version_requirements: !ruby/object:Gem::Requirement
81
- none: false
82
- requirements:
83
- - - ! '>='
84
- - !ruby/object:Gem::Version
85
- version: '0'
86
- - !ruby/object:Gem::Dependency
87
- name: sqlite3
88
- requirement: !ruby/object:Gem::Requirement
89
- none: false
90
- requirements:
91
- - - ! '>='
92
- - !ruby/object:Gem::Version
93
- version: '0'
94
- type: :development
95
- prerelease: false
96
- version_requirements: !ruby/object:Gem::Requirement
97
- none: false
98
- requirements:
99
- - - ! '>='
100
- - !ruby/object:Gem::Version
101
- version: '0'
102
- description: ActiveRecord backend for DelayedJob, originally authored by Tobias Luetke
54
+ description: ActiveRecord backend for Delayed::Job, originally authored by Tobias
55
+ Lütke
103
56
  email:
104
57
  - bryckbost@gmail.com
105
58
  - matt@griffinonline.org
106
59
  - sferik@gmail.com
107
60
  executables: []
108
61
  extensions: []
109
- extra_rdoc_files:
110
- - README.md
62
+ extra_rdoc_files: []
111
63
  files:
64
+ - CONTRIBUTING.md
65
+ - LICENSE.md
66
+ - README.md
67
+ - Rakefile
68
+ - delayed_job_active_record.gemspec
112
69
  - lib/delayed/backend/active_record.rb
113
70
  - lib/delayed_job_active_record.rb
114
71
  - lib/generators/delayed_job/active_record_generator.rb
@@ -119,16 +76,11 @@ files:
119
76
  - spec/delayed/backend/active_record_spec.rb
120
77
  - spec/delayed/serialization/active_record_spec.rb
121
78
  - spec/spec_helper.rb
122
- - LICENSE
123
- - README.md
124
79
  homepage: http://github.com/collectiveidea/delayed_job_active_record
125
- licenses: []
80
+ licenses:
81
+ - MIT
126
82
  post_install_message:
127
- rdoc_options:
128
- - --main
129
- - README.md
130
- - --inline-source
131
- - --line-numbers
83
+ rdoc_options: []
132
84
  require_paths:
133
85
  - lib
134
86
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -139,7 +91,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
139
91
  version: '0'
140
92
  segments:
141
93
  - 0
142
- hash: -4543581460881455669
94
+ hash: -1678145937006917333
143
95
  required_rubygems_version: !ruby/object:Gem::Requirement
144
96
  none: false
145
97
  requirements:
@@ -148,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
148
100
  version: '0'
149
101
  segments:
150
102
  - 0
151
- hash: -4543581460881455669
103
+ hash: -1678145937006917333
152
104
  requirements: []
153
105
  rubyforge_project:
154
106
  rubygems_version: 1.8.23