queue_classic 3.1.0.RC1 → 4.0.0.pre.beta1
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/.circleci/config.yml +192 -0
- data/.gitignore +11 -0
- data/CHANGELOG.md +192 -0
- data/CODE_OF_CONDUCT.md +46 -0
- data/CONTRIBUTING.md +17 -0
- data/Gemfile +12 -0
- data/LICENSE.txt +20 -0
- data/{readme.md → README.md} +120 -83
- data/Rakefile +16 -0
- data/lib/generators/queue_classic/install_generator.rb +6 -0
- data/lib/generators/queue_classic/templates/add_queue_classic.rb +3 -1
- data/lib/generators/queue_classic/templates/update_queue_classic_3_0_0.rb +3 -1
- data/lib/generators/queue_classic/templates/update_queue_classic_3_0_2.rb +3 -1
- data/lib/generators/queue_classic/templates/update_queue_classic_3_1_0.rb +3 -1
- data/lib/generators/queue_classic/templates/update_queue_classic_4_0_0.rb +11 -0
- data/lib/queue_classic/config.rb +86 -0
- data/lib/queue_classic/conn_adapter.rb +37 -16
- data/lib/queue_classic/queue.rb +76 -18
- data/lib/queue_classic/railtie.rb +2 -0
- data/lib/queue_classic/setup.rb +24 -7
- data/lib/queue_classic/tasks.rb +7 -8
- data/lib/queue_classic/version.rb +5 -0
- data/lib/queue_classic/worker.rb +18 -12
- data/lib/queue_classic.rb +50 -58
- data/queue_classic.gemspec +25 -0
- data/sql/create_table.sql +7 -14
- data/sql/ddl.sql +6 -82
- data/sql/downgrade_from_4_0_0.sql +88 -0
- data/sql/update_to_3_0_0.sql +5 -5
- data/sql/update_to_3_1_0.sql +6 -6
- data/sql/update_to_4_0_0.sql +6 -0
- data/test/benchmark_test.rb +15 -12
- data/test/config_test.rb +123 -0
- data/test/helper.rb +47 -3
- data/test/helper.sql +25 -0
- data/test/lib/queue_classic_rails_connection_test.rb +16 -10
- data/test/lib/queue_classic_test.rb +15 -3
- data/test/lib/queue_classic_test_with_activerecord_typecast.rb +21 -0
- data/test/queue_test.rb +127 -4
- data/test/rails-tests/.gitignore +2 -0
- data/test/rails-tests/rails523.sh +23 -0
- data/test/worker_test.rb +153 -35
- metadata +51 -7
data/test/queue_test.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'helper'
|
2
4
|
|
3
5
|
class QueueTest < QCTest
|
4
6
|
|
5
|
-
ResetError = Class.new(
|
7
|
+
ResetError = Class.new(PG::Error)
|
6
8
|
|
7
9
|
def test_enqueue
|
8
10
|
QC.enqueue("Klass.method")
|
@@ -28,12 +30,14 @@ class QueueTest < QCTest
|
|
28
30
|
end
|
29
31
|
|
30
32
|
def test_lock_with_future_job_with_enqueue_in
|
33
|
+
now = Time.now
|
31
34
|
QC.enqueue_in(2, "Klass.method")
|
32
35
|
assert_nil QC.lock
|
33
36
|
sleep 2
|
34
37
|
job = QC.lock
|
35
38
|
assert_equal("Klass.method", job[:method])
|
36
39
|
assert_equal([], job[:args])
|
40
|
+
assert_equal((now + 2).to_i, job[:scheduled_at].to_i)
|
37
41
|
end
|
38
42
|
|
39
43
|
def test_lock_with_future_job_with_enqueue_at_with_a_time_object
|
@@ -44,6 +48,7 @@ class QueueTest < QCTest
|
|
44
48
|
job = QC.lock
|
45
49
|
assert_equal("Klass.method", job[:method])
|
46
50
|
assert_equal([], job[:args])
|
51
|
+
assert_equal(future.to_i, job[:scheduled_at].to_i)
|
47
52
|
end
|
48
53
|
|
49
54
|
def test_lock_with_future_job_with_enqueue_at_with_a_float_timestamp
|
@@ -59,6 +64,20 @@ class QueueTest < QCTest
|
|
59
64
|
def test_count
|
60
65
|
QC.enqueue("Klass.method")
|
61
66
|
assert_equal(1, QC.count)
|
67
|
+
|
68
|
+
QC.enqueue("Klass.method")
|
69
|
+
assert_equal(2, QC.count)
|
70
|
+
assert_equal(2, QC.count_ready)
|
71
|
+
assert_equal(0, QC.count_scheduled)
|
72
|
+
|
73
|
+
QC.enqueue_in(60, "Klass.method")
|
74
|
+
assert_equal(3, QC.count)
|
75
|
+
assert_equal(2, QC.count_ready)
|
76
|
+
assert_equal(1, QC.count_scheduled)
|
77
|
+
|
78
|
+
assert_raises(ArgumentError) do
|
79
|
+
QC.count(:potatoes)
|
80
|
+
end
|
62
81
|
end
|
63
82
|
|
64
83
|
def test_delete
|
@@ -102,13 +121,57 @@ class QueueTest < QCTest
|
|
102
121
|
queue.enqueue("Klass.method")
|
103
122
|
assert_equal(1, queue.count)
|
104
123
|
conn = queue.conn_adapter.connection
|
105
|
-
def conn.exec(*args); raise(
|
124
|
+
def conn.exec(*args); raise(PG::Error); end
|
106
125
|
def conn.reset(*args); raise(ResetError) end
|
107
126
|
# We ensure that the reset method is called on the connection.
|
108
127
|
assert_raises(PG::Error, ResetError) {queue.enqueue("Klass.other_method")}
|
109
128
|
queue.conn_adapter.disconnect
|
110
129
|
end
|
111
130
|
|
131
|
+
def test_enqueue_retry
|
132
|
+
queue = QC::Queue.new("queue_classic_jobs")
|
133
|
+
queue.conn_adapter = QC::ConnAdapter.new
|
134
|
+
conn = queue.conn_adapter.connection
|
135
|
+
conn.exec('select pg_terminate_backend(pg_backend_pid())') rescue nil
|
136
|
+
queue.enqueue("Klass.method")
|
137
|
+
assert_equal(1, queue.count)
|
138
|
+
queue.conn_adapter.disconnect
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_enqueue_stops_retrying_on_permanent_error
|
142
|
+
queue = QC::Queue.new("queue_classic_jobs")
|
143
|
+
queue.conn_adapter = QC::ConnAdapter.new
|
144
|
+
conn = queue.conn_adapter.connection
|
145
|
+
conn.exec('select pg_terminate_backend(pg_backend_pid())') rescue nil
|
146
|
+
# Simulate permanent connection error
|
147
|
+
def conn.exec(*args); raise(PG::Error); end
|
148
|
+
# Ensure that the error is reraised on second time
|
149
|
+
assert_raises(PG::Error) {queue.enqueue("Klass.other_method")}
|
150
|
+
queue.conn_adapter.disconnect
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_enqueue_in_retry
|
154
|
+
queue = QC::Queue.new("queue_classic_jobs")
|
155
|
+
queue.conn_adapter = QC::ConnAdapter.new
|
156
|
+
conn = queue.conn_adapter.connection
|
157
|
+
conn.exec('select pg_terminate_backend(pg_backend_pid())') rescue nil
|
158
|
+
queue.enqueue_in(10,"Klass.method")
|
159
|
+
assert_equal(1, queue.count)
|
160
|
+
queue.conn_adapter.disconnect
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_enqueue_in_stops_retrying_on_permanent_error
|
164
|
+
queue = QC::Queue.new("queue_classic_jobs")
|
165
|
+
queue.conn_adapter = QC::ConnAdapter.new
|
166
|
+
conn = queue.conn_adapter.connection
|
167
|
+
conn.exec('select pg_terminate_backend(pg_backend_pid())') rescue nil
|
168
|
+
# Simulate permanent connection error
|
169
|
+
def conn.exec(*args); raise(PG::Error); end
|
170
|
+
# Ensure that the error is reraised on second time
|
171
|
+
assert_raises(PG::Error) {queue.enqueue_in(10,"Klass.method")}
|
172
|
+
queue.conn_adapter.disconnect
|
173
|
+
end
|
174
|
+
|
112
175
|
def test_custom_default_queue
|
113
176
|
queue_class = Class.new do
|
114
177
|
attr_accessor :jobs
|
@@ -129,9 +192,50 @@ class QueueTest < QCTest
|
|
129
192
|
QC.default_queue = nil
|
130
193
|
end
|
131
194
|
|
195
|
+
def test_multi_threaded_server_can_specified_connection
|
196
|
+
adapter1 = QC::ConnAdapter.new
|
197
|
+
adapter2 = QC::ConnAdapter.new
|
198
|
+
q1 = q2 = nil
|
199
|
+
|
200
|
+
QC.default_conn_adapter = adapter1
|
201
|
+
|
202
|
+
t1 = Thread.new do
|
203
|
+
QC.default_conn_adapter = adapter1
|
204
|
+
q1 = QC::Queue.new('queue1').conn_adapter
|
205
|
+
end
|
206
|
+
|
207
|
+
t2 = Thread.new do
|
208
|
+
QC.default_conn_adapter = adapter2
|
209
|
+
q2 = QC::Queue.new('queue2').conn_adapter
|
210
|
+
end
|
211
|
+
|
212
|
+
t1.join
|
213
|
+
t2.join
|
214
|
+
|
215
|
+
assert_equal adapter1, q1
|
216
|
+
assert_equal adapter2, q2
|
217
|
+
end
|
218
|
+
|
219
|
+
def test_multi_threaded_server_each_thread_acquires_unique_connection
|
220
|
+
q1 = q2 = nil
|
221
|
+
|
222
|
+
t1 = Thread.new do
|
223
|
+
q1 = QC::Queue.new('queue1').conn_adapter
|
224
|
+
end
|
225
|
+
|
226
|
+
t2 = Thread.new do
|
227
|
+
q2 = QC::Queue.new('queue2').conn_adapter
|
228
|
+
end
|
229
|
+
|
230
|
+
t1.join
|
231
|
+
t2.join
|
232
|
+
|
233
|
+
refute_equal q1, q2
|
234
|
+
end
|
235
|
+
|
132
236
|
def test_enqueue_triggers_notify
|
133
237
|
adapter = QC.default_conn_adapter
|
134
|
-
adapter.execute('LISTEN "' + QC
|
238
|
+
adapter.execute('LISTEN "' + QC.queue + '"')
|
135
239
|
adapter.send(:drain_notify)
|
136
240
|
|
137
241
|
msgs = adapter.send(:wait_for_notify, 0.25)
|
@@ -142,4 +246,23 @@ class QueueTest < QCTest
|
|
142
246
|
assert_equal(1, msgs.length)
|
143
247
|
end
|
144
248
|
|
249
|
+
def test_enqueue_returns_job_id
|
250
|
+
enqueued_job = QC.enqueue("Klass.method")
|
251
|
+
locked_job = QC.lock
|
252
|
+
assert_equal enqueued_job, "id" => locked_job[:id]
|
253
|
+
end
|
254
|
+
|
255
|
+
def test_enqueue_in_returns_job_id
|
256
|
+
enqueued_job = QC.enqueue_in(1, "Klass.method")
|
257
|
+
sleep 1
|
258
|
+
locked_job = QC.lock
|
259
|
+
assert_equal enqueued_job, "id" => locked_job[:id]
|
260
|
+
end
|
261
|
+
|
262
|
+
def test_enqueue_at_returns_job_id
|
263
|
+
enqueued_job = QC.enqueue_at(Time.now + 1, "Klass.method")
|
264
|
+
sleep 1
|
265
|
+
locked_job = QC.lock
|
266
|
+
assert_equal enqueued_job, "id" => locked_job[:id]
|
267
|
+
end
|
145
268
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
set -e
|
3
|
+
|
4
|
+
# remove any old folder, should only matter locally
|
5
|
+
rm -rf qctest523
|
6
|
+
|
7
|
+
# install rails but not with much stuff
|
8
|
+
gem install rails -v 5.2.3
|
9
|
+
rails new qctest523 --api --database=postgresql --skip-test-unit --skip-keeps --skip-spring --skip-sprockets --skip-javascript --skip-turbolinks
|
10
|
+
cd qctest523
|
11
|
+
|
12
|
+
# get the db setup, run any default migrations
|
13
|
+
bundle install
|
14
|
+
bundle exec rails db:drop:all
|
15
|
+
bundle exec rails db:create
|
16
|
+
bundle exec rails db:migrate
|
17
|
+
bundle exec rails db:setup
|
18
|
+
|
19
|
+
# install qc --> gem file, bundle, add ourselves and migrate.
|
20
|
+
echo "gem 'queue_classic', path: '../../../'" >> Gemfile
|
21
|
+
bundle install
|
22
|
+
bundle exec rails generate queue_classic:install
|
23
|
+
bundle exec rails db:migrate
|
data/test/worker_test.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'helper'
|
2
4
|
|
3
5
|
module TestObject
|
4
6
|
extend self
|
@@ -27,7 +29,6 @@ class TestWorker < QC::Worker
|
|
27
29
|
end
|
28
30
|
|
29
31
|
class WorkerTest < QCTest
|
30
|
-
|
31
32
|
def test_work
|
32
33
|
QC.enqueue("TestObject.no_args")
|
33
34
|
worker = TestWorker.new
|
@@ -40,7 +41,7 @@ class WorkerTest < QCTest
|
|
40
41
|
def test_failed_job
|
41
42
|
QC.enqueue("TestObject.not_a_method")
|
42
43
|
worker = TestWorker.new
|
43
|
-
worker.work
|
44
|
+
capture_stderr_output { worker.work }
|
44
45
|
assert_equal(1, worker.failed_count)
|
45
46
|
end
|
46
47
|
|
@@ -122,14 +123,16 @@ class WorkerTest < QCTest
|
|
122
123
|
t.join
|
123
124
|
end
|
124
125
|
|
125
|
-
def
|
126
|
+
def test_worker_reuses_conn
|
126
127
|
QC.enqueue("TestObject.no_args")
|
128
|
+
count = QC.default_conn_adapter.execute("SELECT count(*) from pg_stat_activity where datname = current_database()")["count"].to_i;
|
127
129
|
worker = TestWorker.new
|
128
130
|
worker.work
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
131
|
+
|
132
|
+
new_count = QC.default_conn_adapter.execute("SELECT count(*) from pg_stat_activity where datname = current_database()")["count"].to_i;
|
133
|
+
assert(
|
134
|
+
new_count == count,
|
135
|
+
"Worker should not initialize new connections to #{ QC.default_conn_adapter.send(:db_url) }."
|
133
136
|
)
|
134
137
|
end
|
135
138
|
|
@@ -175,48 +178,163 @@ class WorkerTest < QCTest
|
|
175
178
|
assert_equal(0, worker.failed_count)
|
176
179
|
end
|
177
180
|
|
178
|
-
def
|
179
|
-
|
181
|
+
def test_init_worker_with_database_url
|
182
|
+
with_database ENV['DATABASE_URL'] || ENV['QC_DATABASE_URL'] do
|
183
|
+
worker = QC::Worker.new
|
184
|
+
QC.enqueue("TestObject.no_args")
|
185
|
+
worker.lock_job
|
180
186
|
|
181
|
-
|
182
|
-
|
187
|
+
QC.default_conn_adapter.disconnect
|
188
|
+
end
|
189
|
+
end
|
183
190
|
|
184
|
-
|
185
|
-
|
191
|
+
def test_init_worker_without_conn
|
192
|
+
with_database nil do
|
193
|
+
assert_raises(ArgumentError) do
|
194
|
+
worker = QC::Worker.new
|
195
|
+
QC.enqueue("TestObject.no_args")
|
196
|
+
worker.lock_job
|
197
|
+
end
|
198
|
+
end
|
186
199
|
end
|
187
200
|
|
188
|
-
def
|
189
|
-
|
201
|
+
def test_worker_unlocks_job_on_signal_exception
|
202
|
+
job_details = QC.enqueue("Kernel.eval", "raise SignalException.new('INT')")
|
203
|
+
worker = TestWorker.new
|
190
204
|
|
191
|
-
|
192
|
-
QC.enqueue("TestObject.no_args")
|
193
|
-
worker.lock_job
|
205
|
+
unlocked = nil
|
194
206
|
|
195
|
-
|
196
|
-
|
207
|
+
fake_unlock = Proc.new do |job_id|
|
208
|
+
if job_id == job_details['id']
|
209
|
+
unlocked = true
|
210
|
+
end
|
211
|
+
original_unlock(job_id)
|
212
|
+
end
|
213
|
+
|
214
|
+
stub_any_instance(QC::Queue, :unlock, fake_unlock) do
|
215
|
+
begin
|
216
|
+
worker.work
|
217
|
+
rescue SignalException
|
218
|
+
ensure
|
219
|
+
assert unlocked, "SignalException failed to unlock the job in the queue."
|
220
|
+
end
|
221
|
+
end
|
197
222
|
end
|
198
223
|
|
199
|
-
def
|
200
|
-
|
224
|
+
def test_worker_unlocks_job_on_system_exit
|
225
|
+
job_details = QC.enqueue("Kernel.eval", "raise SystemExit.new")
|
226
|
+
worker = TestWorker.new
|
227
|
+
|
228
|
+
unlocked = nil
|
229
|
+
|
230
|
+
fake_unlock = Proc.new do |job_id|
|
231
|
+
if job_id == job_details['id']
|
232
|
+
unlocked = true
|
233
|
+
end
|
234
|
+
original_unlock(job_id)
|
235
|
+
end
|
236
|
+
|
237
|
+
stub_any_instance(QC::Queue, :unlock, fake_unlock) do
|
238
|
+
begin
|
239
|
+
worker.work
|
240
|
+
rescue SystemExit
|
241
|
+
ensure
|
242
|
+
assert unlocked, "SystemExit failed to unlock the job in the queue."
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
def test_worker_does_not_unlock_jobs_on_syntax_error
|
248
|
+
job_details = QC.enqueue("Kernel.eval", "bad syntax")
|
249
|
+
worker = TestWorker.new
|
250
|
+
|
251
|
+
unlocked = nil
|
201
252
|
|
202
|
-
|
253
|
+
fake_unlock = Proc.new do |job_id|
|
254
|
+
if job_id == job_details['id']
|
255
|
+
unlocked = true
|
256
|
+
end
|
257
|
+
original_unlock(job_id)
|
258
|
+
end
|
203
259
|
|
204
|
-
|
260
|
+
stub_any_instance(QC::Queue, :unlock, fake_unlock) do
|
261
|
+
begin
|
262
|
+
errors = capture_stderr_output do
|
263
|
+
worker.work
|
264
|
+
end
|
265
|
+
ensure
|
266
|
+
message = ["SyntaxError unexpectedly unlocked the job in the queue."]
|
267
|
+
message << "Errors:\n#{errors}" unless errors.empty?
|
268
|
+
refute unlocked, message.join("\n")
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
def test_worker_does_not_unlock_jobs_on_load_error
|
274
|
+
job_details = QC.enqueue("Kernel.eval", "require 'not_a_real_file'")
|
275
|
+
worker = TestWorker.new
|
276
|
+
|
277
|
+
unlocked = nil
|
278
|
+
|
279
|
+
fake_unlock = Proc.new do |job_id|
|
280
|
+
if job_id == job_details['id']
|
281
|
+
unlocked = true
|
282
|
+
end
|
283
|
+
original_unlock(job_id)
|
284
|
+
end
|
285
|
+
|
286
|
+
stub_any_instance(QC::Queue, :unlock, fake_unlock) do
|
287
|
+
begin
|
288
|
+
errors = capture_stderr_output do
|
289
|
+
worker.work
|
290
|
+
end
|
291
|
+
ensure
|
292
|
+
message = ["LoadError unexpectedly unlocked the job in the queue."]
|
293
|
+
message << "Errors:\n#{errors}" unless errors.empty?
|
294
|
+
refute unlocked, message.join("\n")
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
def test_worker_does_not_unlock_jobs_on_no_memory_error
|
300
|
+
job_details = QC.enqueue("Kernel.eval", "raise NoMemoryError.new")
|
301
|
+
worker = TestWorker.new
|
302
|
+
|
303
|
+
unlocked = nil
|
304
|
+
|
305
|
+
fake_unlock = Proc.new do |job_id|
|
306
|
+
if job_id == job_details['id']
|
307
|
+
unlocked = true
|
308
|
+
end
|
309
|
+
original_unlock(job_id)
|
310
|
+
end
|
311
|
+
|
312
|
+
stub_any_instance(QC::Queue, :unlock, fake_unlock) do
|
313
|
+
begin
|
314
|
+
errors = capture_stderr_output do
|
315
|
+
worker.work
|
316
|
+
end
|
317
|
+
ensure
|
318
|
+
message = ["NoMemoryError unexpectedly unlocked the job in the queue."]
|
319
|
+
message << "Errors:\n#{errors}" unless errors.empty?
|
320
|
+
refute unlocked, message.join("\n")
|
321
|
+
end
|
322
|
+
end
|
205
323
|
end
|
206
324
|
|
207
325
|
private
|
208
326
|
|
209
|
-
def
|
210
|
-
|
211
|
-
|
327
|
+
def with_database(url)
|
328
|
+
original_conn_adapter = QC.default_conn_adapter
|
329
|
+
original_database_url = ENV['DATABASE_URL']
|
330
|
+
original_qc_database_url = ENV['QC_DATABASE_URL']
|
331
|
+
|
212
332
|
ENV['DATABASE_URL'] = ENV['QC_DATABASE_URL'] = url
|
213
|
-
@conn_adapter = QC.default_conn_adapter
|
214
333
|
QC.default_conn_adapter = nil
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
ENV['
|
219
|
-
|
220
|
-
QC.default_conn_adapter = @conn_adapter
|
334
|
+
yield
|
335
|
+
ensure
|
336
|
+
ENV['DATABASE_URL'] = original_database_url
|
337
|
+
ENV['QC_DATABASE_URL'] = original_qc_database_url
|
338
|
+
QC.default_conn_adapter = original_conn_adapter
|
221
339
|
end
|
222
340
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: queue_classic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.0.0.pre.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Smith (♠ ace hacker)
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-10-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pg
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
version: '0.17'
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '0
|
22
|
+
version: '2.0'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,7 +29,27 @@ dependencies:
|
|
29
29
|
version: '0.17'
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '0
|
32
|
+
version: '2.0'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: activerecord
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 5.0.0
|
40
|
+
- - "<"
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '6.1'
|
43
|
+
type: :development
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: 5.0.0
|
50
|
+
- - "<"
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '6.1'
|
33
53
|
description: queue_classic is a queueing library for Ruby apps. (Rails, Sinatra, Etc...)
|
34
54
|
queue_classic features asynchronous job polling, database maintained locks and no
|
35
55
|
ridiculous dependencies. As a matter of fact, queue_classic only requires pg.
|
@@ -38,31 +58,50 @@ executables: []
|
|
38
58
|
extensions: []
|
39
59
|
extra_rdoc_files: []
|
40
60
|
files:
|
61
|
+
- ".circleci/config.yml"
|
62
|
+
- ".gitignore"
|
63
|
+
- CHANGELOG.md
|
64
|
+
- CODE_OF_CONDUCT.md
|
65
|
+
- CONTRIBUTING.md
|
66
|
+
- Gemfile
|
67
|
+
- LICENSE.txt
|
68
|
+
- README.md
|
69
|
+
- Rakefile
|
41
70
|
- lib/generators/queue_classic/install_generator.rb
|
42
71
|
- lib/generators/queue_classic/templates/add_queue_classic.rb
|
43
72
|
- lib/generators/queue_classic/templates/update_queue_classic_3_0_0.rb
|
44
73
|
- lib/generators/queue_classic/templates/update_queue_classic_3_0_2.rb
|
45
74
|
- lib/generators/queue_classic/templates/update_queue_classic_3_1_0.rb
|
75
|
+
- lib/generators/queue_classic/templates/update_queue_classic_4_0_0.rb
|
46
76
|
- lib/queue_classic.rb
|
77
|
+
- lib/queue_classic/config.rb
|
47
78
|
- lib/queue_classic/conn_adapter.rb
|
48
79
|
- lib/queue_classic/queue.rb
|
49
80
|
- lib/queue_classic/railtie.rb
|
50
81
|
- lib/queue_classic/setup.rb
|
51
82
|
- lib/queue_classic/tasks.rb
|
83
|
+
- lib/queue_classic/version.rb
|
52
84
|
- lib/queue_classic/worker.rb
|
53
|
-
-
|
85
|
+
- queue_classic.gemspec
|
54
86
|
- sql/create_table.sql
|
55
87
|
- sql/ddl.sql
|
56
88
|
- sql/downgrade_from_3_0_0.sql
|
57
89
|
- sql/downgrade_from_3_1_0.sql
|
90
|
+
- sql/downgrade_from_4_0_0.sql
|
58
91
|
- sql/drop_ddl.sql
|
59
92
|
- sql/update_to_3_0_0.sql
|
60
93
|
- sql/update_to_3_1_0.sql
|
94
|
+
- sql/update_to_4_0_0.sql
|
61
95
|
- test/benchmark_test.rb
|
96
|
+
- test/config_test.rb
|
62
97
|
- test/helper.rb
|
98
|
+
- test/helper.sql
|
63
99
|
- test/lib/queue_classic_rails_connection_test.rb
|
64
100
|
- test/lib/queue_classic_test.rb
|
101
|
+
- test/lib/queue_classic_test_with_activerecord_typecast.rb
|
65
102
|
- test/queue_test.rb
|
103
|
+
- test/rails-tests/.gitignore
|
104
|
+
- test/rails-tests/rails523.sh
|
66
105
|
- test/worker_test.rb
|
67
106
|
homepage: http://github.com/QueueClassic/queue_classic
|
68
107
|
licenses:
|
@@ -83,14 +122,19 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
83
122
|
- !ruby/object:Gem::Version
|
84
123
|
version: 1.3.1
|
85
124
|
requirements: []
|
86
|
-
|
87
|
-
rubygems_version: 2.2.2
|
125
|
+
rubygems_version: 3.1.2
|
88
126
|
signing_key:
|
89
127
|
specification_version: 4
|
90
128
|
summary: Simple, efficient worker queue for Ruby & PostgreSQL.
|
91
129
|
test_files:
|
92
130
|
- test/benchmark_test.rb
|
131
|
+
- test/config_test.rb
|
132
|
+
- test/helper.rb
|
133
|
+
- test/helper.sql
|
93
134
|
- test/lib/queue_classic_rails_connection_test.rb
|
94
135
|
- test/lib/queue_classic_test.rb
|
136
|
+
- test/lib/queue_classic_test_with_activerecord_typecast.rb
|
95
137
|
- test/queue_test.rb
|
138
|
+
- test/rails-tests/.gitignore
|
139
|
+
- test/rails-tests/rails523.sh
|
96
140
|
- test/worker_test.rb
|