que 0.11.3 → 2.2.0
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.
- checksums.yaml +5 -5
- data/.github/workflows/tests.yml +51 -0
- data/.gitignore +2 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +502 -97
- data/Dockerfile +20 -0
- data/LICENSE.txt +1 -1
- data/README.md +205 -59
- data/auto/dev +21 -0
- data/auto/pre-push-hook +30 -0
- data/auto/psql +9 -0
- data/auto/test +5 -0
- data/auto/test-postgres-14 +17 -0
- data/bin/que +8 -81
- data/docker-compose.yml +47 -0
- data/docs/README.md +881 -0
- data/lib/que/active_job/extensions.rb +114 -0
- data/lib/que/active_record/connection.rb +51 -0
- data/lib/que/active_record/model.rb +48 -0
- data/lib/que/command_line_interface.rb +259 -0
- data/lib/que/connection.rb +198 -0
- data/lib/que/connection_pool.rb +78 -0
- data/lib/que/job.rb +210 -103
- data/lib/que/job_buffer.rb +255 -0
- data/lib/que/job_methods.rb +176 -0
- data/lib/que/listener.rb +176 -0
- data/lib/que/locker.rb +507 -0
- data/lib/que/metajob.rb +47 -0
- data/lib/que/migrations/4/down.sql +48 -0
- data/lib/que/migrations/4/up.sql +267 -0
- data/lib/que/migrations/5/down.sql +73 -0
- data/lib/que/migrations/5/up.sql +76 -0
- data/lib/que/migrations/6/down.sql +8 -0
- data/lib/que/migrations/6/up.sql +8 -0
- data/lib/que/migrations/7/down.sql +5 -0
- data/lib/que/migrations/7/up.sql +13 -0
- data/lib/que/migrations.rb +37 -18
- data/lib/que/poller.rb +274 -0
- data/lib/que/rails/railtie.rb +12 -0
- data/lib/que/result_queue.rb +35 -0
- data/lib/que/sequel/model.rb +52 -0
- data/lib/que/utils/assertions.rb +62 -0
- data/lib/que/utils/constantization.rb +19 -0
- data/lib/que/utils/error_notification.rb +68 -0
- data/lib/que/utils/freeze.rb +20 -0
- data/lib/que/utils/introspection.rb +50 -0
- data/lib/que/utils/json_serialization.rb +21 -0
- data/lib/que/utils/logging.rb +79 -0
- data/lib/que/utils/middleware.rb +46 -0
- data/lib/que/utils/queue_management.rb +18 -0
- data/lib/que/utils/ruby2_keywords.rb +19 -0
- data/lib/que/utils/transactions.rb +34 -0
- data/lib/que/version.rb +5 -1
- data/lib/que/worker.rb +145 -149
- data/lib/que.rb +103 -159
- data/que.gemspec +17 -4
- data/scripts/docker-entrypoint +14 -0
- data/scripts/test +6 -0
- metadata +59 -95
- data/.rspec +0 -2
- data/.travis.yml +0 -17
- data/Gemfile +0 -24
- data/docs/advanced_setup.md +0 -106
- data/docs/customizing_que.md +0 -200
- data/docs/error_handling.md +0 -47
- data/docs/inspecting_the_queue.md +0 -114
- data/docs/logging.md +0 -50
- data/docs/managing_workers.md +0 -80
- data/docs/migrating.md +0 -30
- data/docs/multiple_queues.md +0 -27
- data/docs/shutting_down_safely.md +0 -7
- data/docs/using_plain_connections.md +0 -41
- data/docs/using_sequel.md +0 -31
- data/docs/writing_reliable_jobs.md +0 -117
- data/lib/generators/que/install_generator.rb +0 -24
- data/lib/generators/que/templates/add_que.rb +0 -13
- data/lib/que/adapters/active_record.rb +0 -54
- data/lib/que/adapters/base.rb +0 -127
- data/lib/que/adapters/connection_pool.rb +0 -16
- data/lib/que/adapters/pg.rb +0 -21
- data/lib/que/adapters/pond.rb +0 -16
- data/lib/que/adapters/sequel.rb +0 -20
- data/lib/que/railtie.rb +0 -16
- data/lib/que/rake_tasks.rb +0 -59
- data/lib/que/sql.rb +0 -152
- data/spec/adapters/active_record_spec.rb +0 -152
- data/spec/adapters/connection_pool_spec.rb +0 -22
- data/spec/adapters/pg_spec.rb +0 -41
- data/spec/adapters/pond_spec.rb +0 -22
- data/spec/adapters/sequel_spec.rb +0 -57
- data/spec/gemfiles/Gemfile1 +0 -18
- data/spec/gemfiles/Gemfile2 +0 -18
- data/spec/spec_helper.rb +0 -118
- data/spec/support/helpers.rb +0 -19
- data/spec/support/jobs.rb +0 -35
- data/spec/support/shared_examples/adapter.rb +0 -37
- data/spec/support/shared_examples/multi_threaded_adapter.rb +0 -46
- data/spec/travis.rb +0 -23
- data/spec/unit/connection_spec.rb +0 -14
- data/spec/unit/customization_spec.rb +0 -251
- data/spec/unit/enqueue_spec.rb +0 -245
- data/spec/unit/helper_spec.rb +0 -12
- data/spec/unit/logging_spec.rb +0 -101
- data/spec/unit/migrations_spec.rb +0 -84
- data/spec/unit/pool_spec.rb +0 -365
- data/spec/unit/run_spec.rb +0 -14
- data/spec/unit/states_spec.rb +0 -50
- data/spec/unit/stats_spec.rb +0 -46
- data/spec/unit/transaction_spec.rb +0 -36
- data/spec/unit/work_spec.rb +0 -407
- data/spec/unit/worker_spec.rb +0 -167
- data/tasks/benchmark.rb +0 -3
- data/tasks/rspec.rb +0 -14
- data/tasks/safe_shutdown.rb +0 -67
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
|
|
5
|
-
describe Que::Migrations do
|
|
6
|
-
it "should be able to perform migrations up and down" do
|
|
7
|
-
# Migration #1 creates the table with a priority default of 1, migration
|
|
8
|
-
# #2 ups that to 100.
|
|
9
|
-
|
|
10
|
-
default = proc do
|
|
11
|
-
result = Que.execute <<-SQL
|
|
12
|
-
select adsrc::integer
|
|
13
|
-
from pg_attribute a
|
|
14
|
-
join pg_class c on c.oid = a.attrelid
|
|
15
|
-
join pg_attrdef on adrelid = attrelid AND adnum = attnum
|
|
16
|
-
where relname = 'que_jobs'
|
|
17
|
-
and attname = 'priority'
|
|
18
|
-
SQL
|
|
19
|
-
|
|
20
|
-
result.first[:adsrc]
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
default.call.should == 100
|
|
24
|
-
Que::Migrations.migrate! :version => 1
|
|
25
|
-
default.call.should == 1
|
|
26
|
-
Que::Migrations.migrate! :version => 2
|
|
27
|
-
default.call.should == 100
|
|
28
|
-
|
|
29
|
-
# Clean up.
|
|
30
|
-
Que.migrate!
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
it "should be able to get and set the current schema version" do
|
|
34
|
-
Que::Migrations.db_version.should == Que::Migrations::CURRENT_VERSION
|
|
35
|
-
Que::Migrations.set_db_version(59328)
|
|
36
|
-
Que::Migrations.db_version.should == 59328
|
|
37
|
-
Que::Migrations.set_db_version(Que::Migrations::CURRENT_VERSION)
|
|
38
|
-
Que::Migrations.db_version.should == Que::Migrations::CURRENT_VERSION
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
it "should be able to cycle the jobs table all the way between nonexistent and current without error" do
|
|
42
|
-
Que::Migrations.db_version.should == Que::Migrations::CURRENT_VERSION
|
|
43
|
-
Que::Migrations.migrate! :version => 0
|
|
44
|
-
Que::Migrations.db_version.should == 0
|
|
45
|
-
Que.db_version.should == 0
|
|
46
|
-
Que::Migrations.migrate!
|
|
47
|
-
Que::Migrations.db_version.should == Que::Migrations::CURRENT_VERSION
|
|
48
|
-
|
|
49
|
-
# The helper on the Que module does the same thing.
|
|
50
|
-
Que.migrate! :version => 0
|
|
51
|
-
Que::Migrations.db_version.should == 0
|
|
52
|
-
Que.migrate!
|
|
53
|
-
Que::Migrations.db_version.should == Que::Migrations::CURRENT_VERSION
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
it "should be able to honor the initial behavior of Que.drop!" do
|
|
57
|
-
DB.table_exists?(:que_jobs).should be true
|
|
58
|
-
Que.drop!
|
|
59
|
-
DB.table_exists?(:que_jobs).should be false
|
|
60
|
-
|
|
61
|
-
# Clean up.
|
|
62
|
-
Que::Migrations.migrate!
|
|
63
|
-
DB.table_exists?(:que_jobs).should be true
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
it "should be able to recognize a que_jobs table created before the versioning system" do
|
|
67
|
-
DB.drop_table :que_jobs
|
|
68
|
-
DB.create_table(:que_jobs){serial :id} # Dummy Table.
|
|
69
|
-
Que::Migrations.db_version.should == 1
|
|
70
|
-
DB.drop_table(:que_jobs)
|
|
71
|
-
Que::Migrations.migrate!
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
it "should be able to honor the initial behavior of Que.create!" do
|
|
75
|
-
DB.drop_table :que_jobs
|
|
76
|
-
Que.create!
|
|
77
|
-
DB.table_exists?(:que_jobs).should be true
|
|
78
|
-
Que::Migrations.db_version.should == 1
|
|
79
|
-
|
|
80
|
-
# Clean up.
|
|
81
|
-
Que::Migrations.migrate!
|
|
82
|
-
DB.table_exists?(:que_jobs).should be true
|
|
83
|
-
end
|
|
84
|
-
end
|
data/spec/unit/pool_spec.rb
DELETED
|
@@ -1,365 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
|
|
5
|
-
describe "Managing the Worker pool" do
|
|
6
|
-
it "should log mode changes" do
|
|
7
|
-
Que.mode = :sync
|
|
8
|
-
Que.mode = :off
|
|
9
|
-
Que.mode = :off
|
|
10
|
-
|
|
11
|
-
$logger.messages.count.should be 3
|
|
12
|
-
m1, m2, m3 = $logger.messages.map { |m| JSON.load(m) }
|
|
13
|
-
|
|
14
|
-
m1['event'].should == 'mode_change'
|
|
15
|
-
m1['value'].should == 'sync'
|
|
16
|
-
|
|
17
|
-
m2['event'].should == 'mode_change'
|
|
18
|
-
m2['value'].should == 'off'
|
|
19
|
-
|
|
20
|
-
m3['event'].should == 'mode_change'
|
|
21
|
-
m3['value'].should == 'off'
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
describe "Que.mode=" do
|
|
25
|
-
describe ":off" do
|
|
26
|
-
it "with worker_count 0 should not instantiate workers or hit the db" do
|
|
27
|
-
Que.connection = nil
|
|
28
|
-
Que.worker_count = 0
|
|
29
|
-
Que.mode = :off
|
|
30
|
-
Que::Worker.workers.should == []
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
it "with worker_count > 0 should not instantiate workers or hit the db" do
|
|
34
|
-
Que.connection = nil
|
|
35
|
-
Que.mode = :off
|
|
36
|
-
Que.worker_count = 5
|
|
37
|
-
Que.mode = :off
|
|
38
|
-
Que::Worker.workers.should == []
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
describe ":sync" do
|
|
43
|
-
it "with worker_count 0 should not instantiate workers or hit the db" do
|
|
44
|
-
Que.connection = nil
|
|
45
|
-
Que.worker_count = 0
|
|
46
|
-
Que.mode = :sync
|
|
47
|
-
Que::Worker.workers.should == []
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
it "with worker_count > 0 should not instantiate workers or hit the db" do
|
|
51
|
-
Que.connection = nil
|
|
52
|
-
Que.mode = :sync
|
|
53
|
-
Que.worker_count = 5
|
|
54
|
-
Que.mode = :sync
|
|
55
|
-
Que::Worker.workers.should == []
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
it "should make jobs run in the same thread as they are queued" do
|
|
59
|
-
Que.mode = :sync
|
|
60
|
-
|
|
61
|
-
ArgsJob.enqueue(5, :testing => "synchronous").should be_an_instance_of ArgsJob
|
|
62
|
-
$passed_args.should == [5, {:testing => "synchronous"}]
|
|
63
|
-
DB[:que_jobs].count.should be 0
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
it "should work fine with enqueuing jobs without a DB connection" do
|
|
67
|
-
Que.connection = nil
|
|
68
|
-
Que.mode = :sync
|
|
69
|
-
|
|
70
|
-
ArgsJob.enqueue(5, :testing => "synchronous").should be_an_instance_of ArgsJob
|
|
71
|
-
$passed_args.should == [5, {:testing => "synchronous"}]
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
it "should not affect jobs that are queued with specific run_ats" do
|
|
75
|
-
Que.mode = :sync
|
|
76
|
-
|
|
77
|
-
ArgsJob.enqueue(5, :testing => "synchronous", :run_at => Time.now + 60)
|
|
78
|
-
DB[:que_jobs].select_map(:job_class).should == ["ArgsJob"]
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
describe ":async" do
|
|
83
|
-
it "with worker_count 0 should not instantiate workers or hit the db" do
|
|
84
|
-
Que.connection = nil
|
|
85
|
-
Que.worker_count = 0
|
|
86
|
-
Que.mode = :async
|
|
87
|
-
Que::Worker.workers.map{|w| [w.state, w.thread.status]}.should == []
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
it "with worker_count > 0 should instantiate workers and hit the db" do
|
|
91
|
-
Que::Job.enqueue
|
|
92
|
-
Que.worker_count = 5
|
|
93
|
-
Que.mode = :async
|
|
94
|
-
sleep_until { Que::Worker.workers.all? &:sleeping? }
|
|
95
|
-
DB[:que_jobs].count.should == 0
|
|
96
|
-
Que::Worker.workers.map{|w| [w.state, w.thread.status]}.should == [[:sleeping, 'sleep']] * 5
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
it "should wake a worker every Que.wake_interval seconds" do
|
|
100
|
-
Que.worker_count = 4
|
|
101
|
-
Que.mode = :async
|
|
102
|
-
sleep_until { Que::Worker.workers.all? &:sleeping? }
|
|
103
|
-
Que.wake_interval = 0.01 # 10 ms
|
|
104
|
-
Que::Job.enqueue
|
|
105
|
-
sleep_until { DB[:que_jobs].count == 0 }
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
it "should work jobs in the queue defined by the Que.queue_name config option" do
|
|
109
|
-
begin
|
|
110
|
-
Que::Job.enqueue 1
|
|
111
|
-
Que::Job.enqueue 2, :queue => 'my_queue'
|
|
112
|
-
|
|
113
|
-
Que.queue_name = 'my_queue'
|
|
114
|
-
|
|
115
|
-
Que.mode = :async
|
|
116
|
-
Que.worker_count = 2
|
|
117
|
-
|
|
118
|
-
sleep_until { Que::Worker.workers.all? &:sleeping? }
|
|
119
|
-
DB[:que_jobs].count.should be 1
|
|
120
|
-
|
|
121
|
-
job = DB[:que_jobs].first
|
|
122
|
-
job[:queue].should == ''
|
|
123
|
-
job[:args].should == '[1]'
|
|
124
|
-
ensure
|
|
125
|
-
Que.queue_name = nil
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
describe "Que.worker_count=" do
|
|
132
|
-
describe "when the mode is :off" do
|
|
133
|
-
it "should record the setting but not instantiate any workers" do
|
|
134
|
-
Que.worker_count.should == 0
|
|
135
|
-
Que.connection = nil
|
|
136
|
-
Que.mode = :off
|
|
137
|
-
Que::Worker.workers.should == []
|
|
138
|
-
|
|
139
|
-
Que.worker_count = 4
|
|
140
|
-
Que.worker_count.should == 4
|
|
141
|
-
Que::Worker.workers.should == []
|
|
142
|
-
|
|
143
|
-
Que.worker_count = 6
|
|
144
|
-
Que.worker_count.should == 6
|
|
145
|
-
Que::Worker.workers.should == []
|
|
146
|
-
|
|
147
|
-
Que.worker_count = 2
|
|
148
|
-
Que.worker_count.should == 2
|
|
149
|
-
Que::Worker.workers.should == []
|
|
150
|
-
|
|
151
|
-
Que.worker_count = 0
|
|
152
|
-
Que.worker_count.should == 0
|
|
153
|
-
Que::Worker.workers.should == []
|
|
154
|
-
end
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
describe "when the mode is :sync" do
|
|
158
|
-
it "should record the setting but not instantiate any workers" do
|
|
159
|
-
Que.worker_count.should == 0
|
|
160
|
-
Que.connection = nil
|
|
161
|
-
Que.mode = :sync
|
|
162
|
-
Que::Worker.workers.should == []
|
|
163
|
-
|
|
164
|
-
Que.worker_count = 4
|
|
165
|
-
Que.worker_count.should == 4
|
|
166
|
-
Que::Worker.workers.should == []
|
|
167
|
-
|
|
168
|
-
Que.worker_count = 6
|
|
169
|
-
Que.worker_count.should == 6
|
|
170
|
-
Que::Worker.workers.should == []
|
|
171
|
-
|
|
172
|
-
Que.worker_count = 2
|
|
173
|
-
Que.worker_count.should == 2
|
|
174
|
-
Que::Worker.workers.should == []
|
|
175
|
-
|
|
176
|
-
Que.worker_count = 0
|
|
177
|
-
Que.worker_count.should == 0
|
|
178
|
-
Que::Worker.workers.should == []
|
|
179
|
-
end
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
describe "when the mode is :async" do
|
|
183
|
-
it "should start hitting the DB when transitioning to a non-zero value" do
|
|
184
|
-
Que.mode = :async
|
|
185
|
-
Que::Job.enqueue
|
|
186
|
-
Que.worker_count = 4
|
|
187
|
-
sleep_until { Que::Worker.workers.all?(&:sleeping?) }
|
|
188
|
-
Que::Worker.workers.map{|w| [w.state, w.thread.status]}.should == [[:sleeping, 'sleep']] * 4
|
|
189
|
-
DB[:que_jobs].count.should == 0
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
it "should stop hitting the DB when transitioning to zero" do
|
|
193
|
-
Que.mode = :async
|
|
194
|
-
Que.worker_count = 4
|
|
195
|
-
sleep_until { Que::Worker.workers.all?(&:sleeping?) }
|
|
196
|
-
Que.connection = nil
|
|
197
|
-
Que.worker_count = 0
|
|
198
|
-
$logger.messages.map{|m| JSON.load(m).values_at('event', 'value')}.should ==
|
|
199
|
-
[['mode_change', 'async'], ['worker_count_change', '4']] + [['job_unavailable', nil]] * 4 + [['worker_count_change', '0']]
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
it "should be able to scale down the number of workers gracefully" do
|
|
203
|
-
Que.mode = :async
|
|
204
|
-
Que.worker_count = 4
|
|
205
|
-
|
|
206
|
-
workers = Que::Worker.workers.dup
|
|
207
|
-
workers.count.should be 4
|
|
208
|
-
sleep_until { Que::Worker.workers.all?(&:sleeping?) }
|
|
209
|
-
|
|
210
|
-
Que.worker_count = 2
|
|
211
|
-
Que::Worker.workers.count.should be 2
|
|
212
|
-
sleep_until { Que::Worker.workers.all?(&:sleeping?) }
|
|
213
|
-
|
|
214
|
-
workers[0..1].should == Que::Worker.workers
|
|
215
|
-
workers[2..3].each do |worker|
|
|
216
|
-
worker.should be_an_instance_of Que::Worker
|
|
217
|
-
worker.thread.status.should == false
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
$logger.messages.map{|m| JSON.load(m).values_at('event', 'value')}.should ==
|
|
221
|
-
[['mode_change', 'async'], ['worker_count_change', '4']] + [['job_unavailable', nil]] * 4 + [['worker_count_change', '2']]
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
it "should be able to scale up the number of workers gracefully" do
|
|
225
|
-
Que.mode = :async
|
|
226
|
-
Que.worker_count = 4
|
|
227
|
-
workers = Que::Worker.workers.dup
|
|
228
|
-
workers.count.should be 4
|
|
229
|
-
|
|
230
|
-
sleep_until { Que::Worker.workers.all?(&:sleeping?) }
|
|
231
|
-
Que.worker_count = 6
|
|
232
|
-
Que::Worker.workers.count.should be 6
|
|
233
|
-
sleep_until { Que::Worker.workers.all?(&:sleeping?) }
|
|
234
|
-
|
|
235
|
-
workers.should == Que::Worker.workers[0..3]
|
|
236
|
-
|
|
237
|
-
$logger.messages.map{|m| JSON.load(m).values_at('event', 'value')}.should ==
|
|
238
|
-
[['mode_change', 'async'], ['worker_count_change', '4']] + [['job_unavailable', nil]] * 4 + [['worker_count_change', '6']] + [['job_unavailable', nil]] * 2
|
|
239
|
-
end
|
|
240
|
-
end
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
describe "Que.wake!" do
|
|
244
|
-
it "when mode = :off should do nothing" do
|
|
245
|
-
Que.connection = nil
|
|
246
|
-
Que.mode = :off
|
|
247
|
-
Que.worker_count = 4
|
|
248
|
-
sleep_until { Que::Worker.workers.all? &:sleeping? }
|
|
249
|
-
Que.wake!
|
|
250
|
-
sleep_until { Que::Worker.workers.all? &:sleeping? }
|
|
251
|
-
$logger.messages.map{|m| JSON.load(m).values_at('event', 'value')}.should ==
|
|
252
|
-
[['mode_change', 'off'], ['worker_count_change', '4']]
|
|
253
|
-
end
|
|
254
|
-
|
|
255
|
-
it "when mode = :sync should do nothing" do
|
|
256
|
-
Que.connection = nil
|
|
257
|
-
Que.mode = :sync
|
|
258
|
-
Que.worker_count = 4
|
|
259
|
-
sleep_until { Que::Worker.workers.all? &:sleeping? }
|
|
260
|
-
Que.wake!
|
|
261
|
-
sleep_until { Que::Worker.workers.all? &:sleeping? }
|
|
262
|
-
$logger.messages.map{|m| JSON.load(m).values_at('event', 'value')}.should ==
|
|
263
|
-
[['mode_change', 'sync'], ['worker_count_change', '4']]
|
|
264
|
-
end
|
|
265
|
-
|
|
266
|
-
it "when mode = :async and worker_count = 0 should do nothing" do
|
|
267
|
-
Que.connection = nil
|
|
268
|
-
Que.mode = :async
|
|
269
|
-
Que.worker_count = 0
|
|
270
|
-
sleep_until { Que::Worker.workers.all? &:sleeping? }
|
|
271
|
-
Que.wake!
|
|
272
|
-
sleep_until { Que::Worker.workers.all? &:sleeping? }
|
|
273
|
-
$logger.messages.map{|m| JSON.load(m).values_at('event', 'value')}.should ==
|
|
274
|
-
[['mode_change', 'async'], ['worker_count_change', '0']]
|
|
275
|
-
end
|
|
276
|
-
|
|
277
|
-
it "when mode = :async and worker_count > 0 should wake up a single worker" do
|
|
278
|
-
Que.mode = :async
|
|
279
|
-
Que.worker_count = 4
|
|
280
|
-
sleep_until { Que::Worker.workers.all? &:sleeping? }
|
|
281
|
-
|
|
282
|
-
BlockJob.enqueue
|
|
283
|
-
Que.wake!
|
|
284
|
-
|
|
285
|
-
$q1.pop
|
|
286
|
-
Que::Worker.workers.first.should be_working
|
|
287
|
-
Que::Worker.workers[1..3].each { |w| w.should be_sleeping }
|
|
288
|
-
DB[:que_jobs].count.should be 1
|
|
289
|
-
$q2.push nil
|
|
290
|
-
|
|
291
|
-
sleep_until { Que::Worker.workers.all? &:sleeping? }
|
|
292
|
-
DB[:que_jobs].count.should be 0
|
|
293
|
-
end
|
|
294
|
-
|
|
295
|
-
it "when mode = :async and worker_count > 0 should be thread-safe" do
|
|
296
|
-
Que.mode = :async
|
|
297
|
-
Que.worker_count = 4
|
|
298
|
-
sleep_until { Que::Worker.workers.all? &:sleeping? }
|
|
299
|
-
threads = 4.times.map { Thread.new { 100.times { Que.wake! } } }
|
|
300
|
-
threads.each(&:join)
|
|
301
|
-
end
|
|
302
|
-
end
|
|
303
|
-
|
|
304
|
-
describe "Que.wake_all!" do
|
|
305
|
-
it "when mode = :off should do nothing" do
|
|
306
|
-
Que.connection = nil
|
|
307
|
-
Que.mode = :off
|
|
308
|
-
Que.worker_count = 4
|
|
309
|
-
sleep_until { Que::Worker.workers.all? &:sleeping? }
|
|
310
|
-
Que.wake_all!
|
|
311
|
-
sleep_until { Que::Worker.workers.all? &:sleeping? }
|
|
312
|
-
$logger.messages.map{|m| JSON.load(m).values_at('event', 'value')}.should ==
|
|
313
|
-
[['mode_change', 'off'], ['worker_count_change', '4']]
|
|
314
|
-
end
|
|
315
|
-
|
|
316
|
-
it "when mode = :sync should do nothing" do
|
|
317
|
-
Que.connection = nil
|
|
318
|
-
Que.mode = :sync
|
|
319
|
-
Que.worker_count = 4
|
|
320
|
-
sleep_until { Que::Worker.workers.all? &:sleeping? }
|
|
321
|
-
Que.wake_all!
|
|
322
|
-
sleep_until { Que::Worker.workers.all? &:sleeping? }
|
|
323
|
-
$logger.messages.map{|m| JSON.load(m).values_at('event', 'value')}.should ==
|
|
324
|
-
[['mode_change', 'sync'], ['worker_count_change', '4']]
|
|
325
|
-
end
|
|
326
|
-
|
|
327
|
-
it "when mode = :async and worker_count = 0 should do nothing" do
|
|
328
|
-
Que.connection = nil
|
|
329
|
-
Que.mode = :async
|
|
330
|
-
Que.worker_count = 0
|
|
331
|
-
sleep_until { Que::Worker.workers.all? &:sleeping? }
|
|
332
|
-
Que.wake_all!
|
|
333
|
-
sleep_until { Que::Worker.workers.all? &:sleeping? }
|
|
334
|
-
$logger.messages.map{|m| JSON.load(m).values_at('event', 'value')}.should ==
|
|
335
|
-
[['mode_change', 'async'], ['worker_count_change', '0']]
|
|
336
|
-
end
|
|
337
|
-
|
|
338
|
-
# This spec requires at least four connections.
|
|
339
|
-
it "when mode = :async and worker_count > 0 should wake up all workers" do
|
|
340
|
-
Que.adapter = QUE_ADAPTERS[:pond]
|
|
341
|
-
|
|
342
|
-
Que.mode = :async
|
|
343
|
-
Que.worker_count = 4
|
|
344
|
-
sleep_until { Que::Worker.workers.all? &:sleeping? }
|
|
345
|
-
|
|
346
|
-
4.times { BlockJob.enqueue }
|
|
347
|
-
Que.wake_all!
|
|
348
|
-
4.times { $q1.pop }
|
|
349
|
-
|
|
350
|
-
Que::Worker.workers.each{ |worker| worker.should be_working }
|
|
351
|
-
4.times { $q2.push nil }
|
|
352
|
-
|
|
353
|
-
sleep_until { Que::Worker.workers.all? &:sleeping? }
|
|
354
|
-
DB[:que_jobs].count.should be 0
|
|
355
|
-
end if QUE_ADAPTERS[:pond]
|
|
356
|
-
|
|
357
|
-
it "when mode = :async and worker_count > 0 should be thread-safe" do
|
|
358
|
-
Que.mode = :async
|
|
359
|
-
Que.worker_count = 4
|
|
360
|
-
sleep_until { Que::Worker.workers.all? &:sleeping? }
|
|
361
|
-
threads = 4.times.map { Thread.new { 100.times { Que.wake_all! } } }
|
|
362
|
-
threads.each(&:join)
|
|
363
|
-
end
|
|
364
|
-
end
|
|
365
|
-
end
|
data/spec/unit/run_spec.rb
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
|
|
5
|
-
describe Que::Job, '.run' do
|
|
6
|
-
it "should immediately process the job with the arguments given to it" do
|
|
7
|
-
result = ArgsJob.run 1, 'two', {:three => 3}
|
|
8
|
-
result.should be_an_instance_of ArgsJob
|
|
9
|
-
result.attrs[:args].should == [1, 'two', {:three => 3}]
|
|
10
|
-
|
|
11
|
-
DB[:que_jobs].count.should be 0
|
|
12
|
-
$passed_args.should == [1, 'two', {:three => 3}]
|
|
13
|
-
end
|
|
14
|
-
end
|
data/spec/unit/states_spec.rb
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
|
|
5
|
-
describe Que, '.worker_states' do
|
|
6
|
-
it "should return a list of the job types in the queue, their counts and the number of each currently running" do
|
|
7
|
-
Que.adapter = QUE_ADAPTERS[:connection_pool]
|
|
8
|
-
|
|
9
|
-
class WorkerStateJob < BlockJob
|
|
10
|
-
def run
|
|
11
|
-
$pid = Que.execute("select pg_backend_pid()").first[:pg_backend_pid]
|
|
12
|
-
super
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
WorkerStateJob.enqueue :priority => 2
|
|
17
|
-
|
|
18
|
-
# Ensure that the portion of the SQL query that accounts for bigint
|
|
19
|
-
# job_ids functions correctly.
|
|
20
|
-
DB[:que_jobs].update(:job_id => 2**33)
|
|
21
|
-
|
|
22
|
-
t = Thread.new { Que::Job.work }
|
|
23
|
-
$q1.pop
|
|
24
|
-
|
|
25
|
-
states = Que.worker_states
|
|
26
|
-
states.length.should be 1
|
|
27
|
-
|
|
28
|
-
$q2.push nil
|
|
29
|
-
t.join
|
|
30
|
-
|
|
31
|
-
state = states.first
|
|
32
|
-
state.keys.should == %w(priority run_at job_id job_class args error_count last_error queue pg_backend_pid pg_state pg_state_changed_at pg_last_query pg_last_query_started_at pg_transaction_started_at pg_waiting_on_lock)
|
|
33
|
-
|
|
34
|
-
state[:priority].should == 2
|
|
35
|
-
state[:run_at].should be_within(3).of Time.now
|
|
36
|
-
state[:job_id].should == 2**33
|
|
37
|
-
state[:job_class].should == 'WorkerStateJob'
|
|
38
|
-
state[:args].should == []
|
|
39
|
-
state[:error_count].should == 0
|
|
40
|
-
state[:last_error].should be nil
|
|
41
|
-
|
|
42
|
-
state[:pg_backend_pid].should == $pid
|
|
43
|
-
state[:pg_state].should == 'idle'
|
|
44
|
-
state[:pg_state_changed_at].should be_within(3).of Time.now
|
|
45
|
-
state[:pg_last_query].should == 'select pg_backend_pid()'
|
|
46
|
-
state[:pg_last_query_started_at].should be_within(3).of Time.now
|
|
47
|
-
state[:pg_transaction_started_at].should == nil
|
|
48
|
-
state[:pg_waiting_on_lock].should == false
|
|
49
|
-
end if QUE_ADAPTERS[:connection_pool]
|
|
50
|
-
end
|
data/spec/unit/stats_spec.rb
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
|
|
5
|
-
describe Que, '.job_stats' do
|
|
6
|
-
it "should return a list of the job types in the queue, their counts and the number of each currently running" do
|
|
7
|
-
BlockJob.enqueue
|
|
8
|
-
Que::Job.enqueue
|
|
9
|
-
|
|
10
|
-
# Have to tweak the job_id to ensure that the portion of the SQL query
|
|
11
|
-
# that accounts for bigint job_ids functions correctly.
|
|
12
|
-
old = Time.now - 3600
|
|
13
|
-
DB[:que_jobs].where(:job_class => "Que::Job").update(:job_id => 2**33, :error_count => 5, :run_at => old)
|
|
14
|
-
|
|
15
|
-
Que::Job.enqueue
|
|
16
|
-
|
|
17
|
-
begin
|
|
18
|
-
DB.get{pg_advisory_lock(2**33)}
|
|
19
|
-
|
|
20
|
-
stats = Que.job_stats
|
|
21
|
-
stats.length.should == 2
|
|
22
|
-
|
|
23
|
-
qj, bj = stats
|
|
24
|
-
|
|
25
|
-
qj.keys.should == %w(queue job_class count count_working count_errored highest_error_count oldest_run_at)
|
|
26
|
-
|
|
27
|
-
qj[:queue].should == ''
|
|
28
|
-
qj[:job_class].should == 'Que::Job'
|
|
29
|
-
qj[:count].should == 2
|
|
30
|
-
qj[:count_working].should == 1
|
|
31
|
-
qj[:count_errored].should == 1
|
|
32
|
-
qj[:highest_error_count].should == 5
|
|
33
|
-
qj[:oldest_run_at].should be_within(3).of old
|
|
34
|
-
|
|
35
|
-
bj[:queue].should == ''
|
|
36
|
-
bj[:job_class].should == 'BlockJob'
|
|
37
|
-
bj[:count].should == 1
|
|
38
|
-
bj[:count_working].should == 0
|
|
39
|
-
bj[:count_errored].should == 0
|
|
40
|
-
bj[:highest_error_count].should == 0
|
|
41
|
-
bj[:oldest_run_at].should be_within(3).of Time.now
|
|
42
|
-
ensure
|
|
43
|
-
DB.get{pg_advisory_unlock_all{}}
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
|
|
5
|
-
describe Que, '.transaction' do
|
|
6
|
-
it "should use a transaction to rollback changes in the event of an error" do
|
|
7
|
-
proc do
|
|
8
|
-
Que.transaction do
|
|
9
|
-
Que.execute "DROP TABLE que_jobs"
|
|
10
|
-
Que.execute "invalid SQL syntax"
|
|
11
|
-
end
|
|
12
|
-
end.should raise_error(PG::Error)
|
|
13
|
-
|
|
14
|
-
DB.table_exists?(:que_jobs).should be true
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
unless RUBY_VERSION.start_with?('1.9')
|
|
18
|
-
it "should rollback correctly in the event of a killed thread" do
|
|
19
|
-
q = Queue.new
|
|
20
|
-
|
|
21
|
-
t = Thread.new do
|
|
22
|
-
Que.transaction do
|
|
23
|
-
Que.execute "DROP TABLE que_jobs"
|
|
24
|
-
q.push :go!
|
|
25
|
-
sleep
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
q.pop
|
|
30
|
-
t.kill
|
|
31
|
-
t.join
|
|
32
|
-
|
|
33
|
-
DB.table_exists?(:que_jobs).should be true
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|