delayed_job_active_record 0.4.4 → 4.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,8 +1,8 @@
1
1
  # coding: utf-8
2
2
 
3
3
  Gem::Specification.new do |spec|
4
- spec.add_dependency 'activerecord', ['>= 2.1.0', '< 4']
5
- spec.add_dependency 'delayed_job', '~> 3.0'
4
+ spec.add_dependency 'activerecord', ['>= 3.0', '< 4.1']
5
+ spec.add_dependency 'delayed_job', '~> 4.0.0.beta1'
6
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']
@@ -15,5 +15,5 @@ Gem::Specification.new do |spec|
15
15
  spec.require_paths = ['lib']
16
16
  spec.summary = 'ActiveRecord backend for DelayedJob'
17
17
  spec.test_files = Dir.glob("spec/**/*")
18
- spec.version = '0.4.4'
18
+ spec.version = '4.0.0.beta1'
19
19
  end
@@ -7,8 +7,7 @@ module Delayed
7
7
  class Job < ::ActiveRecord::Base
8
8
  include Delayed::Backend::Base
9
9
 
10
- attr_accessible :priority, :run_at, :queue, :payload_object,
11
- :failed_at, :locked_at, :locked_by
10
+ scope :by_priority, lambda { order('priority ASC, run_at ASC') }
12
11
 
13
12
  before_save :set_default_run_at
14
13
 
@@ -23,10 +22,6 @@ module Delayed
23
22
  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
23
  end
25
24
 
26
- def self.by_priority
27
- order('priority ASC, run_at ASC')
28
- end
29
-
30
25
  def self.before_fork
31
26
  ::ActiveRecord::Base.clear_all_connections!
32
27
  end
@@ -42,38 +37,44 @@ module Delayed
42
37
 
43
38
  def self.reserve(worker, max_run_time = Worker.max_run_time)
44
39
  # scope to filter to records that are "ready to run"
45
- ready_scope = self.ready_to_run(worker.name, max_run_time)
40
+ readyScope = self.ready_to_run(worker.name, max_run_time)
46
41
 
47
42
  # 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
43
+ readyScope = readyScope.where('priority >= ?', Worker.min_priority) if Worker.min_priority
44
+ readyScope = readyScope.where('priority <= ?', Worker.max_priority) if Worker.max_priority
45
+ readyScope = readyScope.where(:queue => Worker.queues) if Worker.queues.any?
46
+ job = readyScope.by_priority.first
52
47
 
53
48
  now = self.db_time_now
54
49
 
55
- # Optimizations for faster lookups on some common databases
56
- case self.connection.adapter_name
57
- when "PostgreSQL"
58
- # Custom SQL required for PostgreSQL because postgres does not support UPDATE...LIMIT
59
- # 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
- # 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
- # 'FOR UPDATE' and we would have many locking conflicts
62
- quoted_table_name = self.connection.quote_table_name(self.table_name)
63
- 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])
65
- reserved[0]
66
- when "MySQL", "Mysql2"
67
- # This works on MySQL and possibly some other DBs that support UPDATE...LIMIT. It uses separate queries to lock and return the job
68
- count = ready_scope.limit(1).update_all(:locked_at => now, :locked_by => worker.name)
69
- return nil if count == 0
70
- self.where(:locked_at => now, :locked_by => worker.name).first
50
+ return unless job
51
+ job.with_lock do
52
+ job.locked_at = now
53
+ job.locked_by = worker.name
54
+ job.save!
55
+ end
56
+ job
57
+ end
58
+
59
+ # Lock this job for this worker.
60
+ # Returns true if we have the lock, false otherwise.
61
+ def lock_exclusively!(max_run_time, worker)
62
+ now = self.class.db_time_now
63
+ affected_rows = if locked_by != worker
64
+ # We don't own this job so we will update the locked_by name and the locked_at
65
+ self.class.update_all(["locked_at = ?, locked_by = ?", now, worker], ["id = ? and (locked_at is null or locked_at < ?) and (run_at <= ?)", id, (now - max_run_time.to_i), now])
66
+ else
67
+ # We already own this job, this may happen if the job queue crashes.
68
+ # Simply resume and update the locked_at
69
+ self.class.update_all(["locked_at = ?", now], ["id = ? and locked_by = ?", id, worker])
70
+ end
71
+ if affected_rows == 1
72
+ self.locked_at = now
73
+ self.locked_by = worker
74
+ self.changed_attributes.clear
75
+ return true
71
76
  else
