delayed_job_active_record 4.0.0.beta1 → 4.0.0.beta2

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.
@@ -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 = '4.0.0.beta1'
18
+ spec.version = '4.0.0.beta2'
19
19
  end
@@ -37,44 +37,38 @@ module Delayed
37
37
 
38
38
  def self.reserve(worker, max_run_time = Worker.max_run_time)
39
39
  # scope to filter to records that are "ready to run"
40
- readyScope = self.ready_to_run(worker.name, max_run_time)
40
+ ready_scope = self.ready_to_run(worker.name, max_run_time)
41
41
 
42
42
  # scope to filter to the single next eligible job
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
43
+ ready_scope = ready_scope.where('priority >= ?', Worker.min_priority) if Worker.min_priority
44
+ ready_scope = ready_scope.where('priority <= ?', Worker.max_priority) if Worker.max_priority
45
+ ready_scope = ready_scope.where(:queue => Worker.queues) if Worker.queues.any?
46
+ ready_scope = ready_scope.by_priority
47
47
 
48
48
  now = self.db_time_now
49
49
 
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
50
+ # Optimizations for faster lookups on some common databases
51
+ case self.connection.adapter_name
52
+ when "PostgreSQL"
53
+ # Custom SQL required for PostgreSQL because postgres does not support UPDATE...LIMIT
54
+ # 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)
55
+ # Note: active_record would attempt to generate UPDATE...LIMIT like sql for postgres if we use a .limit() filter, but it would not use
56
+ # 'FOR UPDATE' and we would have many locking conflicts
57
+ quoted_table_name = self.connection.quote_table_name(self.table_name)
58
+ subquery_sql = ready_scope.limit(1).lock(true).select('id').to_sql
59
+ reserved = self.find_by_sql(["UPDATE #{quoted_table_name} SET locked_at = ?, locked_by = ? WHERE id IN (#{subquery_sql}) RETURNING *", now, worker.name])
60
+ reserved[0]
61
+ when "MySQL", "Mysql2"
62
+ # This works on MySQL and possibly some other DBs that support UPDATE...LIMIT. It uses separate queries to lock and return the job
63
+ count = ready_scope.limit(1).update_all(:locked_at => now, :locked_by => worker.name)
64
+ return nil if count == 0
65
+ self.where(:locked_at => now, :locked_by => worker.name).first
76
66
  else
77
- return false
67
+ # This is our old fashion, tried and true, but slower lookup
68
+ ready_scope.limit(worker.read_ahead).detect do |job|
69
+ count = ready_scope.where(:id => job.id).update_all(:locked_at => now, :locked_by => worker.name)
70
+ count == 1 && job.reload
71
+ end
78
72
  end
79
73
  end
80
74
 
@@ -1,17 +1,20 @@
1
1
  require 'generators/delayed_job/delayed_job_generator'
2
2
  require 'rails/generators/migration'
3
- require 'rails/generators/active_record/migration'
3
+ require 'rails/generators/active_record'
4
4
 
5
5
  # Extend the DelayedJobGenerator so that it creates an AR migration
6
6
  module DelayedJob
7
7
  class ActiveRecordGenerator < ::DelayedJobGenerator
8
8
  include Rails::Generators::Migration
9
- extend ActiveRecord::Generators::Migration
10
9
 
11
10
  self.source_paths << File.join(File.dirname(__FILE__), 'templates')
12
11
 
13
12
  def create_migration_file
14
13
  migration_template 'migration.rb', 'db/migrate/create_delayed_jobs.rb'
15
14
  end
15
+
16
+ def self.next_migration_number dirname
17
+ ActiveRecord::Generators::Base.next_migration_number dirname
18
+ end
16
19
  end
17
20
  end
@@ -1,17 +1,20 @@
1
1
  require 'generators/delayed_job/delayed_job_generator'
2
2
  require 'rails/generators/migration'
3
- require 'rails/generators/active_record/migration'
3
+ require 'rails/generators/active_record'
4
4
 
5
5
  # Extend the DelayedJobGenerator so that it creates an AR migration
6
6
  module DelayedJob
7
7
  class UpgradeGenerator < ::DelayedJobGenerator
8
8
  include Rails::Generators::Migration
9
- extend ActiveRecord::Generators::Migration
10
9
 
11
10
  self.source_paths << File.join(File.dirname(__FILE__), 'templates')
12
11
 
13
12
  def create_migration_file
14
13
  migration_template 'upgrade_migration.rb', 'db/migrate/add_queue_to_delayed_jobs.rb'
15
14
  end
15
+
16
+ def self.next_migration_number dirname
17
+ ActiveRecord::Generators::Base.next_migration_number dirname
18
+ end
16
19
  end
17
20
  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.0.beta1
4
+ version: 4.0.0.beta2
5
5
  prerelease: 6
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: 2013-03-02 00:00:00.000000000 Z
14
+ date: 2013-04-02 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activerecord
@@ -91,7 +91,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
91
91
  version: '0'
92
92
  segments:
93
93
  - 0
94
- hash: 3791598084815033964
94
+ hash: 1966467636289984878
95
95
  required_rubygems_version: !ruby/object:Gem::Requirement
96
96
  none: false
97
97
  requirements: