que 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +15 -0
- data/CHANGELOG.md +23 -1
- data/README.md +17 -13
- data/docs/advanced_setup.md +13 -11
- data/docs/customizing_que.md +113 -0
- data/docs/error_handling.md +1 -1
- data/docs/logging.md +42 -0
- data/docs/managing_workers.md +6 -0
- data/docs/using_sequel.md +1 -1
- data/lib/generators/que/templates/add_que.rb +4 -2
- data/lib/que.rb +37 -11
- data/lib/que/adapters/active_record.rb +26 -1
- data/lib/que/adapters/base.rb +8 -15
- data/lib/que/job.rb +9 -23
- data/lib/que/migrations.rb +78 -0
- data/lib/que/migrations/1-down.sql +1 -0
- data/lib/que/migrations/1-up.sql +12 -0
- data/lib/que/migrations/2-down.sql +1 -0
- data/lib/que/migrations/2-up.sql +3 -0
- data/lib/que/railtie.rb +8 -3
- data/lib/que/rake_tasks.rb +10 -6
- data/lib/que/sql.rb +1 -29
- data/lib/que/version.rb +1 -1
- data/lib/que/worker.rb +49 -46
- data/que.gemspec +0 -2
- data/spec/adapters/active_record_spec.rb +38 -8
- data/spec/adapters/connection_pool_spec.rb +10 -1
- data/spec/adapters/sequel_spec.rb +19 -8
- data/spec/spec_helper.rb +6 -2
- data/spec/support/shared_examples/adapter.rb +3 -1
- data/spec/travis.rb +13 -0
- data/spec/unit/helper_spec.rb +0 -8
- data/spec/unit/logging_spec.rb +75 -0
- data/spec/unit/migrations_spec.rb +114 -0
- data/spec/unit/pool_spec.rb +22 -40
- data/spec/unit/queue_spec.rb +7 -7
- data/spec/unit/states_spec.rb +3 -5
- data/spec/unit/work_spec.rb +63 -47
- data/spec/unit/worker_spec.rb +20 -52
- data/tasks/safe_shutdown.rb +6 -6
- metadata +17 -17
data/que.gemspec
CHANGED
@@ -14,17 +14,21 @@ unless defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
|
|
14
14
|
it_behaves_like "a multi-threaded Que adapter"
|
15
15
|
|
16
16
|
it "should use the same connection that ActiveRecord does" do
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
begin
|
18
|
+
class ActiveRecordJob < Que::Job
|
19
|
+
def run
|
20
|
+
$pid1 = Integer(Que.execute("select pg_backend_pid()").first['pg_backend_pid'])
|
21
|
+
$pid2 = Integer(ActiveRecord::Base.connection.select_value("select pg_backend_pid()"))
|
22
|
+
end
|
21
23
|
end
|
22
|
-
end
|
23
24
|
|
24
|
-
|
25
|
-
|
25
|
+
ActiveRecordJob.queue
|
26
|
+
Que::Job.work
|
26
27
|
|
27
|
-
|
28
|
+
$pid1.should == $pid2
|
29
|
+
ensure
|
30
|
+
$pid1 = $pid2 = nil
|
31
|
+
end
|
28
32
|
end
|
29
33
|
|
30
34
|
it "should instantiate args as ActiveSupport::HashWithIndifferentAccess" do
|
@@ -44,5 +48,31 @@ unless defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
|
|
44
48
|
Que.wake_interval = 0.005.seconds
|
45
49
|
sleep_until { DB[:que_jobs].empty? }
|
46
50
|
end
|
51
|
+
|
52
|
+
it "should wake up a Worker after queueing a job in async mode, waiting for a transaction to commit if necessary" do
|
53
|
+
Que.mode = :async
|
54
|
+
sleep_until { Que::Worker.workers.all? &:sleeping? }
|
55
|
+
|
56
|
+
# Wakes a worker immediately when not in a transaction.
|
57
|
+
Que::Job.queue
|
58
|
+
sleep_until { Que::Worker.workers.all?(&:sleeping?) && DB[:que_jobs].empty? }
|
59
|
+
|
60
|
+
ActiveRecord::Base.transaction do
|
61
|
+
Que::Job.queue
|
62
|
+
Que::Worker.workers.each { |worker| worker.should be_sleeping }
|
63
|
+
end
|
64
|
+
sleep_until { Que::Worker.workers.all?(&:sleeping?) && DB[:que_jobs].empty? }
|
65
|
+
|
66
|
+
# Do nothing when queueing with a specific :run_at.
|
67
|
+
BlockJob.queue :run_at => Time.now
|
68
|
+
Que::Worker.workers.each { |worker| worker.should be_sleeping }
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should be able to tell when it's in an ActiveRecord transaction" do
|
72
|
+
Que.adapter.should_not be_in_transaction
|
73
|
+
ActiveRecord::Base.transaction do
|
74
|
+
Que.adapter.should be_in_transaction
|
75
|
+
end
|
76
|
+
end
|
47
77
|
end
|
48
78
|
end
|
@@ -1,11 +1,20 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'connection_pool'
|
3
3
|
|
4
|
-
Que.connection = ConnectionPool.new &NEW_PG_CONNECTION
|
4
|
+
Que.connection = QUE_SPEC_CONNECTION_POOL = ConnectionPool.new &NEW_PG_CONNECTION
|
5
5
|
QUE_ADAPTERS[:connection_pool] = Que.adapter
|
6
6
|
|
7
7
|
describe "Que using the ConnectionPool adapter" do
|
8
8
|
before { Que.adapter = QUE_ADAPTERS[:connection_pool] }
|
9
9
|
|
10
10
|
it_behaves_like "a multi-threaded Que adapter"
|
11
|
+
|
12
|
+
it "should be able to tell when it's already in a transaction" do
|
13
|
+
Que.adapter.should_not be_in_transaction
|
14
|
+
QUE_SPEC_CONNECTION_POOL.with do |conn|
|
15
|
+
conn.async_exec "BEGIN"
|
16
|
+
Que.adapter.should be_in_transaction
|
17
|
+
conn.async_exec "COMMIT"
|
18
|
+
end
|
19
|
+
end
|
11
20
|
end
|
@@ -9,17 +9,21 @@ describe "Que using the Sequel adapter" do
|
|
9
9
|
it_behaves_like "a multi-threaded Que adapter"
|
10
10
|
|
11
11
|
it "should use the same connection that Sequel does" do
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
begin
|
13
|
+
class SequelJob < Que::Job
|
14
|
+
def run
|
15
|
+
$pid1 = Integer(Que.execute("select pg_backend_pid()").first['pg_backend_pid'])
|
16
|
+
$pid2 = Integer(SEQUEL_ADAPTER_DB['select pg_backend_pid()'].get)
|
17
|
+
end
|
16
18
|
end
|
17
|
-
end
|
18
19
|
|
19
|
-
|
20
|
-
|
20
|
+
SequelJob.queue
|
21
|
+
Que::Job.work
|
21
22
|
|
22
|
-
|
23
|
+
$pid1.should == $pid2
|
24
|
+
ensure
|
25
|
+
$pid1 = $pid2 = nil
|
26
|
+
end
|
23
27
|
end
|
24
28
|
|
25
29
|
it "should wake up a Worker after queueing a job in async mode, waiting for a transaction to commit if necessary" do
|
@@ -40,4 +44,11 @@ describe "Que using the Sequel adapter" do
|
|
40
44
|
BlockJob.queue :run_at => Time.now
|
41
45
|
Que::Worker.workers.each { |worker| worker.should be_sleeping }
|
42
46
|
end
|
47
|
+
|
48
|
+
it "should be able to tell when it's in a Sequel transaction" do
|
49
|
+
Que.adapter.should_not be_in_transaction
|
50
|
+
SEQUEL_ADAPTER_DB.transaction do
|
51
|
+
Que.adapter.should be_in_transaction
|
52
|
+
end
|
53
|
+
end
|
43
54
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'que'
|
2
2
|
require 'uri'
|
3
3
|
require 'pg'
|
4
|
-
require 'json'
|
5
4
|
require 'logger'
|
5
|
+
require 'json'
|
6
6
|
|
7
7
|
Dir['./spec/support/**/*.rb'].sort.each &method(:require)
|
8
8
|
|
@@ -42,8 +42,12 @@ QUE_ADAPTERS = {:pg => Que.adapter}
|
|
42
42
|
# We use Sequel to examine the database in specs.
|
43
43
|
require 'sequel'
|
44
44
|
DB = Sequel.connect(QUE_URL)
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
# Reset the table to the most up-to-date version.
|
45
49
|
DB.drop_table? :que_jobs
|
46
|
-
|
50
|
+
Que::Migrations.migrate!
|
47
51
|
|
48
52
|
|
49
53
|
|
@@ -7,7 +7,9 @@ shared_examples "a Que adapter" do
|
|
7
7
|
|
8
8
|
it "should be able to queue and work a job" do
|
9
9
|
Que::Job.queue
|
10
|
-
Que::Job.work
|
10
|
+
result = Que::Job.work
|
11
|
+
result[:event].should == :job_worked
|
12
|
+
result[:job][:job_class].should == 'Que::Job'
|
11
13
|
end
|
12
14
|
|
13
15
|
it "should yield the same Postgres connection for the duration of the block" do
|
data/spec/travis.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Run tests a bunch of times, flush out thread race conditions / errors.
|
4
|
+
test_runs = if ENV['TESTS']
|
5
|
+
Integer(ENV['TESTS'])
|
6
|
+
else
|
7
|
+
50
|
8
|
+
end
|
9
|
+
|
10
|
+
1.upto(test_runs) do |i|
|
11
|
+
puts "Test Run #{i}"
|
12
|
+
exit(-1) if !system("bundle exec rake")
|
13
|
+
end
|
data/spec/unit/helper_spec.rb
CHANGED
@@ -1,14 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Que, 'helpers' do
|
4
|
-
it "should be able to drop and create the jobs table" do
|
5
|
-
DB.table_exists?(:que_jobs).should be true
|
6
|
-
Que.drop!
|
7
|
-
DB.table_exists?(:que_jobs).should be false
|
8
|
-
Que.create!
|
9
|
-
DB.table_exists?(:que_jobs).should be true
|
10
|
-
end
|
11
|
-
|
12
4
|
it "should be able to clear the jobs table" do
|
13
5
|
DB[:que_jobs].insert :job_class => "Que::Job"
|
14
6
|
DB[:que_jobs].count.should be 1
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Logging" do
|
4
|
+
it "by default should record the library and thread id in JSON" do
|
5
|
+
Que.log :event => "blah", :source => 4
|
6
|
+
$logger.messages.count.should be 1
|
7
|
+
|
8
|
+
message = JSON.load($logger.messages.first)
|
9
|
+
message['lib'].should == 'que'
|
10
|
+
message['event'].should == 'blah'
|
11
|
+
message['source'].should == 4
|
12
|
+
message['thread'].should == Thread.current.object_id
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should not raise an error when no logger is present" do
|
16
|
+
begin
|
17
|
+
Que.logger = nil
|
18
|
+
|
19
|
+
Que::Job.queue
|
20
|
+
worker = Que::Worker.new
|
21
|
+
sleep_until { worker.sleeping? }
|
22
|
+
|
23
|
+
DB[:que_jobs].should be_empty
|
24
|
+
|
25
|
+
worker.stop
|
26
|
+
worker.wait_until_stopped
|
27
|
+
ensure
|
28
|
+
Que.logger = $logger
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should allow the use of a custom log formatter" do
|
33
|
+
begin
|
34
|
+
Que.log_formatter = proc { |data| "Logged event is #{data[:event]}" }
|
35
|
+
Que.log :event => 'my_event'
|
36
|
+
$logger.messages.count.should be 1
|
37
|
+
$logger.messages.first.should == "Logged event is my_event"
|
38
|
+
ensure
|
39
|
+
Que.log_formatter = nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should not log anything if the logging formatter returns falsey" do
|
44
|
+
begin
|
45
|
+
Que.log_formatter = proc { |data| false }
|
46
|
+
|
47
|
+
Que.log :event => "blah"
|
48
|
+
$logger.messages.should be_empty
|
49
|
+
ensure
|
50
|
+
Que.log_formatter = nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should use a :level option to set the log level if one exists, or default to info" do
|
55
|
+
begin
|
56
|
+
Que.logger = o = Object.new
|
57
|
+
|
58
|
+
def o.method_missing(level, message)
|
59
|
+
$level = level
|
60
|
+
$message = message
|
61
|
+
end
|
62
|
+
|
63
|
+
Que.log :message => 'one'
|
64
|
+
$level.should == :info
|
65
|
+
JSON.load($message)['message'].should == 'one'
|
66
|
+
|
67
|
+
Que.log :message => 'two', :level => 'debug'
|
68
|
+
$level.should == :debug
|
69
|
+
JSON.load($message)['message'].should == 'two'
|
70
|
+
ensure
|
71
|
+
Que.logger = $logger
|
72
|
+
$level = $message = nil
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Que::Migrations do
|
4
|
+
it "should be able to perform migrations up and down" do
|
5
|
+
# Migration #1 creates the table with a priority default of 1, migration
|
6
|
+
# #2 ups that to 100.
|
7
|
+
|
8
|
+
default = proc do
|
9
|
+
result = Que.execute <<-SQL
|
10
|
+
select adsrc
|
11
|
+
from pg_attribute a
|
12
|
+
join pg_class c on c.oid = a.attrelid
|
13
|
+
join pg_attrdef on adrelid = attrelid AND adnum = attnum
|
14
|
+
where relname = 'que_jobs'
|
15
|
+
and attname = 'priority'
|
16
|
+
SQL
|
17
|
+
|
18
|
+
result.first['adsrc'].to_i
|
19
|
+
end
|
20
|
+
|
21
|
+
default.call.should == 100
|
22
|
+
Que::Migrations.migrate! :version => 1
|
23
|
+
default.call.should == 1
|
24
|
+
Que::Migrations.migrate! :version => 2
|
25
|
+
default.call.should == 100
|
26
|
+
|
27
|
+
# Clean up.
|
28
|
+
Que.migrate!
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should be able to get and set the current schema version" do
|
32
|
+
Que::Migrations.db_version.should == Que::Migrations::CURRENT_VERSION
|
33
|
+
Que::Migrations.set_db_version(59328)
|
34
|
+
Que::Migrations.db_version.should == 59328
|
35
|
+
Que::Migrations.set_db_version(Que::Migrations::CURRENT_VERSION)
|
36
|
+
Que::Migrations.db_version.should == Que::Migrations::CURRENT_VERSION
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should be able to cycle the jobs table all the way between nonexistent and current without error" do
|
40
|
+
Que::Migrations.db_version.should == Que::Migrations::CURRENT_VERSION
|
41
|
+
Que::Migrations.migrate! :version => 0
|
42
|
+
Que::Migrations.db_version.should == 0
|
43
|
+
Que::Migrations.migrate!
|
44
|
+
Que::Migrations.db_version.should == Que::Migrations::CURRENT_VERSION
|
45
|
+
|
46
|
+
# The helper on the Que module does the same thing.
|
47
|
+
Que.migrate! :version => 0
|
48
|
+
Que::Migrations.db_version.should == 0
|
49
|
+
Que.migrate!
|
50
|
+
Que::Migrations.db_version.should == Que::Migrations::CURRENT_VERSION
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should be able to honor the initial behavior of Que.drop!" do
|
54
|
+
DB.table_exists?(:que_jobs).should be true
|
55
|
+
Que.drop!
|
56
|
+
DB.table_exists?(:que_jobs).should be false
|
57
|
+
|
58
|
+
# Clean up.
|
59
|
+
Que::Migrations.migrate!
|
60
|
+
DB.table_exists?(:que_jobs).should be true
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should be able to recognize a que_jobs table created before the versioning system" do
|
64
|
+
DB.drop_table :que_jobs
|
65
|
+
DB.create_table(:que_jobs){serial :id} # Dummy Table.
|
66
|
+
Que::Migrations.db_version.should == 1
|
67
|
+
DB.drop_table(:que_jobs)
|
68
|
+
Que::Migrations.migrate!
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should be able to honor the initial behavior of Que.create!" do
|
72
|
+
DB.drop_table :que_jobs
|
73
|
+
Que.create!
|
74
|
+
DB.table_exists?(:que_jobs).should be true
|
75
|
+
Que::Migrations.db_version.should == 1
|
76
|
+
|
77
|
+
# Clean up.
|
78
|
+
Que::Migrations.migrate!
|
79
|
+
DB.table_exists?(:que_jobs).should be true
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should use transactions to protect its migrations from errors" do
|
83
|
+
proc do
|
84
|
+
Que::Migrations.transaction do
|
85
|
+
Que.execute "DROP TABLE que_jobs"
|
86
|
+
Que.execute "invalid SQL syntax"
|
87
|
+
end
|
88
|
+
end.should raise_error(PG::Error)
|
89
|
+
|
90
|
+
DB.table_exists?(:que_jobs).should be true
|
91
|
+
end
|
92
|
+
|
93
|
+
# In Ruby 1.9, it's impossible to tell inside an ensure block whether the
|
94
|
+
# currently executing thread has been killed.
|
95
|
+
unless RUBY_VERSION.start_with?('1.9')
|
96
|
+
it "should use transactions to protect its migrations from killed threads" do
|
97
|
+
q = Queue.new
|
98
|
+
|
99
|
+
t = Thread.new do
|
100
|
+
Que::Migrations.transaction do
|
101
|
+
Que.execute "DROP TABLE que_jobs"
|
102
|
+
q.push :go!
|
103
|
+
sleep
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
q.pop
|
108
|
+
t.kill
|
109
|
+
t.join
|
110
|
+
|
111
|
+
DB.table_exists?(:que_jobs).should be true
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
data/spec/unit/pool_spec.rb
CHANGED
@@ -4,12 +4,15 @@ describe "Managing the Worker pool" do
|
|
4
4
|
it "should log mode changes" do
|
5
5
|
Que.mode = :sync
|
6
6
|
Que.mode = :off
|
7
|
-
$logger.messages.should == ["[Que] Set mode to :sync", "[Que] Set mode to :off"]
|
8
|
-
end
|
9
7
|
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
$logger.messages.count.should be 2
|
9
|
+
m1, m2 = $logger.messages.map{|m| JSON.load(m)}
|
10
|
+
|
11
|
+
m1['event'].should == 'mode_change'
|
12
|
+
m1['value'].should == 'sync'
|
13
|
+
|
14
|
+
m2['event'].should == 'mode_change'
|
15
|
+
m2['value'].should == 'off'
|
13
16
|
end
|
14
17
|
|
15
18
|
describe "Que.mode = :sync" do
|
@@ -19,10 +22,6 @@ describe "Managing the Worker pool" do
|
|
19
22
|
ArgsJob.queue(5, :testing => "synchronous").should be_an_instance_of ArgsJob
|
20
23
|
$passed_args.should == [5, {'testing' => "synchronous"}]
|
21
24
|
DB[:que_jobs].count.should be 0
|
22
|
-
|
23
|
-
$logger.messages.length.should be 2
|
24
|
-
$logger.messages[0].should == "[Que] Set mode to :sync"
|
25
|
-
$logger.messages[1].should =~ /\A\[Que\] Worked job in/
|
26
25
|
end
|
27
26
|
|
28
27
|
it "should not affect jobs that are queued with specific run_ats" do
|
@@ -31,11 +30,6 @@ describe "Managing the Worker pool" do
|
|
31
30
|
ArgsJob.queue(5, :testing => "synchronous", :run_at => Time.now + 60)
|
32
31
|
DB[:que_jobs].select_map(:job_class).should == ["ArgsJob"]
|
33
32
|
end
|
34
|
-
|
35
|
-
it "then Que.stop! should do nothing" do
|
36
|
-
Que::Worker.workers.should be_empty
|
37
|
-
Que.stop!
|
38
|
-
end
|
39
33
|
end
|
40
34
|
|
41
35
|
describe "Que.mode = :async" do
|
@@ -44,7 +38,8 @@ describe "Managing the Worker pool" do
|
|
44
38
|
Que.worker_count.should be 4
|
45
39
|
sleep_until { Que::Worker.workers.all?(&:sleeping?) }
|
46
40
|
|
47
|
-
$logger.messages.
|
41
|
+
$logger.messages.map{|m| JSON.load(m).values_at('event', 'value')}.should ==
|
42
|
+
[['mode_change', 'async'], ['worker_count_change', '4']] + [['job_unavailable', nil]] * 4
|
48
43
|
end
|
49
44
|
|
50
45
|
it "should be done automatically when setting a worker count" do
|
@@ -53,7 +48,8 @@ describe "Managing the Worker pool" do
|
|
53
48
|
Que.worker_count.should == 2
|
54
49
|
sleep_until { Que::Worker.workers.all?(&:sleeping?) }
|
55
50
|
|
56
|
-
$logger.messages.
|
51
|
+
$logger.messages.map{|m| JSON.load(m).values_at('event', 'value')}.should ==
|
52
|
+
[['mode_change', 'async'], ['worker_count_change', '2']] + [['job_unavailable', nil]] * 2
|
57
53
|
end
|
58
54
|
|
59
55
|
it "should not affect the number of workers if a worker_count has already been set" do
|
@@ -62,7 +58,8 @@ describe "Managing the Worker pool" do
|
|
62
58
|
Que.worker_count.should be 1
|
63
59
|
sleep_until { Que::Worker.workers.all?(&:sleeping?) }
|
64
60
|
|
65
|
-
$logger.messages.
|
61
|
+
$logger.messages.map{|m| JSON.load(m).values_at('event', 'value')}.should ==
|
62
|
+
[['mode_change', 'async'], ['worker_count_change', '1'], ['job_unavailable', nil]]
|
66
63
|
end
|
67
64
|
|
68
65
|
it "then Que.worker_count = 0 should set the mode to :off" do
|
@@ -75,7 +72,8 @@ describe "Managing the Worker pool" do
|
|
75
72
|
Que.worker_count.should == 0
|
76
73
|
Que.mode.should == :off
|
77
74
|
|
78
|
-
$logger.messages.
|
75
|
+
$logger.messages.map{|m| JSON.load(m).values_at('event', 'value')}.should ==
|
76
|
+
[['mode_change', 'async'], ['worker_count_change', '4']] + [['job_unavailable', nil]] * 4 + [['mode_change', 'off'], ['worker_count_change', '0']]
|
79
77
|
end
|
80
78
|
|
81
79
|
it "then Que.worker_count = 2 should gracefully decrease the number of workers" do
|
@@ -94,7 +92,8 @@ describe "Managing the Worker pool" do
|
|
94
92
|
worker.thread.status.should == false
|
95
93
|
end
|
96
94
|
|
97
|
-
$logger.messages.
|
95
|
+
$logger.messages.map{|m| JSON.load(m).values_at('event', 'value')}.should ==
|
96
|
+
[['mode_change', 'async'], ['worker_count_change', '4']] + [['job_unavailable', nil]] * 4 + [['worker_count_change', '2']]
|
98
97
|
end
|
99
98
|
|
100
99
|
it "then Que.worker_count = 6 should gracefully increase the number of workers" do
|
@@ -109,7 +108,8 @@ describe "Managing the Worker pool" do
|
|
109
108
|
|
110
109
|
workers.should == Que::Worker.workers[0..3]
|
111
110
|
|
112
|
-
$logger.messages.
|
111
|
+
$logger.messages.map{|m| JSON.load(m).values_at('event', 'value')}.should ==
|
112
|
+
[['mode_change', 'async'], ['worker_count_change', '4']] + [['job_unavailable', nil]] * 4 + [['worker_count_change', '6']] + [['job_unavailable', nil]] * 2
|
113
113
|
end
|
114
114
|
|
115
115
|
it "then Que.mode = :off should gracefully shut down workers" do
|
@@ -124,7 +124,8 @@ describe "Managing the Worker pool" do
|
|
124
124
|
workers.count.should be 4
|
125
125
|
workers.each { |worker| worker.thread.status.should be false }
|
126
126
|
|
127
|
-
$logger.messages.
|
127
|
+
$logger.messages.map{|m| JSON.load(m).values_at('event', 'value')}.should ==
|
128
|
+
[['mode_change', 'async'], ['worker_count_change', '4']] + [['job_unavailable', nil]] * 4 + [['mode_change', 'off'], ['worker_count_change', '0']]
|
128
129
|
end
|
129
130
|
|
130
131
|
it "then Que.wake! should wake up a single worker" do
|
@@ -181,24 +182,5 @@ describe "Managing the Worker pool" do
|
|
181
182
|
Que::Job.queue
|
182
183
|
sleep_until { DB[:que_jobs].count == 0 }
|
183
184
|
end
|
184
|
-
|
185
|
-
it "then Que.stop! should interrupt all running jobs" do
|
186
|
-
begin
|
187
|
-
# Que.stop! can unpredictably affect connections, which may affect
|
188
|
-
# other tests, so use a new one.
|
189
|
-
pg = NEW_PG_CONNECTION.call
|
190
|
-
Que.connection = pg
|
191
|
-
|
192
|
-
BlockJob.queue
|
193
|
-
Que.mode = :async
|
194
|
-
$q1.pop
|
195
|
-
Que.stop!
|
196
|
-
ensure
|
197
|
-
if pg
|
198
|
-
# Closing the connection can raise a NullPointerException on JRuby.
|
199
|
-
pg.close rescue nil
|
200
|
-
end
|
201
|
-
end
|
202
|
-
end
|
203
185
|
end
|
204
186
|
end
|