mongojob 0.0.1
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.
- data/LICENSE +20 -0
- data/README.md +29 -0
- data/Rakefile +5 -0
- data/bin/mongojob-cli +0 -0
- data/bin/mongojob-deamon +9 -0
- data/bin/mongojob-web +15 -0
- data/bin/mongojob-worker +9 -0
- data/lib/mongojob.rb +69 -0
- data/lib/mongojob/deamon.rb +17 -0
- data/lib/mongojob/helpers.rb +32 -0
- data/lib/mongojob/job.rb +63 -0
- data/lib/mongojob/mixins/document.rb +13 -0
- data/lib/mongojob/mixins/fiber_runner.rb +51 -0
- data/lib/mongojob/model/job.rb +121 -0
- data/lib/mongojob/model/queue.rb +16 -0
- data/lib/mongojob/model/worker.rb +35 -0
- data/lib/mongojob/version.rb +3 -0
- data/lib/mongojob/web.rb +80 -0
- data/lib/mongojob/web/helpers.rb +46 -0
- data/lib/mongojob/worker.rb +370 -0
- data/lib/mongojob/worker_helpers.rb +5 -0
- data/spec/mongojob/job_spec.rb +32 -0
- data/spec/mongojob/model/job_spec.rb +61 -0
- data/spec/mongojob/worker_spec.rb +101 -0
- data/spec/mongojob_spec.rb +58 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +47 -0
- data/tasks/spec.rb +16 -0
- metadata +167 -0
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../spec_helper.rb')
|
2
|
+
|
3
|
+
describe "MongoJob" do
|
4
|
+
describe "Job" do
|
5
|
+
|
6
|
+
it "should properly set self.@threading value" do
|
7
|
+
class ForkJob < MongoJob::Job
|
8
|
+
threading :fork
|
9
|
+
end
|
10
|
+
|
11
|
+
class FiberJob < MongoJob::Job
|
12
|
+
threading :fiber
|
13
|
+
end
|
14
|
+
|
15
|
+
class NonForkJob < MongoJob::Job
|
16
|
+
threading false
|
17
|
+
end
|
18
|
+
|
19
|
+
ForkJob.fork?.should == true
|
20
|
+
ForkJob.fiber?.should == false
|
21
|
+
FiberJob.fork?.should == false
|
22
|
+
FiberJob.fiber?.should == true
|
23
|
+
NonForkJob.fork?.should == false
|
24
|
+
NonForkJob.fiber?.should == false
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should run a job" do
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../../spec_helper.rb')
|
2
|
+
|
3
|
+
class FakeJob < MongoJob::Job
|
4
|
+
|
5
|
+
def perform
|
6
|
+
puts "hello"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "MongoJob" do
|
11
|
+
describe "Model" do
|
12
|
+
describe "Job" do
|
13
|
+
|
14
|
+
it "should properly create job objects" do
|
15
|
+
job = MongoJob::Model::Job.create({
|
16
|
+
klass: 'FakeJob',
|
17
|
+
options: {a: 1}
|
18
|
+
})
|
19
|
+
job.klass.should == 'FakeJob'
|
20
|
+
job.job_class.to_s.should == 'FakeJob'
|
21
|
+
job.job_object.class.to_s.should == 'FakeJob'
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#at' do
|
25
|
+
it "should set percentage progress with at(percent)" do
|
26
|
+
job_id = MongoJob.enqueue FooProcessor
|
27
|
+
job = MongoJob.find_job job_id
|
28
|
+
job.at 0.24
|
29
|
+
job = MongoJob.find_job job_id
|
30
|
+
job.percent_done.should == 0.24
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should set percentage progress with at(at, total)" do
|
34
|
+
job_id = MongoJob.enqueue FooProcessor
|
35
|
+
job = MongoJob.find_job job_id
|
36
|
+
job.at 24, 100
|
37
|
+
job = MongoJob.find_job job_id
|
38
|
+
job.percent_done.should == 0.24
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should set custom progress and status" do
|
42
|
+
job_id = MongoJob.enqueue FooProcessor
|
43
|
+
job = MongoJob.find_job job_id
|
44
|
+
job.at 24, 100, status: {foo: 'bar'}
|
45
|
+
job = MongoJob.find_job job_id
|
46
|
+
job.custom_status['foo'].should == 'bar'
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should set custom progress without status" do
|
50
|
+
job_id = MongoJob.enqueue FooProcessor
|
51
|
+
job = MongoJob.find_job job_id
|
52
|
+
job.at status: {foo: 'bar'}
|
53
|
+
job = MongoJob.find_job job_id
|
54
|
+
job.custom_status['foo'].should == 'bar'
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../spec_helper.rb')
|
2
|
+
|
3
|
+
describe "MongoJob" do
|
4
|
+
describe "Worker" do
|
5
|
+
it "should have a unique id" do
|
6
|
+
worker = MongoJob::Worker.new(:queue)
|
7
|
+
worker.id.should =~ /^[a-z0-9\-_\.]+:[0-9]+$/i
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should fetch new jobs" do
|
11
|
+
worker = MongoJob::Worker.new(:queue)
|
12
|
+
fooworker = MongoJob::Worker.new(:fooqueue)
|
13
|
+
MongoJob.enqueue(FooProcessor, {a: 1, b:2})
|
14
|
+
|
15
|
+
|
16
|
+
job = worker.get_new_job
|
17
|
+
job.should == nil
|
18
|
+
|
19
|
+
job = fooworker.get_new_job
|
20
|
+
job.options['a'].should == 1
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should fetch new jobs in order of its defined queues" do
|
24
|
+
worker = MongoJob::Worker.new(:fooqueue, :barqueue, max_jobs: 4)
|
25
|
+
MongoJob.enqueue(FooProcessor, {a: 1})
|
26
|
+
MongoJob.enqueue(BarProcessor, {a: 2})
|
27
|
+
MongoJob.enqueue(FooProcessor, {a: 3})
|
28
|
+
MongoJob.enqueue(BarProcessor, {a: 4})
|
29
|
+
|
30
|
+
1.upto(4) do |i|
|
31
|
+
job = worker.get_new_job
|
32
|
+
job.queue_name.should == 'fooqueue' if i <= 2
|
33
|
+
job.queue_name.should == 'barqueue' if i > 2
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should tick with its worker data" do
|
38
|
+
worker = MongoJob::Worker.new(:fooqueue)
|
39
|
+
worker.tick
|
40
|
+
|
41
|
+
# Database should have a record with the tick data
|
42
|
+
MongoJob::Model::Worker.all.should have(1).worker
|
43
|
+
worker1 = MongoJob::Model::Worker.all.first
|
44
|
+
worker1.id.should == worker.id
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should run fibers when told so" do
|
48
|
+
worker = MongoJob::Worker.new(:fooqueue)
|
49
|
+
counter = 0
|
50
|
+
EM.run do
|
51
|
+
EM.add_timer(5){EM.stop} # stop after 5 seconds
|
52
|
+
worker.run_em_fiber(1) do
|
53
|
+
counter += 1
|
54
|
+
end
|
55
|
+
end
|
56
|
+
counter.should >= 4
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should run defined jobs without errors" do
|
60
|
+
EM.run do
|
61
|
+
EM.add_timer(5){EM.stop} # stop after 5 seconds
|
62
|
+
worker = MongoJob::Worker.new(:fooqueue)
|
63
|
+
worker.run_defined_tasks
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should fork" do
|
68
|
+
worker = MongoJob::Worker.new(:fooqueue)
|
69
|
+
worker.fork do
|
70
|
+
puts "anything"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should actully run a job" do
|
75
|
+
# real_job = RealJob.new({'file_name' => 'test_file'})
|
76
|
+
# real_job.perform
|
77
|
+
# content = ''
|
78
|
+
# ::File.open(::File.join(TEST_DIR, 'test_file'), 'r') do |f|
|
79
|
+
# content = f.read
|
80
|
+
# end
|
81
|
+
# content.should == 'this actually worked'
|
82
|
+
# ::File.unlink(::File.join(TEST_DIR, 'test_file'))
|
83
|
+
|
84
|
+
worker = MongoJob::Worker.new(:realjob)
|
85
|
+
MongoJob.enqueue(RealJob)
|
86
|
+
pid = Process.fork do
|
87
|
+
worker.run
|
88
|
+
end
|
89
|
+
sleep 3
|
90
|
+
Process.kill "KILL", pid
|
91
|
+
content = ''
|
92
|
+
::File.open(::File.join(TEST_DIR, 'test_file'), 'r') do |f|
|
93
|
+
content = f.read
|
94
|
+
end
|
95
|
+
content.should == 'this actually worked'
|
96
|
+
|
97
|
+
# Wow, at this point we have a nice working job processor!
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '/spec_helper.rb')
|
2
|
+
|
3
|
+
|
4
|
+
describe "MongoJob" do
|
5
|
+
it "should put jobs on the queue" do
|
6
|
+
|
7
|
+
MongoJob.enqueue(FooProcessor, {a: 1, b:2})
|
8
|
+
|
9
|
+
MongoJob::Model::Job.all.size.should == 1
|
10
|
+
MongoJob::Model::Queue.all.size.should == 1
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should reserve jobs from the queue" do
|
14
|
+
MongoJob.enqueue(FooProcessor, {a: 1, b:2})
|
15
|
+
worker_id = 'my_worker_id'
|
16
|
+
job = MongoJob.reserve(:fooqueue, worker_id)
|
17
|
+
job.klass.should == 'FooProcessor'
|
18
|
+
job.options['a'].should == 1
|
19
|
+
job.options['b'].should == 2
|
20
|
+
job.queue_name.should == 'fooqueue'
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should find jobs by job_id" do
|
24
|
+
job_id = MongoJob.enqueue FooProcessor
|
25
|
+
job = MongoJob.find_job job_id
|
26
|
+
job.should_not == nil
|
27
|
+
job.id.to_s.should == job_id
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should put and get jobs in FIFO order" do
|
31
|
+
MongoJob.enqueue(FooProcessor, {a: 0}); sleep 1
|
32
|
+
MongoJob.enqueue(FooProcessor, {a: 1}); sleep 1
|
33
|
+
MongoJob.enqueue(FooProcessor, {a: 2}); sleep 1
|
34
|
+
MongoJob.enqueue(FooProcessor, {a: 3}); sleep 1
|
35
|
+
MongoJob.enqueue(FooProcessor, {a: 4}); sleep 1
|
36
|
+
|
37
|
+
worker_id = 'my_worker_id'
|
38
|
+
0.upto(4).each do |i|
|
39
|
+
job = MongoJob.reserve(:fooqueue, worker_id)
|
40
|
+
job.options['a'].should == i
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should remove jobs from the queue" do
|
45
|
+
job_id = MongoJob.enqueue(FooProcessor, {a: 2})
|
46
|
+
MongoJob.dequeue(job_id)
|
47
|
+
MongoJob::Model::Job.all.size.should == 0
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should extract queue name from worker class" do
|
51
|
+
|
52
|
+
MongoJob.queue_from_class(FooProcessor).should == :fooqueue
|
53
|
+
MongoJob.queue_from_class(BarProcessor).should == :barqueue
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require "spec"
|
2
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
3
|
+
ENV["RACK_ENV"] = ENV["ENVIRONMENT"] = "test"
|
4
|
+
|
5
|
+
require "mongojob"
|
6
|
+
|
7
|
+
class FooProcessor < MongoJob::Job
|
8
|
+
queue :fooqueue
|
9
|
+
def perform
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class BarProcessor < MongoJob::Job
|
15
|
+
queue :barqueue
|
16
|
+
|
17
|
+
def perform
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class RealJob < MongoJob::Job
|
22
|
+
queue :realjob
|
23
|
+
threading :fiber
|
24
|
+
|
25
|
+
def perform
|
26
|
+
::File.open(::File.join(TEST_DIR, 'test_file'), 'w') do |f|
|
27
|
+
f.write "this actually worked"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
Spec::Runner.configure do |config|
|
33
|
+
config.before(:all) do
|
34
|
+
::TEST_DIR = File.expand_path(File.dirname(__FILE__) + '/../tmp/test') unless defined? TEST_DIR
|
35
|
+
FileUtils::mkdir_p TEST_DIR
|
36
|
+
|
37
|
+
MongoJob.database_name = 'mongojob-test'
|
38
|
+
end
|
39
|
+
config.before(:each) do
|
40
|
+
FileUtils::rm_r Dir["#{TEST_DIR}/*"]
|
41
|
+
|
42
|
+
# Remove collections
|
43
|
+
MongoJob::Model::Queue.collection.remove
|
44
|
+
MongoJob::Model::Job.collection.remove
|
45
|
+
MongoJob::Model::Worker.collection.remove
|
46
|
+
end
|
47
|
+
end
|
data/tasks/spec.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec/rake/spectask'
|
2
|
+
|
3
|
+
desc "Run the specs under spec"
|
4
|
+
Spec::Rake::SpecTask.new do |t|
|
5
|
+
t.spec_opts = ['--options', "spec/spec.opts"]
|
6
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
7
|
+
end
|
8
|
+
|
9
|
+
namespace :spec do
|
10
|
+
desc "Run specs with RCov"
|
11
|
+
Spec::Rake::SpecTask.new('rcov') do |t|
|
12
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
13
|
+
t.rcov = true
|
14
|
+
t.rcov_opts = ['--exclude', '\/Library\/Ruby']
|
15
|
+
end
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mongojob
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Michal Frackowiak
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-06-01 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: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: eventmachine
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :runtime
|
48
|
+
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: sinatra
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
type: :runtime
|
62
|
+
version_requirements: *id003
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: haml
|
65
|
+
prerelease: false
|
66
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
hash: 3
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
version: "0"
|
75
|
+
type: :runtime
|
76
|
+
version_requirements: *id004
|
77
|
+
- !ruby/object:Gem::Dependency
|
78
|
+
name: vegas
|
79
|
+
prerelease: false
|
80
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
hash: 3
|
86
|
+
segments:
|
87
|
+
- 0
|
88
|
+
version: "0"
|
89
|
+
type: :runtime
|
90
|
+
version_requirements: *id005
|
91
|
+
description: " MongoJob is a MongoDB-backed Ruby library for creating background jobs,\n placing those jobs on multiple queues, and processing them later.\n"
|
92
|
+
email: michalf@openlabs.pl
|
93
|
+
executables:
|
94
|
+
- mongojob-cli
|
95
|
+
- mongojob-web
|
96
|
+
- mongojob-deamon
|
97
|
+
- mongojob-worker
|
98
|
+
extensions: []
|
99
|
+
|
100
|
+
extra_rdoc_files:
|
101
|
+
- LICENSE
|
102
|
+
- README.md
|
103
|
+
files:
|
104
|
+
- README.md
|
105
|
+
- Rakefile
|
106
|
+
- LICENSE
|
107
|
+
- lib/mongojob/deamon.rb
|
108
|
+
- lib/mongojob/helpers.rb
|
109
|
+
- lib/mongojob/job.rb
|
110
|
+
- lib/mongojob/mixins/document.rb
|
111
|
+
- lib/mongojob/mixins/fiber_runner.rb
|
112
|
+
- lib/mongojob/model/job.rb
|
113
|
+
- lib/mongojob/model/queue.rb
|
114
|
+
- lib/mongojob/model/worker.rb
|
115
|
+
- lib/mongojob/version.rb
|
116
|
+
- lib/mongojob/web/helpers.rb
|
117
|
+
- lib/mongojob/web.rb
|
118
|
+
- lib/mongojob/worker.rb
|
119
|
+
- lib/mongojob/worker_helpers.rb
|
120
|
+
- lib/mongojob.rb
|
121
|
+
- bin/mongojob-cli
|
122
|
+
- bin/mongojob-deamon
|
123
|
+
- bin/mongojob-web
|
124
|
+
- bin/mongojob-worker
|
125
|
+
- spec/mongojob/job_spec.rb
|
126
|
+
- spec/mongojob/model/job_spec.rb
|
127
|
+
- spec/mongojob/worker_spec.rb
|
128
|
+
- spec/mongojob_spec.rb
|
129
|
+
- spec/spec.opts
|
130
|
+
- spec/spec_helper.rb
|
131
|
+
- tasks/spec.rb
|
132
|
+
has_rdoc: true
|
133
|
+
homepage: http://github.com/michalf/mongojob
|
134
|
+
licenses: []
|
135
|
+
|
136
|
+
post_install_message:
|
137
|
+
rdoc_options:
|
138
|
+
- --charset=UTF-8
|
139
|
+
require_paths:
|
140
|
+
- lib
|
141
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
142
|
+
none: false
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
hash: 3
|
147
|
+
segments:
|
148
|
+
- 0
|
149
|
+
version: "0"
|
150
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
151
|
+
none: false
|
152
|
+
requirements:
|
153
|
+
- - ">="
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
hash: 3
|
156
|
+
segments:
|
157
|
+
- 0
|
158
|
+
version: "0"
|
159
|
+
requirements: []
|
160
|
+
|
161
|
+
rubyforge_project:
|
162
|
+
rubygems_version: 1.3.7
|
163
|
+
signing_key:
|
164
|
+
specification_version: 3
|
165
|
+
summary: MongoJob is a MongoDB-backed queueing system
|
166
|
+
test_files: []
|
167
|
+
|