que 0.14.3 → 1.0.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- 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
|