72
- # This is our old fashion, tried and true, but slower lookup
73
- ready_scope.limit(worker.read_ahead).detect do |job|
74
- count = ready_scope.where(:id => job.id).update_all(:locked_at => now, :locked_by => worker.name)
75
- count == 1 && job.reload
76
- end
77
+ return false
77
78
  end
78
79
  end
79
80
 
@@ -43,21 +43,6 @@ describe Delayed::Backend::ActiveRecord::Job do
43
43
  end
44
44
  end
45
45
 
46
- context "ActiveRecord::Base.send(:attr_accessible, nil)" do
47
- before do
48
- Delayed::Backend::ActiveRecord::Job.send(:attr_accessible, nil)
49
- end
50
-
51
- after do
52
- Delayed::Backend::ActiveRecord::Job.send(:attr_accessible, *Delayed::Backend::ActiveRecord::Job.new.attributes.keys)
53
- end
54
-
55
- it "is still accessible" do
56
- job = Delayed::Backend::ActiveRecord::Job.enqueue :payload_object => EnqueueJobMod.new
57
- expect(Delayed::Backend::ActiveRecord::Job.find(job.id).handler).to_not be_blank
58
- end
59
- end
60
-
61
46
  context "ActiveRecord::Base.table_name_prefix" do
62
47
  it "when prefix is not set, use 'delayed_jobs' as table name" do
63
48
  ::ActiveRecord::Base.table_name_prefix = nil
@@ -49,7 +49,7 @@ class Story < ActiveRecord::Base
49
49
  self.primary_key = :story_id
50
50
  def tell; text; end
51
51
  def whatever(n, _); tell*n; end
52
- default_scope where(:scoped => true)
52
+ default_scope { where(:scoped => true) }
53
53
 
54
54
  handle_asynchronously :whatever
55
55
  end
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: delayed_job_active_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
5
- prerelease:
4
+ version: 4.0.0.beta1
5
+ prerelease: 6
6
6
  platform: ruby
7
7
  authors:
8
8
  - Brian Ryckbost
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2013-04-02 00:00:00.000000000 Z
14
+ date: 2013-03-02 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activerecord
@@ -20,10 +20,10 @@ dependencies:
20
20
  requirements:
21
21
  - - ! '>='
22
22
  - !ruby/object:Gem::Version
23
- version: 2.1.0
23
+ version: '3.0'
24
24
  - - <
25
25
  - !ruby/object:Gem::Version
26
- version: '4'
26
+ version: '4.1'
27
27
  type: :runtime
28
28
  prerelease: false
29
29
  version_requirements: !ruby/object:Gem::Requirement
@@ -31,10 +31,10 @@ dependencies:
31
31
  requirements:
32
32
  - - ! '>='
33
33
  - !ruby/object:Gem::Version
34
- version: 2.1.0
34
+ version: '3.0'
35
35
  - - <
36
36
  - !ruby/object:Gem::Version
37
- version: '4'
37
+ version: '4.1'
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: delayed_job
40
40
  requirement: !ruby/object:Gem::Requirement
@@ -42,7 +42,7 @@ dependencies:
42
42
  requirements:
43
43
  - - ~>
44
44
  - !ruby/object:Gem::Version
45
- version: '3.0'
45
+ version: 4.0.0.beta1
46
46
  type: :runtime
47
47
  prerelease: false
48
48
  version_requirements: !ruby/object:Gem::Requirement
@@ -50,7 +50,7 @@ dependencies:
50
50
  requirements:
51
51
  - - ~>
52
52
  - !ruby/object:Gem::Version
53
- version: '3.0'
53
+ version: 4.0.0.beta1
54
54
  description: ActiveRecord backend for Delayed::Job, originally authored by Tobias
55
55
  Lütke
56
56
  email:
@@ -91,16 +91,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
91
91
  version: '0'
92
92
  segments:
93
93
  - 0
94
- hash: 1565525879185101901
94
+ hash: 3791598084815033964
95
95
  required_rubygems_version: !ruby/object:Gem::Requirement
96
96
  none: false
97
97
  requirements:
98
- - - ! '>='
98
+ - - ! '>'
99
99
  - !ruby/object:Gem::Version
100
- version: '0'
101
- segments:
102
- - 0
103
- hash: 1565525879185101901
100
+ version: 1.3.1
104
101
  requirements: []
105
102
  rubyforge_project:
106
103
  rubygems_version: 1.8.25