Permalink
Browse files

Merge remote branch 'moneypools/master'

* moneypools/master:
  Bugfix: No update_attribute in mongo_mapper
  Pushing new gemspec to make bundler happier
  Adding very important indexes. Can't believe I forgot them
  Updating MongoMapper backend
  Updates to the backend test structure

Conflicts:
	delayed_job.gemspec
  • Loading branch information...
2 parents 8125b2a + 32ead61 commit 980cb220b8cde488bfc432746bb8f8c8d1be6a94 @bkeepers bkeepers committed Mar 25, 2010
View
@@ -51,7 +51,7 @@ You can change the backend in an initializer:
<pre>
# config/initializers/delayed_job.rb
-Delayed::Worker.backend = :mongo
+Delayed::Worker.backend = :mongo_mapper
</pre>
h2. Upgrading to 1.8
View
@@ -32,7 +32,7 @@ task :default => :spec
desc 'Run the specs'
Spec::Rake::SpecTask.new(:spec) do |t|
t.libs << 'lib'
- t.pattern = 'spec/**/*_spec.rb'
+ t.pattern = 'spec/*_spec.rb'
t.verbose = true
end
task :spec => :check_dependencies
View
@@ -5,11 +5,11 @@
Gem::Specification.new do |s|
s.name = %q{delayed_job}
- s.version = "1.8.5"
+ s.version = "1.8.4"
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Brandon Keepers", "Tobias L\303\274tke"]
- s.date = %q{2010-03-15}
+ s.date = %q{2010-03-25}
s.description = %q{Delayed_job (or DJ) encapsulates the common pattern of asynchronously executing longer tasks in the background. It is a direct extraction from Shopify where the job table is responsible for a multitude of core tasks.}
s.email = %q{tobi@leetsoft.com}
s.extra_rdoc_files = [
@@ -27,17 +27,29 @@ Gem::Specification.new do |s|
"generators/delayed_job/templates/migration.rb",
"generators/delayed_job/templates/script",
"init.rb",
+ "lib/delayed/backend/active_record.rb",
+ "lib/delayed/backend/base.rb",
+ "lib/delayed/backend/mongo_mapper.rb",
"lib/delayed/command.rb",
"lib/delayed/message_sending.rb",
"lib/delayed/performable_method.rb",
"lib/delayed/recipes.rb",
"lib/delayed/tasks.rb",
"lib/delayed/worker.rb",
"lib/delayed_job.rb",
+ "moneypools-delayed_job.gemspec",
"recipes/delayed_job.rb",
+ "spec/backend/active_record_job_spec.rb",
+ "spec/backend/mongo_mapper_job_spec.rb",
+ "spec/backend/shared_backend_spec.rb",
"spec/delayed_method_spec.rb",
- "spec/job_spec.rb",
+ "spec/performable_method_spec.rb",
+ "spec/sample_jobs.rb",
+ "spec/setup/active_record.rb",
+ "spec/setup/mongo_mapper.rb",
+ "spec/spec_helper.rb",
"spec/story_spec.rb",
+ "spec/worker_spec.rb",
"tasks/jobs.rake"
]
s.homepage = %q{http://github.com/collectiveidea/delayed_job}
@@ -46,20 +58,38 @@ Gem::Specification.new do |s|
s.rubygems_version = %q{1.3.5}
s.summary = %q{Database-backed asynchronous priority queue system -- Extracted from Shopify}
s.test_files = [
- "spec/database.rb",
+ "spec/backend",
+ "spec/backend/active_record_job_spec.rb",
+ "spec/backend/mongo_mapper_job_spec.rb",
+ "spec/backend/shared_backend_spec.rb",
"spec/delayed_method_spec.rb",
- "spec/job_spec.rb",
- "spec/story_spec.rb"
+ "spec/performable_method_spec.rb",
+ "spec/sample_jobs.rb",
+ "spec/setup",
+ "spec/setup/active_record.rb",
+ "spec/setup/mongo_mapper.rb",
+ "spec/spec_helper.rb",
+ "spec/story_spec.rb",
+ "spec/worker_spec.rb"
]
if s.respond_to? :specification_version then
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
s.specification_version = 3
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
+ s.add_runtime_dependency(%q<daemons>, [">= 0"])
+ s.add_development_dependency(%q<rspec>, [">= 0"])
+ s.add_development_dependency(%q<sqlite3-ruby>, [">= 0"])
else
+ s.add_dependency(%q<daemons>, [">= 0"])
+ s.add_dependency(%q<rspec>, [">= 0"])
+ s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
end
else
+ s.add_dependency(%q<daemons>, [">= 0"])
+ s.add_dependency(%q<rspec>, [">= 0"])
+ s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
end
end
@@ -81,4 +81,4 @@ def self.db_time_now
end
end
end
-end
+end
@@ -1,6 +1,6 @@
require 'mongo_mapper'
-module MongoMapper
+module ::MongoMapper
module Document
module ClassMethods
def load_for_delayed_job(id)
@@ -18,9 +18,9 @@ def dump_for_delayed_job
module Delayed
module Backend
- module Mongo
+ module MongoMapper
class Job
- include MongoMapper::Document
+ include ::MongoMapper::Document
include Delayed::Backend::Base
set_collection_name 'delayed_jobs'
@@ -29,32 +29,37 @@ class Job
key :handler, String
key :run_at, Time
key :locked_at, Time
- key :locked_by, String
+ key :locked_by, String, :index => true
key :failed_at, Time
key :last_error, String
timestamps!
before_save :set_default_run_at
+
+ ensure_index [[:priority, 1], [:run_at, 1]]
def self.db_time_now
- MongoMapper.time_class.now.utc
+ ::MongoMapper.time_class.now.utc
end
def self.find_available(worker_name, limit = 5, max_run_time = Worker.max_run_time)
- where = "this.run_at <= new Date(#{db_time_now.to_f * 1000}) && (this.locked_at == null || this.locked_at < new Date(#{(db_time_now - max_run_time).to_f * 1000})) || this.locked_by == #{worker_name.to_json}"
- # all(:limit => limit, :failed_at => nil, '$where' => where)
-
+ right_now = db_time_now
+
conditions = {
- '$where' => where,
- :limit => limit,
+ :run_at => {"$lte" => right_now},
+ :limit => -limit, # In mongo, positive limits are 'soft' and negative are 'hard'
:failed_at => nil,
:sort => [['priority', 1], ['run_at', 1]]
}
+
+ where = "this.locked_at == null || this.locked_at < #{make_date(right_now - max_run_time)}"
- # (conditions[:priority] ||= {})['$gte'] = Worker.min_priority if Worker.min_priority
- # (conditions[:priority] ||= {})['$lte'] = Worker.max_priority if Worker.max_priority
+ (conditions[:priority] ||= {})['$gte'] = Worker.min_priority if Worker.min_priority
+ (conditions[:priority] ||= {})['$lte'] = Worker.max_priority if Worker.max_priority
- all(conditions)
+ results = all(conditions.merge(:locked_by => worker_name))
+ results += all(conditions.merge('$where' => where)) if results.size < limit
+ results
end
# When a worker is exiting, make sure we don't have any locked jobs.
@@ -65,16 +70,16 @@ def self.clear_locks!(worker_name)
# Lock this job for this worker.
# Returns true if we have the lock, false otherwise.
def lock_exclusively!(max_run_time, worker = worker_name)
- now = self.class.db_time_now
- overtime = make_date(now - max_run_time.to_i)
+ right_now = self.class.db_time_now
+ overtime = right_now - max_run_time.to_i
- query = "this._id == #{id.to_json} && this.run_at <= #{make_date(now)} && (this.locked_at == null || this.locked_at < #{overtime} || this.locked_by == #{worker.to_json})"
+ query = "this.locked_at == null || this.locked_at < #{make_date(overtime)} || this.locked_by == #{worker.to_json}"
+ conditions = {:_id => id, :run_at => {"$lte" => right_now}, "$where" => query}
- conditions = {"$where" => make_query(query)}
- collection.update(conditions, {"$set" => {:locked_at => now, :locked_by => worker}}, :multi => true)
+ collection.update(conditions, {"$set" => {:locked_at => right_now, :locked_by => worker}})
affected_rows = collection.find({:_id => id, :locked_by => worker}).count
if affected_rows == 1
- self.locked_at = now
+ self.locked_at = right_now
self.locked_by = worker
return true
else
@@ -84,27 +89,18 @@ def lock_exclusively!(max_run_time, worker = worker_name)
private
- def self.make_date(date)
- "new Date(#{date.to_f * 1000})"
+ def self.make_date(date_or_seconds)
+ "new Date(#{date_or_seconds.to_f * 1000})"
end
def make_date(date)
self.class.make_date(date)
end
- def self.make_query(string)
- "function() { return (#{string}); }"
- end
-
- def make_query(string)
- self.class.make_query(string)
- end
-
-
def set_default_run_at
self.run_at ||= self.class.db_time_now
end
end
end
end
-end
+end
@@ -59,4 +59,4 @@ def dump(obj)
end
end
end
-end
+end
View
@@ -126,7 +126,7 @@ def reschedule(job, time = nil)
job.save!
else
say "* [JOB] PERMANENTLY removing #{job.name} because of #{job.attempts} consecutive failures.", Logger::INFO
- self.class.destroy_failed_jobs ? job.destroy : job.update_attribute(:failed_at, Delayed::Job.db_time_now)
+ self.class.destroy_failed_jobs ? job.destroy : job.update_attributes(:failed_at => Delayed::Job.db_time_now)
end
end
View
@@ -1,3 +1,5 @@
+require 'active_support'
+
require File.dirname(__FILE__) + '/delayed/message_sending'
require File.dirname(__FILE__) + '/delayed/performable_method'
require File.dirname(__FILE__) + '/delayed/backend/base'
@@ -6,7 +8,14 @@
Object.send(:include, Delayed::MessageSending)
Module.send(:include, Delayed::MessageSending::ClassMethods)
-Delayed::Worker.backend = :active_record
+if defined?(ActiveRecord)
+ Delayed::Worker.backend = :active_record
+elsif defined?(MongoMapper)
+ Delayed::Worker.backend = :mongo_mapper
+else
+ $stderr.puts "Could not decide on a backend, defaulting to active_record"
+ Delayed::Worker.backend = :active_record
+end
if defined?(Merb::Plugins)
Merb::Plugins.add_rakefiles File.dirname(__FILE__) / 'delayed' / 'tasks'
@@ -0,0 +1,94 @@
+# Generated by jeweler
+# DO NOT EDIT THIS FILE DIRECTLY
+# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
+# -*- encoding: utf-8 -*-
+
+Gem::Specification.new do |s|
+ s.name = %q{moneypools-delayed_job}
+ s.version = "1.8.4"
+
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
+ s.authors = ["Brandon Keepers", "Tobias L\303\274tke"]
+ s.date = %q{2010-02-23}
+ s.description = %q{Delayed_job (or DJ) encapsulates the common pattern of asynchronously executing longer tasks in the background. It is a direct extraction from Shopify where the job table is responsible for a multitude of core tasks.}
+ s.email = %q{tobi@leetsoft.com}
+ s.extra_rdoc_files = [
+ "README.textile"
+ ]
+ s.files = [
+ ".gitignore",
+ "MIT-LICENSE",
+ "README.textile",
+ "Rakefile",
+ "VERSION",
+ "contrib/delayed_job.monitrc",
+ "delayed_job.gemspec",
+ "generators/delayed_job/delayed_job_generator.rb",
+ "generators/delayed_job/templates/migration.rb",
+ "generators/delayed_job/templates/script",
+ "init.rb",
+ "lib/delayed/backend/active_record.rb",
+ "lib/delayed/backend/base.rb",
+ "lib/delayed/backend/mongo_mapper.rb",
+ "lib/delayed/command.rb",
+ "lib/delayed/message_sending.rb",
+ "lib/delayed/performable_method.rb",
+ "lib/delayed/recipes.rb",
+ "lib/delayed/tasks.rb",
+ "lib/delayed/worker.rb",
+ "lib/delayed_job.rb",
+ "recipes/delayed_job.rb",
+ "spec/backend/active_record_job_spec.rb",
+ "spec/backend/mongo_mapper_job_spec.rb",
+ "spec/backend/shared_backend_spec.rb",
+ "spec/delayed_method_spec.rb",
+ "spec/performable_method_spec.rb",
+ "spec/sample_jobs.rb",
+ "spec/setup/active_record.rb",
+ "spec/setup/mongo_mapper.rb",
+ "spec/spec_helper.rb",
+ "spec/story_spec.rb",
+ "spec/worker_spec.rb",
+ "tasks/jobs.rake"
+ ]
+ s.homepage = %q{http://github.com/collectiveidea/delayed_job}
+ s.rdoc_options = ["--main", "README.textile", "--inline-source", "--line-numbers"]
+ s.require_paths = ["lib"]
+ s.rubygems_version = %q{1.3.6}
+ s.summary = %q{Database-backed asynchronous priority queue system -- Extracted from Shopify}
+ s.test_files = [
+ "spec/backend",
+ "spec/backend/active_record_job_spec.rb",
+ "spec/backend/mongo_mapper_job_spec.rb",
+ "spec/backend/shared_backend_spec.rb",
+ "spec/delayed_method_spec.rb",
+ "spec/performable_method_spec.rb",
+ "spec/sample_jobs.rb",
+ "spec/setup",
+ "spec/setup/active_record.rb",
+ "spec/setup/mongo_mapper.rb",
+ "spec/spec_helper.rb",
+ "spec/story_spec.rb",
+ "spec/worker_spec.rb"
+ ]
+
+ if s.respond_to? :specification_version then
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
+ s.specification_version = 3
+
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
+ s.add_runtime_dependency(%q<daemons>, [">= 0"])
+ s.add_development_dependency(%q<rspec>, [">= 0"])
+ s.add_development_dependency(%q<sqlite3-ruby>, [">= 0"])
+ else
+ s.add_dependency(%q<daemons>, [">= 0"])
+ s.add_dependency(%q<rspec>, [">= 0"])
+ s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
+ end
+ else
+ s.add_dependency(%q<daemons>, [">= 0"])
+ s.add_dependency(%q<rspec>, [">= 0"])
+ s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
+ end
+end
+
@@ -1,4 +1,5 @@
require 'spec_helper'
+require 'delayed/backend/active_record'
describe Delayed::Job do
before(:all) do
Oops, something went wrong.

0 comments on commit 980cb22

Please sign in to comment.