que 0.14.3 → 1.0.0.beta
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/.gitignore +2 -0
- data/CHANGELOG.md +108 -14
- data/LICENSE.txt +1 -1
- data/README.md +49 -45
- data/bin/command_line_interface.rb +239 -0
- data/bin/que +8 -82
- data/docs/README.md +2 -0
- data/docs/active_job.md +6 -0
- data/docs/advanced_setup.md +7 -64
- data/docs/command_line_interface.md +45 -0
- data/docs/error_handling.md +65 -18
- data/docs/inspecting_the_queue.md +30 -80
- data/docs/job_helper_methods.md +27 -0
- data/docs/logging.md +3 -22
- data/docs/managing_workers.md +6 -61
- data/docs/middleware.md +15 -0
- data/docs/migrating.md +4 -7
- data/docs/multiple_queues.md +8 -4
- data/docs/shutting_down_safely.md +1 -1
- data/docs/using_plain_connections.md +39 -15
- data/docs/using_sequel.md +5 -3
- data/docs/writing_reliable_jobs.md +15 -24
- data/lib/que.rb +98 -182
- data/lib/que/active_job/extensions.rb +97 -0
- data/lib/que/active_record/connection.rb +51 -0
- data/lib/que/active_record/model.rb +48 -0
- data/lib/que/connection.rb +179 -0
- data/lib/que/connection_pool.rb +78 -0
- data/lib/que/job.rb +107 -156
- data/lib/que/job_cache.rb +240 -0
- data/lib/que/job_methods.rb +168 -0
- data/lib/que/listener.rb +176 -0
- data/lib/que/locker.rb +466 -0
- data/lib/que/metajob.rb +47 -0
- data/lib/que/migrations.rb +24 -17
- data/lib/que/migrations/4/down.sql +48 -0
- data/lib/que/migrations/4/up.sql +265 -0
- data/lib/que/poller.rb +267 -0
- data/lib/que/rails/railtie.rb +14 -0
- data/lib/que/result_queue.rb +35 -0
- data/lib/que/sequel/model.rb +51 -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 +78 -0
- data/lib/que/utils/middleware.rb +33 -0
- data/lib/que/utils/queue_management.rb +18 -0
- data/lib/que/utils/transactions.rb +34 -0
- data/lib/que/version.rb +1 -1
- data/lib/que/worker.rb +128 -167
- data/que.gemspec +13 -2
- metadata +37 -80
- data/.rspec +0 -2
- data/.travis.yml +0 -64
- data/Gemfile +0 -24
- data/docs/customizing_que.md +0 -200
- 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 -40
- data/lib/que/adapters/base.rb +0 -133
- 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 -170
- data/spec/adapters/active_record_spec.rb +0 -175
- 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/Gemfile.current +0 -19
- data/spec/gemfiles/Gemfile.old +0 -19
- data/spec/gemfiles/Gemfile.older +0 -19
- data/spec/gemfiles/Gemfile.oldest +0 -19
- data/spec/spec_helper.rb +0 -129
- data/spec/support/helpers.rb +0 -25
- data/spec/support/jobs.rb +0 -35
- data/spec/support/shared_examples/adapter.rb +0 -42
- data/spec/support/shared_examples/multi_threaded_adapter.rb +0 -46
- data/spec/unit/configuration_spec.rb +0 -31
- 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 -596
- 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
data/lib/que/adapters/pg.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'monitor'
|
4
|
-
|
5
|
-
module Que
|
6
|
-
module Adapters
|
7
|
-
class PG < Base
|
8
|
-
attr_reader :lock
|
9
|
-
|
10
|
-
def initialize(pg)
|
11
|
-
@pg = pg
|
12
|
-
@lock = Monitor.new # Must be re-entrant.
|
13
|
-
super
|
14
|
-
end
|
15
|
-
|
16
|
-
def checkout
|
17
|
-
@lock.synchronize { yield @pg }
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
data/lib/que/adapters/pond.rb
DELETED
data/lib/que/adapters/sequel.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Que
|
4
|
-
module Adapters
|
5
|
-
class Sequel < Base
|
6
|
-
def initialize(db)
|
7
|
-
@db = db
|
8
|
-
super
|
9
|
-
end
|
10
|
-
|
11
|
-
def checkout(&block)
|
12
|
-
@db.synchronize(&block)
|
13
|
-
end
|
14
|
-
|
15
|
-
def wake_worker_after_commit
|
16
|
-
@db.after_commit { Que.wake! }
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
data/lib/que/railtie.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Que
|
4
|
-
class Railtie < Rails::Railtie
|
5
|
-
config.que = Que
|
6
|
-
|
7
|
-
Que.logger = proc { Rails.logger }
|
8
|
-
Que.mode = :sync if Rails.env.test?
|
9
|
-
Que.connection = ::ActiveRecord if defined? ::ActiveRecord
|
10
|
-
Que.json_converter = :with_indifferent_access.to_proc
|
11
|
-
|
12
|
-
rake_tasks do
|
13
|
-
load 'que/rake_tasks.rb'
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
data/lib/que/rake_tasks.rb
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
namespace :que do
|
4
|
-
desc "Process Que's jobs using a worker pool"
|
5
|
-
task :work => :environment do
|
6
|
-
$stdout.sync = true
|
7
|
-
|
8
|
-
$stdout.puts "The que:work rake task has been deprecated and will be removed in Que 1.0. Please transition to the que command line interface instead."
|
9
|
-
|
10
|
-
if defined?(::Rails) && Rails.respond_to?(:application)
|
11
|
-
# ActiveSupport's dependency autoloading isn't threadsafe, and Que uses
|
12
|
-
# multiple threads, which means that eager loading is necessary. Rails
|
13
|
-
# explicitly prevents eager loading when the environment task is invoked,
|
14
|
-
# so we need to manually eager load the app here.
|
15
|
-
Rails.application.eager_load!
|
16
|
-
end
|
17
|
-
|
18
|
-
Que.logger.level = Logger.const_get((ENV['QUE_LOG_LEVEL'] || 'INFO').upcase)
|
19
|
-
Que.worker_count = (ENV['QUE_WORKER_COUNT'] || 4).to_i
|
20
|
-
Que.wake_interval = (ENV['QUE_WAKE_INTERVAL'] || 0.1).to_f
|
21
|
-
Que.queue_name = ENV['QUE_QUEUE'] if ENV['QUE_QUEUE']
|
22
|
-
Que.mode = :async
|
23
|
-
|
24
|
-
# When changing how signals are caught, be sure to test the behavior with
|
25
|
-
# the rake task in tasks/safe_shutdown.rb.
|
26
|
-
|
27
|
-
stop = false
|
28
|
-
%w( INT TERM ).each do |signal|
|
29
|
-
trap(signal) {stop = true}
|
30
|
-
end
|
31
|
-
|
32
|
-
at_exit do
|
33
|
-
$stdout.puts "Finishing Que's current jobs before exiting..."
|
34
|
-
Que.worker_count = 0
|
35
|
-
Que.mode = :off
|
36
|
-
$stdout.puts "Que's jobs finished, exiting..."
|
37
|
-
end
|
38
|
-
|
39
|
-
loop do
|
40
|
-
sleep 0.01
|
41
|
-
break if stop
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
desc "Migrate Que's job table to the most recent version (creating it if it doesn't exist)"
|
46
|
-
task :migrate => :environment do
|
47
|
-
Que.migrate!
|
48
|
-
end
|
49
|
-
|
50
|
-
desc "Drop Que's job table"
|
51
|
-
task :drop => :environment do
|
52
|
-
Que.drop!
|
53
|
-
end
|
54
|
-
|
55
|
-
desc "Clear Que's job table"
|
56
|
-
task :clear => :environment do
|
57
|
-
Que.clear!
|
58
|
-
end
|
59
|
-
end
|
data/lib/que/sql.rb
DELETED
@@ -1,170 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Que
|
4
|
-
SQL = {
|
5
|
-
# Locks a job using a Postgres recursive CTE [1].
|
6
|
-
#
|
7
|
-
# As noted by the Postgres documentation, it may be slightly easier to
|
8
|
-
# think about this expression as iteration rather than recursion, despite
|
9
|
-
# the `RECURSION` nomenclature defined by the SQL standards committee.
|
10
|
-
# Recursion is used here so that jobs in the table can be iterated one-by-
|
11
|
-
# one until a lock can be acquired, where a non-recursive `SELECT` would
|
12
|
-
# have the undesirable side-effect of locking multiple jobs at once. i.e.
|
13
|
-
# Consider that the following would have the worker lock *all* unlocked
|
14
|
-
# jobs:
|
15
|
-
#
|
16
|
-
# SELECT (j).*, pg_try_advisory_lock((j).job_id) AS locked
|
17
|
-
# FROM que_jobs AS j;
|
18
|
-
#
|
19
|
-
# The CTE will initially produce an "anchor" from the non-recursive term
|
20
|
-
# (i.e. before the `UNION`), and then use it as the contents of the
|
21
|
-
# working table as it continues to iterate through `que_jobs` looking for
|
22
|
-
# a lock. The jobs table has a sort on (priority, run_at, job_id) which
|
23
|
-
# allows it to walk the jobs table in a stable manner. As noted above, the
|
24
|
-
# recursion examines one job at a time so that it only ever acquires a
|
25
|
-
# single lock.
|
26
|
-
#
|
27
|
-
# The recursion has two possible end conditions:
|
28
|
-
#
|
29
|
-
# 1. If a lock *can* be acquired, it bubbles up to the top-level `SELECT`
|
30
|
-
# outside of the `job` CTE which stops recursion because it is
|
31
|
-
# constrained with a `LIMIT` of 1.
|
32
|
-
#
|
33
|
-
# 2. If a lock *cannot* be acquired, the recursive term of the expression
|
34
|
-
# (i.e. what's after the `UNION`) will return an empty result set
|
35
|
-
# because there are no more candidates left that could possibly be
|
36
|
-
# locked. This empty result automatically ends recursion.
|
37
|
-
#
|
38
|
-
# Note that this query can be easily modified to lock any number of jobs
|
39
|
-
# by tweaking the LIMIT clause in the main SELECT statement.
|
40
|
-
#
|
41
|
-
# [1] http://www.postgresql.org/docs/devel/static/queries-with.html
|
42
|
-
#
|
43
|
-
# Thanks to RhodiumToad in #postgresql for help with the original version
|
44
|
-
# of the job lock CTE.
|
45
|
-
:lock_job => %{
|
46
|
-
WITH RECURSIVE jobs AS (
|
47
|
-
SELECT (j).*, pg_try_advisory_lock((j).job_id) AS locked
|
48
|
-
FROM (
|
49
|
-
SELECT j
|
50
|
-
FROM que_jobs AS j
|
51
|
-
WHERE queue = $1::text
|
52
|
-
AND run_at <= now()
|
53
|
-
ORDER BY priority, run_at, job_id
|
54
|
-
LIMIT 1
|
55
|
-
) AS t1
|
56
|
-
UNION ALL (
|
57
|
-
SELECT (j).*, pg_try_advisory_lock((j).job_id) AS locked
|
58
|
-
FROM (
|
59
|
-
SELECT (
|
60
|
-
SELECT j
|
61
|
-
FROM que_jobs AS j
|
62
|
-
WHERE queue = $1::text
|
63
|
-
AND run_at <= now()
|
64
|
-
AND (priority, run_at, job_id) > (jobs.priority, jobs.run_at, jobs.job_id)
|
65
|
-
ORDER BY priority, run_at, job_id
|
66
|
-
LIMIT 1
|
67
|
-
) AS j
|
68
|
-
FROM jobs
|
69
|
-
WHERE jobs.job_id IS NOT NULL
|
70
|
-
LIMIT 1
|
71
|
-
) AS t1
|
72
|
-
)
|
73
|
-
)
|
74
|
-
SELECT queue, priority, run_at, job_id, job_class, args, error_count
|
75
|
-
FROM jobs
|
76
|
-
WHERE locked
|
77
|
-
LIMIT 1
|
78
|
-
}.freeze,
|
79
|
-
|
80
|
-
:check_job => %{
|
81
|
-
SELECT 1 AS one
|
82
|
-
FROM que_jobs
|
83
|
-
WHERE queue = $1::text
|
84
|
-
AND priority = $2::smallint
|
85
|
-
AND run_at = $3::timestamptz
|
86
|
-
AND job_id = $4::bigint
|
87
|
-
}.freeze,
|
88
|
-
|
89
|
-
:set_error => %{
|
90
|
-
UPDATE que_jobs
|
91
|
-
SET error_count = error_count + 1,
|
92
|
-
run_at = now() + $1::bigint * '1 second'::interval,
|
93
|
-
last_error = $2::text
|
94
|
-
WHERE queue = $3::text
|
95
|
-
AND priority = $4::smallint
|
96
|
-
AND run_at = $5::timestamptz
|
97
|
-
AND job_id = $6::bigint
|
98
|
-
}.freeze,
|
99
|
-
|
100
|
-
:insert_job => %{
|
101
|
-
INSERT INTO que_jobs
|
102
|
-
(queue, priority, run_at, job_class, args)
|
103
|
-
VALUES
|
104
|
-
(coalesce($1, '')::text, coalesce($2, 100)::smallint, coalesce($3, now())::timestamptz, $4::text, coalesce($5, '[]')::json)
|
105
|
-
RETURNING *
|
106
|
-
}.freeze,
|
107
|
-
|
108
|
-
:destroy_job => %{
|
109
|
-
DELETE FROM que_jobs
|
110
|
-
WHERE queue = $1::text
|
111
|
-
AND priority = $2::smallint
|
112
|
-
AND run_at = $3::timestamptz
|
113
|
-
AND job_id = $4::bigint
|
114
|
-
}.freeze,
|
115
|
-
|
116
|
-
:job_stats => %{
|
117
|
-
SELECT queue,
|
118
|
-
job_class,
|
119
|
-
count(*) AS count,
|
120
|
-
count(locks.job_id) AS count_working,
|
121
|
-
sum((error_count > 0)::int) AS count_errored,
|
122
|
-
max(error_count) AS highest_error_count,
|
123
|
-
min(run_at) AS oldest_run_at
|
124
|
-
FROM que_jobs
|
125
|
-
LEFT JOIN (
|
126
|
-
SELECT (classid::bigint << 32) + objid::bigint AS job_id
|
127
|
-
FROM pg_locks
|
128
|
-
WHERE locktype = 'advisory'
|
129
|
-
) locks USING (job_id)
|
130
|
-
GROUP BY queue, job_class
|
131
|
-
ORDER BY count(*) DESC
|
132
|
-
}.freeze,
|
133
|
-
|
134
|
-
:worker_states_95 => %{
|
135
|
-
SELECT que_jobs.*,
|
136
|
-
pg.pid AS pg_backend_pid,
|
137
|
-
pg.state AS pg_state,
|
138
|
-
pg.state_change AS pg_state_changed_at,
|
139
|
-
pg.query AS pg_last_query,
|
140
|
-
pg.query_start AS pg_last_query_started_at,
|
141
|
-
pg.xact_start AS pg_transaction_started_at,
|
142
|
-
pg.waiting AS pg_waiting_on_lock
|
143
|
-
FROM que_jobs
|
144
|
-
JOIN (
|
145
|
-
SELECT (classid::bigint << 32) + objid::bigint AS job_id, pg_stat_activity.*
|
146
|
-
FROM pg_locks
|
147
|
-
JOIN pg_stat_activity USING (pid)
|
148
|
-
WHERE locktype = 'advisory'
|
149
|
-
) pg USING (job_id)
|
150
|
-
}.freeze,
|
151
|
-
|
152
|
-
:worker_states_96 => %{
|
153
|
-
SELECT que_jobs.*,
|
154
|
-
pg.pid AS pg_backend_pid,
|
155
|
-
pg.state AS pg_state,
|
156
|
-
pg.state_change AS pg_state_changed_at,
|
157
|
-
pg.query AS pg_last_query,
|
158
|
-
pg.query_start AS pg_last_query_started_at,
|
159
|
-
pg.xact_start AS pg_transaction_started_at,
|
160
|
-
pg.wait_event_type IS NOT NULL AS pg_waiting_on_lock
|
161
|
-
FROM que_jobs
|
162
|
-
JOIN (
|
163
|
-
SELECT (classid::bigint << 32) + objid::bigint AS job_id, pg_stat_activity.*
|
164
|
-
FROM pg_locks
|
165
|
-
JOIN pg_stat_activity USING (pid)
|
166
|
-
WHERE locktype = 'advisory'
|
167
|
-
) pg USING (job_id)
|
168
|
-
}.freeze,
|
169
|
-
}.freeze
|
170
|
-
end
|
@@ -1,175 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Don't run these specs in JRuby until jruby-pg is compatible with ActiveRecord.
|
4
|
-
unless defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
|
5
|
-
|
6
|
-
require 'spec_helper'
|
7
|
-
require 'active_record'
|
8
|
-
|
9
|
-
if ActiveRecord.version.release >= Gem::Version.new('4.2') && ActiveRecord.version.release < Gem::Version.new('5.0')
|
10
|
-
ActiveRecord::Base.raise_in_transactional_callbacks = true
|
11
|
-
end
|
12
|
-
ActiveRecord::Base.establish_connection(QUE_URL)
|
13
|
-
|
14
|
-
Que.connection = ActiveRecord
|
15
|
-
QUE_ADAPTERS[:active_record] = Que.adapter
|
16
|
-
|
17
|
-
describe "Que using the ActiveRecord adapter" do
|
18
|
-
before { Que.adapter = QUE_ADAPTERS[:active_record] }
|
19
|
-
|
20
|
-
it_behaves_like "a multi-threaded Que adapter"
|
21
|
-
|
22
|
-
it "should use the same connection that ActiveRecord does" do
|
23
|
-
begin
|
24
|
-
class ActiveRecordJob < Que::Job
|
25
|
-
def run
|
26
|
-
$pid1 = Integer(Que.execute("select pg_backend_pid()").first['pg_backend_pid'])
|
27
|
-
$pid2 = Integer(ActiveRecord::Base.connection.select_value("select pg_backend_pid()"))
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
ActiveRecordJob.enqueue
|
32
|
-
Que::Job.work
|
33
|
-
|
34
|
-
$pid1.should == $pid2
|
35
|
-
ensure
|
36
|
-
$pid1 = $pid2 = nil
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
context "if the connection goes down and is reconnected" do
|
41
|
-
around do |example|
|
42
|
-
Que::Job.enqueue
|
43
|
-
::ActiveRecord::Base.connection_pool.with_connection do |conn|
|
44
|
-
ActiveRecord::Base.connection.reconnect!
|
45
|
-
example.run
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
it "should recreate the prepared statements" do
|
50
|
-
expect { Que::Job.enqueue }.not_to raise_error
|
51
|
-
|
52
|
-
DB[:que_jobs].count.should == 2
|
53
|
-
end
|
54
|
-
|
55
|
-
it "should work properly even in a transaction" do
|
56
|
-
ActiveRecord::Base.transaction do
|
57
|
-
expect { Que::Job.enqueue }.not_to raise_error
|
58
|
-
end
|
59
|
-
|
60
|
-
DB[:que_jobs].count.should == 2
|
61
|
-
end
|
62
|
-
|
63
|
-
it "should log this extraordinary event" do
|
64
|
-
pending
|
65
|
-
$logger.messages.clear
|
66
|
-
Que::Job.enqueue
|
67
|
-
|
68
|
-
if $logger.messages.count != 1
|
69
|
-
puts $logger.messages.inspect
|
70
|
-
end
|
71
|
-
|
72
|
-
$logger.messages.count.should == 1
|
73
|
-
message = JSON.load($logger.messages.first)
|
74
|
-
message['lib'].should == 'que'
|
75
|
-
message['event'].should == 'reprepare_statement'
|
76
|
-
message['name'].should == 'insert_job'
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
it "should instantiate args as ActiveSupport::HashWithIndifferentAccess" do
|
81
|
-
begin
|
82
|
-
# Mimic the setting in the Railtie.
|
83
|
-
Que.json_converter = :with_indifferent_access.to_proc
|
84
|
-
|
85
|
-
ArgsJob.enqueue :param => 2
|
86
|
-
Que::Job.work
|
87
|
-
$passed_args.first[:param].should == 2
|
88
|
-
$passed_args.first.should be_an_instance_of ActiveSupport::HashWithIndifferentAccess
|
89
|
-
ensure
|
90
|
-
Que.json_converter = Que::INDIFFERENTIATOR
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
it "should support Rails' special extensions for times" do
|
95
|
-
Que.mode = :async
|
96
|
-
Que.worker_count = 4
|
97
|
-
sleep_until { Que::Worker.workers.all? &:sleeping? }
|
98
|
-
|
99
|
-
Que::Job.enqueue :run_at => 1.minute.ago
|
100
|
-
DB[:que_jobs].get(:run_at).should be_within(3).of Time.now - 60
|
101
|
-
|
102
|
-
Que.wake_interval = 0.005.seconds
|
103
|
-
sleep_until { DB[:que_jobs].empty? }
|
104
|
-
end
|
105
|
-
|
106
|
-
it "should wake up a Worker after queueing a job in async mode, waiting for a transaction to commit if necessary" do
|
107
|
-
pending
|
108
|
-
|
109
|
-
Que.mode = :async
|
110
|
-
Que.worker_count = 4
|
111
|
-
sleep_until { Que::Worker.workers.all? &:sleeping? }
|
112
|
-
|
113
|
-
# Wakes a worker immediately when not in a transaction.
|
114
|
-
Que::Job.enqueue
|
115
|
-
sleep_until { Que::Worker.workers.all?(&:sleeping?) && DB[:que_jobs].empty? }
|
116
|
-
|
117
|
-
# Wakes a worker on transaction commit when in a transaction.
|
118
|
-
ActiveRecord::Base.transaction do
|
119
|
-
Que::Job.enqueue
|
120
|
-
Que::Worker.workers.each { |worker| worker.should be_sleeping }
|
121
|
-
end
|
122
|
-
sleep_until { Que::Worker.workers.all?(&:sleeping?) && DB[:que_jobs].empty? }
|
123
|
-
|
124
|
-
# Does nothing when in a nested transaction.
|
125
|
-
# TODO: ideally this would wake after the outer transaction commits
|
126
|
-
if ActiveRecord.version.release >= Gem::Version.new('5.0')
|
127
|
-
ActiveRecord::Base.transaction do
|
128
|
-
ActiveRecord::Base.transaction(requires_new: true) do
|
129
|
-
Que::Job.enqueue
|
130
|
-
Que::Worker.workers.each { |worker| worker.should be_sleeping }
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
# Do nothing when queueing with a specific :run_at.
|
136
|
-
BlockJob.enqueue :run_at => Time.now
|
137
|
-
Que::Worker.workers.each { |worker| worker.should be_sleeping }
|
138
|
-
end
|
139
|
-
|
140
|
-
it "should be able to survive an ActiveRecord::Rollback without raising an error" do
|
141
|
-
ActiveRecord::Base.transaction do
|
142
|
-
Que::Job.enqueue
|
143
|
-
raise ActiveRecord::Rollback, "Call tech support!"
|
144
|
-
end
|
145
|
-
DB[:que_jobs].count.should be 0
|
146
|
-
end
|
147
|
-
|
148
|
-
it "should be able to tell when it's in an ActiveRecord transaction" do
|
149
|
-
Que.adapter.should_not be_in_transaction
|
150
|
-
ActiveRecord::Base.transaction do
|
151
|
-
Que.adapter.should be_in_transaction
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
it "should not leak connections to other databases when using ActiveRecord's multiple database support" do
|
156
|
-
class SecondDatabaseModel < ActiveRecord::Base
|
157
|
-
establish_connection(QUE_URL)
|
158
|
-
end
|
159
|
-
|
160
|
-
SecondDatabaseModel.clear_active_connections!
|
161
|
-
SecondDatabaseModel.connection_handler.active_connections?.should == false
|
162
|
-
|
163
|
-
class SecondDatabaseModelJob < Que::Job
|
164
|
-
def run(*args)
|
165
|
-
SecondDatabaseModel.connection.execute("SELECT 1")
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
SecondDatabaseModelJob.enqueue
|
170
|
-
Que::Job.work
|
171
|
-
|
172
|
-
SecondDatabaseModel.connection_handler.active_connections?.should == false
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|