job_boss 0.2 → 0.4
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/README.markdown +25 -2
- data/Rakefile +21 -8
- data/bin/job_boss +1 -0
- data/doc/ActiveSupport/TestCase.html +584 -0
- data/doc/{Passenger.html → ActiveSupport.html} +10 -30
- data/doc/CreateJobs.html +31 -16
- data/doc/{Mongrel.html → DaemonTest.html} +23 -39
- data/doc/JobBoss/Boss.html +466 -68
- data/doc/JobBoss/Config.html +77 -39
- data/doc/JobBoss/Job.html +375 -97
- data/doc/JobBoss/Queuer.html +35 -21
- data/doc/JobBoss.html +14 -311
- data/doc/{ActiveRecord.html → MathJobs.html} +66 -36
- data/doc/Rakefile.html +43 -9
- data/doc/SleepJobs.html +251 -0
- data/doc/{PhusionPassenger.html → StringJobs.html} +66 -38
- data/doc/bin/job_boss.html +1 -1
- data/doc/created.rid +14 -8
- data/doc/index.html +63 -7
- data/doc/lib/job_boss/boss_rb.html +5 -1
- data/doc/lib/job_boss/{configuror_rb.html → config_rb.html} +2 -2
- data/doc/lib/job_boss/job_rb.html +3 -1
- data/doc/lib/job_boss/queuer_rb.html +1 -1
- data/doc/lib/migrate_rb.html +1 -1
- data/doc/{vendor/spawn/lib/spawn_rb.html → test/app_root/app/jobs/math_jobs_rb.html} +7 -7
- data/doc/{vendor/spawn/lib/patches_rb.html → test/app_root/app/jobs/sleep_jobs_rb.html} +8 -12
- data/doc/test/app_root/app/jobs/string_jobs_rb.html +52 -0
- data/doc/test/test_helper_rb.html +62 -0
- data/doc/{vendor/spawn/init_rb.html → test/unit/daemon_test_rb.html} +3 -3
- data/doc/test/unit/job_test_rb.html +60 -0
- data/job_boss.gemspec +3 -2
- data/lib/job_boss/boss.rb +29 -7
- data/lib/job_boss/config.rb +49 -0
- data/lib/job_boss/job.rb +57 -13
- data/lib/migrate.rb +3 -1
- data/test/app_root/app/jobs/math_jobs.rb +5 -0
- data/test/app_root/app/jobs/sleep_jobs.rb +9 -0
- data/test/app_root/app/jobs/string_jobs.rb +5 -0
- data/test/app_root/config/database.yml +22 -0
- data/test/test_helper.rb +113 -0
- data/test/unit/daemon_test.rb +29 -0
- data/test/unit/job_test.rb +73 -0
- metadata +46 -27
- data/doc/ActiveRecord/Base.html +0 -343
- data/doc/Mongrel/HttpServer.html +0 -275
- data/doc/Passenger/Railz/RequestHandler.html +0 -271
- data/doc/Passenger/Railz.html +0 -185
- data/doc/PhusionPassenger/Rack/RequestHandler.html +0 -271
- data/doc/PhusionPassenger/Rack.html +0 -185
- data/doc/PhusionPassenger/Railz/RequestHandler.html +0 -271
- data/doc/PhusionPassenger/Railz.html +0 -185
- data/doc/Spawn/SpawnId.html +0 -276
- data/doc/Spawn.html +0 -742
- data/doc/vendor/spawn/CHANGELOG.html +0 -275
- data/doc/vendor/spawn/LICENSE.html +0 -151
- data/lib/job_boss/configuror.rb +0 -40
data/lib/migrate.rb
CHANGED
@@ -8,11 +8,13 @@ class CreateJobs < ActiveRecord::Migration
|
|
8
8
|
t.datetime :cancelled_at
|
9
9
|
t.datetime :completed_at
|
10
10
|
t.string :status
|
11
|
+
|
12
|
+
t.string :error_class
|
11
13
|
t.string :error_message
|
12
14
|
t.text :error_backtrace
|
13
15
|
|
14
16
|
t.string :employee_host
|
15
|
-
t.
|
17
|
+
t.integer :employee_pid
|
16
18
|
|
17
19
|
t.timestamps
|
18
20
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# SQLite version 3.x
|
2
|
+
# gem install sqlite3-ruby (not necessary on OS X Leopard)
|
3
|
+
development:
|
4
|
+
adapter: sqlite3
|
5
|
+
database: test/app_root/db/development.sqlite3
|
6
|
+
pool: 5
|
7
|
+
timeout: 10000
|
8
|
+
|
9
|
+
# Warning: The database defined as "test" will be erased and
|
10
|
+
# re-generated from your development database when you run "rake".
|
11
|
+
# Do not set this db to the same as development or production.
|
12
|
+
test:
|
13
|
+
adapter: sqlite3
|
14
|
+
database: test/app_root/db/test.sqlite3
|
15
|
+
pool: 5
|
16
|
+
timeout: 10000
|
17
|
+
|
18
|
+
production:
|
19
|
+
adapter: sqlite3
|
20
|
+
database: test/app_root/db/production.sqlite3
|
21
|
+
pool: 5
|
22
|
+
timeout: 10000
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'sqlite3'
|
4
|
+
|
5
|
+
require 'fileutils'
|
6
|
+
FileUtils.cd(File.expand_path('../..', __FILE__))
|
7
|
+
|
8
|
+
require 'active_support'
|
9
|
+
|
10
|
+
class ActiveSupport::TestCase
|
11
|
+
# Add more helper methods to be used by all tests here...
|
12
|
+
|
13
|
+
setup :setup_paths
|
14
|
+
teardown :clean_app_environment
|
15
|
+
teardown :stop_daemon
|
16
|
+
|
17
|
+
def setup_paths
|
18
|
+
@app_root_path = File.join('test', 'app_root')
|
19
|
+
@db_path = File.join(@app_root_path, 'db')
|
20
|
+
@log_path = File.join(@app_root_path, 'log', 'job_boss.log')
|
21
|
+
@db_yaml_path = File.join(@app_root_path, 'config', 'database.yml')
|
22
|
+
end
|
23
|
+
|
24
|
+
def clean_app_environment
|
25
|
+
Dir.glob(File.join(@db_path, '*')).each {|path| File.unlink(path) }
|
26
|
+
Dir.glob(File.join(@app_root_path, 'log', '*')).each {|path| File.unlink(path) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def assert_pid_running(pid, message="")
|
30
|
+
full_message = build_message(message, "PID <?> expected to be running.", pid)
|
31
|
+
assert_block(full_message) do
|
32
|
+
begin
|
33
|
+
Process.kill(0, pid.to_i)
|
34
|
+
true
|
35
|
+
rescue
|
36
|
+
false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def assert_pid_not_running(pid, message="")
|
42
|
+
full_message = build_message(message, "PID <?> expected to not be running.", pid)
|
43
|
+
assert_block(full_message) do
|
44
|
+
begin
|
45
|
+
Process.kill(0, pid.to_i)
|
46
|
+
false
|
47
|
+
rescue
|
48
|
+
true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def start_daemon(options)
|
54
|
+
clean_app_environment
|
55
|
+
|
56
|
+
stop_daemon
|
57
|
+
|
58
|
+
option_string = options.collect do |key, value|
|
59
|
+
'--' + key.to_s.gsub('_', '-') + " " + value.to_s
|
60
|
+
end
|
61
|
+
|
62
|
+
output = `bin/job_boss start -- #{option_string.join(' ')}`
|
63
|
+
|
64
|
+
@daemon_pid = get_pid_from_startup(output)
|
65
|
+
|
66
|
+
assert_pid_running(@daemon_pid)
|
67
|
+
|
68
|
+
@daemon_pid
|
69
|
+
end
|
70
|
+
|
71
|
+
def get_pid_from_startup(output)
|
72
|
+
output.match(/job_boss: process with pid (\d+) started./)[1].to_i
|
73
|
+
end
|
74
|
+
|
75
|
+
def wait_for_file(file_path, timeout = 5)
|
76
|
+
i = 0
|
77
|
+
until File.exist?(file_path)
|
78
|
+
sleep(1)
|
79
|
+
|
80
|
+
raise "File failed to appear!" if i > timeout
|
81
|
+
i += 1
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def wait_until_job_assigned(job, wait_interval = 0.5)
|
86
|
+
until job.assigned?
|
87
|
+
sleep(wait_interval)
|
88
|
+
job.reload
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def stop_daemon
|
93
|
+
`bin/job_boss stop`
|
94
|
+
|
95
|
+
# Give the daemon a bit of time to stop
|
96
|
+
# sleep(0.5)
|
97
|
+
assert_pid_not_running(@daemon_pid) if @daemon_pid
|
98
|
+
end
|
99
|
+
|
100
|
+
def restart_daemon
|
101
|
+
assert_pid_running(@daemon_pid)
|
102
|
+
|
103
|
+
output = `bin/job_boss restart`
|
104
|
+
|
105
|
+
# Give the daemon a bit of time to stop
|
106
|
+
# sleep(0.5)
|
107
|
+
assert_pid_not_running(@daemon_pid)
|
108
|
+
|
109
|
+
@daemon_pid = get_pid_from_startup(output)
|
110
|
+
|
111
|
+
assert_pid_running(@daemon_pid)
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class DaemonTest < ActiveSupport::TestCase
|
4
|
+
test "daemon options" do
|
5
|
+
start_daemon(:application_root => @app_root_path)
|
6
|
+
|
7
|
+
wait_for_file(@log_path)
|
8
|
+
|
9
|
+
assert File.read(@log_path).match('INFO -- : Job Boss started')
|
10
|
+
|
11
|
+
stop_daemon
|
12
|
+
|
13
|
+
|
14
|
+
custom_log_path = File.join('log', 'loggity.log')
|
15
|
+
full_custom_log_path = File.join(@app_root_path, custom_log_path)
|
16
|
+
|
17
|
+
start_daemon(:application_root => @app_root_path, :log_path => custom_log_path, :environment => 'production')
|
18
|
+
wait_for_file(full_custom_log_path)
|
19
|
+
|
20
|
+
assert File.read(full_custom_log_path).match('INFO -- : Job Boss started')
|
21
|
+
assert File.exist?(File.join(@app_root_path, 'db', 'production.sqlite3'))
|
22
|
+
|
23
|
+
restart_daemon
|
24
|
+
|
25
|
+
stop_daemon
|
26
|
+
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'active_record'
|
3
|
+
require 'job_boss/boss'
|
4
|
+
require 'job_boss/job'
|
5
|
+
Dir.glob('test/app_root/app/jobs/*_jobs.rb').each {|lib| require lib }
|
6
|
+
|
7
|
+
class DaemonTest < ActiveSupport::TestCase
|
8
|
+
test "job queuing" do
|
9
|
+
start_daemon(:application_root => @app_root_path)
|
10
|
+
|
11
|
+
wait_for_file(@log_path)
|
12
|
+
|
13
|
+
config = YAML.load(File.read(@db_yaml_path))
|
14
|
+
|
15
|
+
ActiveRecord::Base.establish_connection(config['development'])
|
16
|
+
|
17
|
+
# Test returning results from a number of jobs
|
18
|
+
jobs = (0..10).collect do |i|
|
19
|
+
JobBoss::Boss.queue.math.is_prime?(i)
|
20
|
+
end
|
21
|
+
|
22
|
+
JobBoss::Job.wait_for_jobs(jobs)
|
23
|
+
|
24
|
+
assert_equal 11, JobBoss::Job.completed.count
|
25
|
+
|
26
|
+
JobBoss::Job.result_hash(jobs).each do |args, result|
|
27
|
+
assert_equal MathJobs.new.is_prime?(args.first), result
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
# Test functions with multiple arguments and a complex return value (an Array in this case)
|
32
|
+
job = JobBoss::Boss.queue.string.concatenate('test', 'of', 'concatenation')
|
33
|
+
JobBoss::Job.wait_for_jobs(job)
|
34
|
+
assert_equal 12, JobBoss::Job.completed.count
|
35
|
+
|
36
|
+
assert_equal ['testofconcatenation', 3], job.result
|
37
|
+
|
38
|
+
assert job.time_taken > 0
|
39
|
+
assert_nil job.error
|
40
|
+
|
41
|
+
|
42
|
+
# Test cancelling of a job
|
43
|
+
job = JobBoss::Boss.queue.sleep.sleep_for(10)
|
44
|
+
|
45
|
+
wait_until_job_assigned(job)
|
46
|
+
|
47
|
+
assert_pid_running(job.employee_pid)
|
48
|
+
|
49
|
+
job.cancel
|
50
|
+
|
51
|
+
sleep(2)
|
52
|
+
|
53
|
+
assert_pid_not_running(job.employee_pid)
|
54
|
+
|
55
|
+
job.reload
|
56
|
+
assert job.cancelled?
|
57
|
+
assert_not_nil job.cancelled_at
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
# Test raising of errors
|
62
|
+
job = JobBoss::Boss.queue.sleep.do_not_never_sleep
|
63
|
+
JobBoss::Job.wait_for_jobs(job)
|
64
|
+
job.reload
|
65
|
+
|
66
|
+
error = job.error
|
67
|
+
assert_equal ArgumentError, error.class
|
68
|
+
assert_equal "I can't not do that, Dave.", error.message
|
69
|
+
assert_equal Array, error.backtrace.class
|
70
|
+
|
71
|
+
stop_daemon
|
72
|
+
end
|
73
|
+
end
|
metadata
CHANGED
@@ -4,8 +4,8 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
version: "0.
|
7
|
+
- 4
|
8
|
+
version: "0.4"
|
9
9
|
platform: ruby
|
10
10
|
authors:
|
11
11
|
- Brian Underwood
|
@@ -13,7 +13,7 @@ autorequire:
|
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
15
|
|
16
|
-
date: 2010-11-
|
16
|
+
date: 2010-11-28 00:00:00 -05:00
|
17
17
|
default_executable: job_boss
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
type: :runtime
|
44
44
|
version_requirements: *id002
|
45
45
|
- !ruby/object:Gem::Dependency
|
46
|
-
name: daemons
|
46
|
+
name: daemons-mikehale
|
47
47
|
prerelease: false
|
48
48
|
requirement: &id003 !ruby/object:Gem::Requirement
|
49
49
|
none: false
|
@@ -55,6 +55,19 @@ dependencies:
|
|
55
55
|
version: "0"
|
56
56
|
type: :runtime
|
57
57
|
version_requirements: *id003
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: sqlite3-ruby
|
60
|
+
prerelease: false
|
61
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
segments:
|
67
|
+
- 0
|
68
|
+
version: "0"
|
69
|
+
type: :runtime
|
70
|
+
version_requirements: *id004
|
58
71
|
description: job_boss allows you to queue jobs which are unqueued by a "Job Boss" daemon and handed off to workers to process
|
59
72
|
email:
|
60
73
|
- ml+job_boss@semi-sentient.com
|
@@ -68,49 +81,49 @@ files:
|
|
68
81
|
- README.markdown
|
69
82
|
- Rakefile
|
70
83
|
- bin/job_boss
|
71
|
-
- doc/
|
72
|
-
- doc/
|
84
|
+
- doc/ActiveSupport.html
|
85
|
+
- doc/ActiveSupport/TestCase.html
|
73
86
|
- doc/CreateJobs.html
|
87
|
+
- doc/DaemonTest.html
|
74
88
|
- doc/JobBoss.html
|
75
89
|
- doc/JobBoss/Boss.html
|
76
90
|
- doc/JobBoss/Config.html
|
77
91
|
- doc/JobBoss/Job.html
|
78
92
|
- doc/JobBoss/Queuer.html
|
79
|
-
- doc/
|
80
|
-
- doc/Mongrel/HttpServer.html
|
81
|
-
- doc/Passenger.html
|
82
|
-
- doc/Passenger/Railz.html
|
83
|
-
- doc/Passenger/Railz/RequestHandler.html
|
84
|
-
- doc/PhusionPassenger.html
|
85
|
-
- doc/PhusionPassenger/Rack.html
|
86
|
-
- doc/PhusionPassenger/Rack/RequestHandler.html
|
87
|
-
- doc/PhusionPassenger/Railz.html
|
88
|
-
- doc/PhusionPassenger/Railz/RequestHandler.html
|
93
|
+
- doc/MathJobs.html
|
89
94
|
- doc/Rakefile.html
|
90
|
-
- doc/
|
91
|
-
- doc/
|
95
|
+
- doc/SleepJobs.html
|
96
|
+
- doc/StringJobs.html
|
92
97
|
- doc/bin/job_boss.html
|
93
98
|
- doc/created.rid
|
94
99
|
- doc/index.html
|
95
100
|
- doc/lib/job_boss/boss_rb.html
|
96
101
|
- doc/lib/job_boss/capistrano_rb.html
|
97
|
-
- doc/lib/job_boss/
|
102
|
+
- doc/lib/job_boss/config_rb.html
|
98
103
|
- doc/lib/job_boss/job_rb.html
|
99
104
|
- doc/lib/job_boss/queuer_rb.html
|
100
105
|
- doc/lib/migrate_rb.html
|
101
106
|
- doc/rdoc.css
|
102
|
-
- doc/
|
103
|
-
- doc/
|
104
|
-
- doc/
|
105
|
-
- doc/
|
106
|
-
- doc/
|
107
|
+
- doc/test/app_root/app/jobs/math_jobs_rb.html
|
108
|
+
- doc/test/app_root/app/jobs/sleep_jobs_rb.html
|
109
|
+
- doc/test/app_root/app/jobs/string_jobs_rb.html
|
110
|
+
- doc/test/test_helper_rb.html
|
111
|
+
- doc/test/unit/daemon_test_rb.html
|
112
|
+
- doc/test/unit/job_test_rb.html
|
107
113
|
- job_boss.gemspec
|
108
114
|
- lib/job_boss/boss.rb
|
109
115
|
- lib/job_boss/capistrano.rb
|
110
|
-
- lib/job_boss/
|
116
|
+
- lib/job_boss/config.rb
|
111
117
|
- lib/job_boss/job.rb
|
112
118
|
- lib/job_boss/queuer.rb
|
113
119
|
- lib/migrate.rb
|
120
|
+
- test/app_root/app/jobs/math_jobs.rb
|
121
|
+
- test/app_root/app/jobs/sleep_jobs.rb
|
122
|
+
- test/app_root/app/jobs/string_jobs.rb
|
123
|
+
- test/app_root/config/database.yml
|
124
|
+
- test/test_helper.rb
|
125
|
+
- test/unit/daemon_test.rb
|
126
|
+
- test/unit/job_test.rb
|
114
127
|
has_rdoc: true
|
115
128
|
homepage: http://github.com/cheerfulstoic/job_boss
|
116
129
|
licenses: []
|
@@ -147,5 +160,11 @@ rubygems_version: 1.3.7
|
|
147
160
|
signing_key:
|
148
161
|
specification_version: 3
|
149
162
|
summary: Asyncronous, parallel job processing
|
150
|
-
test_files:
|
151
|
-
|
163
|
+
test_files:
|
164
|
+
- test/app_root/app/jobs/math_jobs.rb
|
165
|
+
- test/app_root/app/jobs/sleep_jobs.rb
|
166
|
+
- test/app_root/app/jobs/string_jobs.rb
|
167
|
+
- test/app_root/config/database.yml
|
168
|
+
- test/test_helper.rb
|
169
|
+
- test/unit/daemon_test.rb
|
170
|
+
- test/unit/job_test.rb
|