delayed_job_mongo_mapper 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright © 2010 Andrew Timberlake
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,14 @@
1
+ # delayed_job MongoMapper backend
2
+
3
+ ## Installation
4
+
5
+ Add the gems to your Gemfile:
6
+
7
+ gem 'delayed_job'
8
+ gem 'delayed_job_mongo_mapper'
9
+
10
+ Create the indexes:
11
+
12
+ script/rails runner 'Delayed::Backend::MongoMapper::Job.create_indexes'
13
+
14
+ That's it. Use [delayed_job as normal](http://github.com/collectiveidea/delayed_job).
@@ -0,0 +1,91 @@
1
+ module Delayed
2
+ module Backend
3
+ module MongoMapper
4
+ class Job
5
+ include ::MongoMapper::Document
6
+ include Delayed::Backend::Base
7
+ set_collection_name 'delayed_jobs'
8
+
9
+ key :priority, Integer, :default => 0
10
+ key :attempts, Integer, :default => 0
11
+ key :handler, String
12
+ key :run_at, Time
13
+ key :locked_at, Time
14
+ key :locked_by, String #, :index => true
15
+ key :failed_at, Time
16
+ key :last_error, String
17
+ timestamps!
18
+
19
+ #ensure_index [[:priority, 1], [:run_at, 1]]
20
+
21
+ before_save :set_default_run_at
22
+
23
+ def self.before_fork
24
+ ::MongoMapper.connection.close
25
+ end
26
+
27
+ def self.after_fork
28
+ ::MongoMapper.connection.connect
29
+ end
30
+
31
+ def self.db_time_now
32
+ Time.now.utc
33
+ end
34
+
35
+ def self.find_available(worker_name, limit = 5, max_run_time = Worker.max_run_time)
36
+ right_now = db_time_now
37
+
38
+ conditions = {
39
+ :run_at => {"$lte" => right_now},
40
+ :limit => -limit, # In mongo, positive limits are 'soft' and negative are 'hard'
41
+ :failed_at => nil,
42
+ :sort => [[:priority, 1], [:run_at, 1]]
43
+ }
44
+
45
+ where = "this.locked_at == null || this.locked_at < #{make_date(right_now - max_run_time)}"
46
+
47
+ (conditions[:priority] ||= {})['$gte'] = Worker.min_priority.to_i if Worker.min_priority
48
+ (conditions[:priority] ||= {})['$lte'] = Worker.max_priority.to_i if Worker.max_priority
49
+
50
+ results = all(conditions.merge(:locked_by => worker_name))
51
+ results += all(conditions.merge('$where' => where)) if results.size < limit
52
+ results
53
+ end
54
+
55
+ # When a worker is exiting, make sure we don't have any locked jobs.
56
+ def self.clear_locks!(worker_name)
57
+ collection.update({:locked_by => worker_name}, {"$set" => {:locked_at => nil, :locked_by => nil}}, :multi => true)
58
+ end
59
+
60
+ # Lock this job for this worker.
61
+ # Returns true if we have the lock, false otherwise.
62
+ def lock_exclusively!(max_run_time, worker = worker_name)
63
+ right_now = self.class.db_time_now
64
+ overtime = right_now - max_run_time.to_i
65
+
66
+ query = "this.locked_at == null || this.locked_at < #{make_date(overtime)} || this.locked_by == #{worker.to_json}"
67
+ conditions = {:_id => id, :run_at => {"$lte" => right_now}, "$where" => query}
68
+
69
+ collection.update(conditions, {"$set" => {:locked_at => right_now, :locked_by => worker}})
70
+ affected_rows = self.collection.find({:_id => id, :locked_by => worker}).count
71
+ if affected_rows == 1
72
+ self.locked_at = right_now
73
+ self.locked_by = worker
74
+ return true
75
+ else
76
+ return false
77
+ end
78
+ end
79
+
80
+ private
81
+ def self.make_date(date_or_seconds)
82
+ "new Date(#{date_or_seconds.to_f * 1000})"
83
+ end
84
+
85
+ def make_date(date)
86
+ self.class.make_date(date)
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,14 @@
1
+ MongoMapper::Document.class_eval do
2
+ yaml_as "tag:ruby.yaml.org,2002:MongoMapper"
3
+
4
+ def self.yaml_new(klass, tag, val)
5
+ klass.find!(val['_id'])
6
+ rescue MongoMapper::DocumentNotFound
7
+ raise Delayed::DeserializationError
8
+ end
9
+
10
+ def to_yaml_properties
11
+ ['@_id']
12
+ end
13
+ end
14
+
@@ -0,0 +1,6 @@
1
+ require 'mongo_mapper'
2
+ require 'delayed_job'
3
+ require 'delayed/serialization/mongo_mapper'
4
+ require 'delayed/backend/mongo_mapper'
5
+
6
+ Delayed::Worker.backend = :mongo_mapper
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe Delayed::Backend::MongoMapper::Job do
4
+ it_should_behave_like 'a delayed_job backend'
5
+
6
+ describe "before_fork" do
7
+ after do
8
+ ::MongoMapper.connection.close
9
+ end
10
+
11
+ it "should disconnect" do
12
+ lambda do
13
+ Delayed::Backend::MongoMapper::Job.before_fork
14
+ end.should change { !!MongoMapper.connection.connected? }.from(true).to(false)
15
+ end
16
+ end
17
+
18
+ describe "after_fork" do
19
+ before do
20
+ ::MongoMapper.connection.close
21
+ end
22
+
23
+ it "should call reconnect" do
24
+ lambda do
25
+ Delayed::Backend::MongoMapper::Job.after_fork
26
+ end.should change { !!MongoMapper.connection.connected? }.from(false).to(true)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+ require 'rspec'
6
+ require 'delayed_job_mongo_mapper'
7
+ require 'delayed/backend/shared_spec'
8
+
9
+ MongoMapper.database = 'dl_spec'
10
+
11
+ class Story
12
+ include ::MongoMapper::Document
13
+
14
+ def tell; text; end
15
+ def whatever(n, _); tell*n; end
16
+ def self.count; end
17
+
18
+ handle_asynchronously :whatever
19
+ end
20
+
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: delayed_job_mongo_mapper
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Andrew Timberlake
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-11-24 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: mongo_mapper
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 51
30
+ segments:
31
+ - 0
32
+ - 8
33
+ - 6
34
+ version: 0.8.6
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: delayed_job
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 9
46
+ segments:
47
+ - 2
48
+ - 1
49
+ - 1
50
+ version: 2.1.1
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: rspec
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 2
64
+ - 0
65
+ version: "2.0"
66
+ type: :development
67
+ version_requirements: *id003
68
+ description:
69
+ email: andrew@andrewtimberlake.com
70
+ executables: []
71
+
72
+ extensions: []
73
+
74
+ extra_rdoc_files:
75
+ - LICENSE
76
+ - README.md
77
+ files:
78
+ - lib/delayed_job_mongo_mapper.rb
79
+ - lib/delayed/backend/mongo_mapper.rb
80
+ - lib/delayed/serialization/mongo_mapper.rb
81
+ - spec/spec.opts
82
+ - spec/delayed_job_mongo_mapper_spec.rb
83
+ - spec/spec_helper.rb
84
+ - LICENSE
85
+ - README.md
86
+ has_rdoc: true
87
+ homepage: http://github.com/andrewtimberlake/delayed_job_mongo_mapper
88
+ licenses: []
89
+
90
+ post_install_message:
91
+ rdoc_options:
92
+ - --charset=UTF-8
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ hash: 3
101
+ segments:
102
+ - 0
103
+ version: "0"
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ hash: 3
110
+ segments:
111
+ - 0
112
+ version: "0"
113
+ requirements: []
114
+
115
+ rubyforge_project:
116
+ rubygems_version: 1.3.7
117
+ signing_key:
118
+ specification_version: 3
119
+ summary: MongoMapper backend for delayed_job
120
+ test_files:
121
+ - spec/spec.opts
122
+ - spec/delayed_job_mongo_mapper_spec.rb
123
+ - spec/spec_helper.rb