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
@@ -0,0 +1,88 @@
|
|
1
|
+
DO $$DECLARE r record;
|
2
|
+
BEGIN
|
3
|
+
-- If jsonb type is available, do nothing as we're downgrading from 4.0.0
|
4
|
+
IF EXISTS (SELECT 1 FROM pg_type WHERE typname = 'jsonb') THEN
|
5
|
+
-- do nothing - it should already be already jsonb
|
6
|
+
-- Otherwise, use json type for the args column if available
|
7
|
+
ELSIF EXISTS (SELECT 1 FROM pg_type WHERE typname = 'json') THEN
|
8
|
+
-- this should only happen if someone downgrades QC and their database < pg 9.4
|
9
|
+
ALTER TABLE queue_classic_jobs ALTER COLUMN args TYPE json USING args::json;
|
10
|
+
END IF;
|
11
|
+
|
12
|
+
|
13
|
+
END$$;
|
14
|
+
|
15
|
+
|
16
|
+
--
|
17
|
+
-- Re install the lock_head function
|
18
|
+
--
|
19
|
+
|
20
|
+
-- We are declaring the return type to be queue_classic_jobs.
|
21
|
+
-- This is ok since I am assuming that all of the users added queues will
|
22
|
+
-- have identical columns to queue_classic_jobs.
|
23
|
+
-- When QC supports queues with columns other than the default, we will have to change this.
|
24
|
+
|
25
|
+
CREATE OR REPLACE FUNCTION lock_head(q_name varchar, top_boundary integer)
|
26
|
+
RETURNS SETOF queue_classic_jobs AS $$
|
27
|
+
DECLARE
|
28
|
+
unlocked bigint;
|
29
|
+
relative_top integer;
|
30
|
+
job_count integer;
|
31
|
+
BEGIN
|
32
|
+
-- The purpose is to release contention for the first spot in the table.
|
33
|
+
-- The select count(*) is going to slow down dequeue performance but allow
|
34
|
+
-- for more workers. Would love to see some optimization here...
|
35
|
+
|
36
|
+
EXECUTE 'SELECT count(*) FROM '
|
37
|
+
|| '(SELECT * FROM queue_classic_jobs '
|
38
|
+
|| ' WHERE locked_at IS NULL'
|
39
|
+
|| ' AND q_name = '
|
40
|
+
|| quote_literal(q_name)
|
41
|
+
|| ' AND scheduled_at <= '
|
42
|
+
|| quote_literal(now())
|
43
|
+
|| ' LIMIT '
|
44
|
+
|| quote_literal(top_boundary)
|
45
|
+
|| ') limited'
|
46
|
+
INTO job_count;
|
47
|
+
|
48
|
+
SELECT TRUNC(random() * (top_boundary - 1))
|
49
|
+
INTO relative_top;
|
50
|
+
|
51
|
+
IF job_count < top_boundary THEN
|
52
|
+
relative_top = 0;
|
53
|
+
END IF;
|
54
|
+
|
55
|
+
LOOP
|
56
|
+
BEGIN
|
57
|
+
EXECUTE 'SELECT id FROM queue_classic_jobs '
|
58
|
+
|| ' WHERE locked_at IS NULL'
|
59
|
+
|| ' AND q_name = '
|
60
|
+
|| quote_literal(q_name)
|
61
|
+
|| ' AND scheduled_at <= '
|
62
|
+
|| quote_literal(now())
|
63
|
+
|| ' ORDER BY id ASC'
|
64
|
+
|| ' LIMIT 1'
|
65
|
+
|| ' OFFSET ' || quote_literal(relative_top)
|
66
|
+
|| ' FOR UPDATE NOWAIT'
|
67
|
+
INTO unlocked;
|
68
|
+
EXIT;
|
69
|
+
EXCEPTION
|
70
|
+
WHEN lock_not_available THEN
|
71
|
+
-- do nothing. loop again and hope we get a lock
|
72
|
+
END;
|
73
|
+
END LOOP;
|
74
|
+
|
75
|
+
RETURN QUERY EXECUTE 'UPDATE queue_classic_jobs '
|
76
|
+
|| ' SET locked_at = (CURRENT_TIMESTAMP),'
|
77
|
+
|| ' locked_by = (select pg_backend_pid())'
|
78
|
+
|| ' WHERE id = $1'
|
79
|
+
|| ' AND locked_at is NULL'
|
80
|
+
|| ' RETURNING *'
|
81
|
+
USING unlocked;
|
82
|
+
|
83
|
+
RETURN;
|
84
|
+
END $$ LANGUAGE plpgsql;
|
85
|
+
|
86
|
+
CREATE OR REPLACE FUNCTION lock_head(tname varchar) RETURNS SETOF queue_classic_jobs AS $$ BEGIN
|
87
|
+
RETURN QUERY EXECUTE 'SELECT * FROM lock_head($1,10)' USING tname;
|
88
|
+
END $$ LANGUAGE plpgsql;
|
data/sql/update_to_3_0_0.sql
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
DO $$DECLARE r record;
|
2
2
|
BEGIN
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
BEGIN
|
4
|
+
ALTER TABLE queue_classic_jobs ADD COLUMN created_at timestamptz DEFAULT now();
|
5
|
+
EXCEPTION
|
6
|
+
WHEN duplicate_column THEN RAISE NOTICE 'column created_at already exists in queue_classic_jobs.';
|
7
|
+
END;
|
8
8
|
END$$;
|
9
9
|
|
10
10
|
DO $$DECLARE r record;
|
data/sql/update_to_3_1_0.sql
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
DO $$DECLARE r record;
|
2
2
|
BEGIN
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
BEGIN
|
4
|
+
ALTER TABLE queue_classic_jobs ADD COLUMN scheduled_at timestamptz DEFAULT now();
|
5
|
+
CREATE INDEX idx_qc_on_scheduled_at_only_unlocked ON queue_classic_jobs (scheduled_at, id) WHERE locked_at IS NULL;
|
6
|
+
EXCEPTION
|
7
|
+
WHEN duplicate_column THEN RAISE NOTICE 'column scheduled_at already exists in queue_classic_jobs.';
|
8
|
+
END;
|
9
9
|
END$$;
|
data/test/benchmark_test.rb
CHANGED
@@ -1,37 +1,40 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'helper'
|
2
4
|
|
3
5
|
if ENV["QC_BENCHMARK"]
|
4
6
|
class BenchmarkTest < QCTest
|
7
|
+
BENCHMARK_SIZE = Integer(ENV.fetch("QC_BENCHMARK_SIZE", 10_000))
|
8
|
+
BENCHMARK_MAX_TIME_DEQUEUE = Integer(ENV.fetch("QC_BENCHMARK_MAX_TIME_DEQUEUE", 30))
|
9
|
+
BENCHMARK_MAX_TIME_ENQUEUE = Integer(ENV.fetch("QC_BENCHMARK_MAX_TIME_ENQUEUE", 5))
|
5
10
|
|
6
11
|
def test_enqueue
|
7
|
-
n = 10_000
|
8
12
|
start = Time.now
|
9
|
-
|
10
|
-
QC.enqueue("1.odd?"
|
13
|
+
BENCHMARK_SIZE.times do
|
14
|
+
QC.enqueue("1.odd?")
|
11
15
|
end
|
12
|
-
assert_equal(
|
16
|
+
assert_equal(BENCHMARK_SIZE, QC.count)
|
13
17
|
|
14
18
|
elapsed = Time.now - start
|
15
|
-
|
19
|
+
assert_operator(elapsed, :<, BENCHMARK_MAX_TIME_ENQUEUE)
|
16
20
|
end
|
17
21
|
|
18
22
|
def test_dequeue
|
19
23
|
worker = QC::Worker.new
|
20
24
|
worker.running = true
|
21
|
-
|
22
|
-
|
23
|
-
QC.enqueue("1.odd?", [])
|
25
|
+
BENCHMARK_SIZE.times do
|
26
|
+
QC.enqueue("1.odd?")
|
24
27
|
end
|
25
|
-
assert_equal(
|
28
|
+
assert_equal(BENCHMARK_SIZE, QC.count)
|
26
29
|
|
27
30
|
start = Time.now
|
28
|
-
|
31
|
+
BENCHMARK_SIZE.times do
|
29
32
|
worker.work
|
30
33
|
end
|
31
34
|
elapsed = Time.now - start
|
32
35
|
|
33
36
|
assert_equal(0, QC.count)
|
34
|
-
|
37
|
+
assert_operator(elapsed, :<, BENCHMARK_MAX_TIME_DEQUEUE)
|
35
38
|
end
|
36
39
|
|
37
40
|
end
|
data/test/config_test.rb
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'helper'
|
4
|
+
|
5
|
+
class ConfigTest < QCTest
|
6
|
+
def setup
|
7
|
+
QC.reset_config
|
8
|
+
end
|
9
|
+
|
10
|
+
def teardown
|
11
|
+
QC.reset_config
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_app_name_default
|
15
|
+
assert_equal "queue_classic", QC.app_name
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_configure_app_name_with_env_var
|
19
|
+
with_env "QC_APP_NAME" => "zomg_qc" do
|
20
|
+
assert_equal "zomg_qc", QC.app_name
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_wait_time_default
|
25
|
+
assert_equal 5, QC.wait_time
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_configure_wait_time_with_env_var
|
29
|
+
with_env "QC_LISTEN_TIME" => "7" do
|
30
|
+
assert_equal 7, QC.wait_time
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_table_name_default
|
35
|
+
assert_equal "queue_classic_jobs", QC.table_name
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_queue_default
|
39
|
+
assert_equal "default", QC.queue
|
40
|
+
assert_equal "default", QC.default_queue.name
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_configure_queue_with_env_var
|
44
|
+
with_env "QUEUE" => "priority" do
|
45
|
+
assert_equal "priority", QC.queue
|
46
|
+
assert_equal "priority", QC.default_queue.name
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_assign_default_queue
|
51
|
+
QC.default_queue = QC::Queue.new "dispensable"
|
52
|
+
assert_equal "default", QC.queue
|
53
|
+
assert_equal "dispensable", QC.default_queue.name
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_queues_default
|
57
|
+
assert_equal [], QC.queues
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_configure_queues_with_env_var
|
61
|
+
with_env "QUEUES" => "first,second,third" do
|
62
|
+
assert_equal %w(first second third), QC.queues
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_configure_queues_with_whitespace
|
67
|
+
with_env "QUEUES" => " one, two, three " do
|
68
|
+
assert_equal %w(one two three), QC.queues
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_top_bound_default
|
73
|
+
assert_equal 9, QC.top_bound
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_configure_top_bound_with_env_var
|
77
|
+
with_env "QC_TOP_BOUND" => "5" do
|
78
|
+
assert_equal 5, QC.top_bound
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_fork_worker_default
|
83
|
+
refute QC.fork_worker?
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_configure_fork_worker_with_env_var
|
87
|
+
with_env "QC_FORK_WORKER" => "yo" do
|
88
|
+
assert QC.fork_worker?
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_configuration_constants_are_deprecated
|
93
|
+
warning = capture_stderr_output do
|
94
|
+
QC::FORK_WORKER
|
95
|
+
end
|
96
|
+
assert_match "QC::FORK_WORKER is deprecated", warning
|
97
|
+
assert_match "QC.fork_worker? instead", warning
|
98
|
+
end
|
99
|
+
|
100
|
+
class TestWorker < QC::Worker; end
|
101
|
+
|
102
|
+
def test_default_worker_class
|
103
|
+
assert_equal QC::Worker, QC.default_worker_class
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_configure_default_worker_class_with_env_var
|
107
|
+
if RUBY_VERSION =~ /^1\.9\./
|
108
|
+
skip "Kernel.const_get in Ruby 1.9.x does not perform recursive lookups"
|
109
|
+
end
|
110
|
+
with_env "QC_DEFAULT_WORKER_CLASS" => "ConfigTest::TestWorker" do
|
111
|
+
assert_equal TestWorker, QC.default_worker_class
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_assign_default_worker_class
|
116
|
+
original_worker = QC.default_worker_class
|
117
|
+
QC.default_worker_class = TestWorker
|
118
|
+
|
119
|
+
assert_equal TestWorker, QC.default_worker_class
|
120
|
+
ensure
|
121
|
+
QC.default_worker_class = original_worker
|
122
|
+
end
|
123
|
+
end
|
data/test/helper.rb
CHANGED
@@ -1,9 +1,19 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler"
|
4
|
+
require "minitest/reporters"
|
5
|
+
|
6
|
+
Bundler.setup :default, :test
|
7
|
+
|
8
|
+
if ENV['CIRCLECI'] == "true"
|
9
|
+
Minitest::Reporters.use! Minitest::Reporters::JUnitReporter.new
|
10
|
+
else
|
11
|
+
Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
|
12
|
+
end
|
3
13
|
|
4
14
|
ENV["DATABASE_URL"] ||= "postgres:///queue_classic_test"
|
5
15
|
|
6
|
-
|
16
|
+
require_relative '../lib/queue_classic'
|
7
17
|
require "stringio"
|
8
18
|
require "minitest/autorun"
|
9
19
|
|
@@ -48,4 +58,38 @@ class QCTest < Minitest::Test
|
|
48
58
|
$stdout = original_stdout
|
49
59
|
end
|
50
60
|
|
61
|
+
def with_env(temporary_environment)
|
62
|
+
original_environment = {}
|
63
|
+
temporary_environment.each do |name, value|
|
64
|
+
original_environment[name] = ENV[name]
|
65
|
+
ENV[name] = value
|
66
|
+
end
|
67
|
+
yield
|
68
|
+
ensure
|
69
|
+
original_environment.each { |name, value| ENV[name] = value }
|
70
|
+
end
|
71
|
+
|
72
|
+
def stub_any_instance(class_name, method_name, definition)
|
73
|
+
new_method_name = "new_#{method_name}"
|
74
|
+
original_method_name = "original_#{method_name}"
|
75
|
+
|
76
|
+
method_present = class_name.instance_methods(false).include? method_name
|
77
|
+
|
78
|
+
if method_present
|
79
|
+
class_name.send(:alias_method, original_method_name, method_name)
|
80
|
+
class_name.send(:define_method, new_method_name, definition)
|
81
|
+
class_name.send(:alias_method, method_name, new_method_name)
|
82
|
+
|
83
|
+
yield
|
84
|
+
else
|
85
|
+
message = "#{class_name} does not have method #{method_name}."
|
86
|
+
message << "\nAvailable methods: #{class_name.instance_methods(false)}"
|
87
|
+
raise ArgumentError.new message
|
88
|
+
end
|
89
|
+
ensure
|
90
|
+
if method_present
|
91
|
+
class_name.send(:alias_method, method_name, original_method_name)
|
92
|
+
class_name.send(:undef_method, new_method_name)
|
93
|
+
end
|
94
|
+
end
|
51
95
|
end
|
data/test/helper.sql
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
DO $$
|
2
|
+
-- Set initial sequence to a large number to test the entire toolchain
|
3
|
+
-- works on integers with higher bits set.
|
4
|
+
DECLARE
|
5
|
+
quoted_name text;
|
6
|
+
quoted_size text;
|
7
|
+
BEGIN
|
8
|
+
-- Find the name of the relevant sequence.
|
9
|
+
--
|
10
|
+
-- pg_get_serial_sequence quotes identifiers as part of its
|
11
|
+
-- behavior.
|
12
|
+
SELECT name
|
13
|
+
INTO STRICT quoted_name
|
14
|
+
FROM pg_get_serial_sequence('queue_classic_jobs', 'id') AS name;
|
15
|
+
|
16
|
+
-- Don't quote, because ALTER SEQUENCE RESTART doesn't like
|
17
|
+
-- general literals, only unquoted numeric literals.
|
18
|
+
SELECT pow(2, 34)::text AS size
|
19
|
+
INTO STRICT quoted_size;
|
20
|
+
|
21
|
+
EXECUTE 'ALTER SEQUENCE ' || quoted_name ||
|
22
|
+
' RESTART ' || quoted_size || ';';
|
23
|
+
END;
|
24
|
+
$$;
|
25
|
+
|
@@ -1,35 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require File.expand_path("../../helper.rb", __FILE__)
|
2
4
|
|
3
5
|
class QueueClassicRailsConnectionTest < QCTest
|
4
6
|
def before_setup
|
5
|
-
|
6
|
-
ActiveRecord.const_set :Base, Module.new
|
7
|
-
|
7
|
+
@original_conn_adapter = QC.default_conn_adapter
|
8
8
|
QC.default_conn_adapter = nil
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
11
|
+
def before_teardown
|
12
12
|
ActiveRecord.send :remove_const, :Base
|
13
13
|
Object.send :remove_const, :ActiveRecord
|
14
|
+
|
15
|
+
QC.default_conn_adapter = @original_conn_adapter
|
14
16
|
end
|
15
17
|
|
16
18
|
def test_uses_active_record_connection_if_exists
|
17
19
|
connection = get_connection
|
18
|
-
|
20
|
+
QC.default_conn_adapter.execute('SELECT 1;')
|
21
|
+
connection.verify
|
19
22
|
end
|
20
23
|
|
21
24
|
def test_does_not_use_active_record_connection_if_env_var_set
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
25
|
+
with_env 'QC_RAILS_DATABASE' => 'false' do
|
26
|
+
connection = get_connection
|
27
|
+
QC.default_conn_adapter.execute('SELECT 1;')
|
28
|
+
assert_raises(MockExpectationError) { connection.verify }
|
29
|
+
end
|
26
30
|
end
|
27
31
|
|
28
32
|
private
|
29
33
|
def get_connection
|
30
34
|
connection = Minitest::Mock.new
|
31
|
-
connection.expect(:raw_connection, QC::ConnAdapter.new.connection)
|
35
|
+
connection.expect(:raw_connection, QC::ConnAdapter.new(active_record_connection_share: true).connection)
|
32
36
|
|
37
|
+
Object.send :const_set, :ActiveRecord, Module.new
|
38
|
+
ActiveRecord.const_set :Base, Module.new
|
33
39
|
ActiveRecord::Base.define_singleton_method(:connection) do
|
34
40
|
connection
|
35
41
|
end
|
@@ -1,24 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require File.expand_path("../../helper.rb", __FILE__)
|
2
4
|
|
3
5
|
class QueueClassicTest < QCTest
|
6
|
+
def test_only_delegate_calls_to_queue_it_understands
|
7
|
+
e = assert_raises(NoMethodError) do
|
8
|
+
QC.probably_not
|
9
|
+
end
|
10
|
+
assert_match "undefined method `probably_not' for QC:Module", e.message
|
11
|
+
end
|
12
|
+
|
4
13
|
def test_default_conn_adapter_default_value
|
5
14
|
assert(QC.default_conn_adapter.is_a?(QC::ConnAdapter))
|
6
15
|
end
|
7
16
|
|
8
|
-
def
|
17
|
+
def test_assigning_a_default_conn_adapter
|
18
|
+
original_conn_adapter = QC.default_conn_adapter
|
9
19
|
connection = QC::ConnAdapter.new
|
10
20
|
QC.default_conn_adapter = connection
|
11
21
|
assert_equal(QC.default_conn_adapter, connection)
|
22
|
+
ensure
|
23
|
+
QC.default_conn_adapter = original_conn_adapter
|
12
24
|
end
|
13
25
|
|
14
26
|
def test_unlock_jobs_of_dead_workers
|
15
27
|
# Insert a locked job
|
16
28
|
adapter = QC::ConnAdapter.new
|
17
|
-
query = "INSERT INTO #{QC
|
29
|
+
query = "INSERT INTO #{QC.table_name} (q_name, method, args, locked_by, locked_at) VALUES ('whatever', 'Kernel.puts', '[\"ok?\"]', 0, (CURRENT_TIMESTAMP))"
|
18
30
|
adapter.execute(query)
|
19
31
|
|
20
32
|
# We should have no unlocked jobs
|
21
|
-
query_locked_jobs = "SELECT * FROM #{QC
|
33
|
+
query_locked_jobs = "SELECT * FROM #{QC.table_name} WHERE locked_at IS NULL"
|
22
34
|
res = adapter.connection.exec(query_locked_jobs)
|
23
35
|
assert_equal(0, res.count)
|
24
36
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require File.expand_path("../../helper.rb", __FILE__)
|
4
|
+
|
5
|
+
class QueueClassicTest < QCTest
|
6
|
+
def before_teardown
|
7
|
+
ActiveRecord.send :remove_const, :Base
|
8
|
+
Object.send :remove_const, :ActiveRecord
|
9
|
+
|
10
|
+
QC.default_conn_adapter = @original_conn_adapter
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_lock_with_active_record_timestamp_type_cast
|
14
|
+
# Insert an unlocked job
|
15
|
+
p_queue = QC::Queue.new("priority_queue")
|
16
|
+
conn_adapter = Minitest::Mock.new
|
17
|
+
conn_adapter.expect(:execute, {"id" => '1', "q_name" => 'test', "method" => "Kernel.puts", "args" => "[]", "scheduled_at" => Time.now}, [String, String])
|
18
|
+
QC.default_conn_adapter = conn_adapter
|
19
|
+
assert_equal(p_queue.lock, {})
|
20
|
+
end
|
21
|
+
end
|