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.
Files changed (114) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/tests.yml +51 -0
  3. data/.gitignore +2 -0
  4. data/.ruby-version +1 -0
  5. data/CHANGELOG.md +502 -97
  6. data/Dockerfile +20 -0
  7. data/LICENSE.txt +1 -1
  8. data/README.md +205 -59
  9. data/auto/dev +21 -0
  10. data/auto/pre-push-hook +30 -0
  11. data/auto/psql +9 -0
  12. data/auto/test +5 -0
  13. data/auto/test-postgres-14 +17 -0
  14. data/bin/que +8 -81
  15. data/docker-compose.yml +47 -0
  16. data/docs/README.md +881 -0
  17. data/lib/que/active_job/extensions.rb +114 -0
  18. data/lib/que/active_record/connection.rb +51 -0
  19. data/lib/que/active_record/model.rb +48 -0
  20. data/lib/que/command_line_interface.rb +259 -0
  21. data/lib/que/connection.rb +198 -0
  22. data/lib/que/connection_pool.rb +78 -0
  23. data/lib/que/job.rb +210 -103
  24. data/lib/que/job_buffer.rb +255 -0
  25. data/lib/que/job_methods.rb +176 -0
  26. data/lib/que/listener.rb +176 -0
  27. data/lib/que/locker.rb +507 -0
  28. data/lib/que/metajob.rb +47 -0
  29. data/lib/que/migrations/4/down.sql +48 -0
  30. data/lib/que/migrations/4/up.sql +267 -0
  31. data/lib/que/migrations/5/down.sql +73 -0
  32. data/lib/que/migrations/5/up.sql +76 -0
  33. data/lib/que/migrations/6/down.sql +8 -0
  34. data/lib/que/migrations/6/up.sql +8 -0
  35. data/lib/que/migrations/7/down.sql +5 -0
  36. data/lib/que/migrations/7/up.sql +13 -0
  37. data/lib/que/migrations.rb +37 -18
  38. data/lib/que/poller.rb +274 -0
  39. data/lib/que/rails/railtie.rb +12 -0
  40. data/lib/que/result_queue.rb +35 -0
  41. data/lib/que/sequel/model.rb +52 -0
  42. data/lib/que/utils/assertions.rb +62 -0
  43. data/lib/que/utils/constantization.rb +19 -0
  44. data/lib/que/utils/error_notification.rb +68 -0
  45. data/lib/que/utils/freeze.rb +20 -0
  46. data/lib/que/utils/introspection.rb +50 -0
  47. data/lib/que/utils/json_serialization.rb +21 -0
  48. data/lib/que/utils/logging.rb +79 -0
  49. data/lib/que/utils/middleware.rb +46 -0
  50. data/lib/que/utils/queue_management.rb +18 -0
  51. data/lib/que/utils/ruby2_keywords.rb +19 -0
  52. data/lib/que/utils/transactions.rb +34 -0
  53. data/lib/que/version.rb +5 -1
  54. data/lib/que/worker.rb +145 -149
  55. data/lib/que.rb +103 -159
  56. data/que.gemspec +17 -4
  57. data/scripts/docker-entrypoint +14 -0
  58. data/scripts/test +6 -0
  59. metadata +59 -95
  60. data/.rspec +0 -2
  61. data/.travis.yml +0 -17
  62. data/Gemfile +0 -24
  63. data/docs/advanced_setup.md +0 -106
  64. data/docs/customizing_que.md +0 -200
  65. data/docs/error_handling.md +0 -47
  66. data/docs/inspecting_the_queue.md +0 -114
  67. data/docs/logging.md +0 -50
  68. data/docs/managing_workers.md +0 -80
  69. data/docs/migrating.md +0 -30
  70. data/docs/multiple_queues.md +0 -27
  71. data/docs/shutting_down_safely.md +0 -7
  72. data/docs/using_plain_connections.md +0 -41
  73. data/docs/using_sequel.md +0 -31
  74. data/docs/writing_reliable_jobs.md +0 -117
  75. data/lib/generators/que/install_generator.rb +0 -24
  76. data/lib/generators/que/templates/add_que.rb +0 -13
  77. data/lib/que/adapters/active_record.rb +0 -54
  78. data/lib/que/adapters/base.rb +0 -127
  79. data/lib/que/adapters/connection_pool.rb +0 -16
  80. data/lib/que/adapters/pg.rb +0 -21
  81. data/lib/que/adapters/pond.rb +0 -16
  82. data/lib/que/adapters/sequel.rb +0 -20
  83. data/lib/que/railtie.rb +0 -16
  84. data/lib/que/rake_tasks.rb +0 -59
  85. data/lib/que/sql.rb +0 -152
  86. data/spec/adapters/active_record_spec.rb +0 -152
  87. data/spec/adapters/connection_pool_spec.rb +0 -22
  88. data/spec/adapters/pg_spec.rb +0 -41
  89. data/spec/adapters/pond_spec.rb +0 -22
  90. data/spec/adapters/sequel_spec.rb +0 -57
  91. data/spec/gemfiles/Gemfile1 +0 -18
  92. data/spec/gemfiles/Gemfile2 +0 -18
  93. data/spec/spec_helper.rb +0 -118
  94. data/spec/support/helpers.rb +0 -19
  95. data/spec/support/jobs.rb +0 -35
  96. data/spec/support/shared_examples/adapter.rb +0 -37
  97. data/spec/support/shared_examples/multi_threaded_adapter.rb +0 -46
  98. data/spec/travis.rb +0 -23
  99. data/spec/unit/connection_spec.rb +0 -14
  100. data/spec/unit/customization_spec.rb +0 -251
  101. data/spec/unit/enqueue_spec.rb +0 -245
  102. data/spec/unit/helper_spec.rb +0 -12
  103. data/spec/unit/logging_spec.rb +0 -101
  104. data/spec/unit/migrations_spec.rb +0 -84
  105. data/spec/unit/pool_spec.rb +0 -365
  106. data/spec/unit/run_spec.rb +0 -14
  107. data/spec/unit/states_spec.rb +0 -50
  108. data/spec/unit/stats_spec.rb +0 -46
  109. data/spec/unit/transaction_spec.rb +0 -36
  110. data/spec/unit/work_spec.rb +0 -407
  111. data/spec/unit/worker_spec.rb +0 -167
  112. data/tasks/benchmark.rb +0 -3
  113. data/tasks/rspec.rb +0 -14
  114. 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
@@ -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
@@ -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
@@ -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
@@ -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