mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
ActiveJob::Base#queue_adapter
is now a class_attribute
This allows different `queue_adapters` to be used in each `ActiveJob` class heirarchy. Previously, all subclasses used a single global queue adapter.
This commit is contained in:
parent
7884c8f88e
commit
1f8558fa27
4 changed files with 82 additions and 17 deletions
|
@ -1,4 +1,5 @@
|
|||
require 'active_job/queue_adapters/inline_adapter'
|
||||
require 'active_support/core_ext/class/attribute'
|
||||
require 'active_support/core_ext/string/inflections'
|
||||
|
||||
module ActiveJob
|
||||
|
@ -7,34 +8,45 @@ module ActiveJob
|
|||
module QueueAdapter #:nodoc:
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
class_attribute :_queue_adapter, instance_accessor: false, instance_predicate: false
|
||||
self.queue_adapter = :inline
|
||||
end
|
||||
|
||||
# Includes the setter method for changing the active queue adapter.
|
||||
module ClassMethods
|
||||
mattr_reader(:queue_adapter) { ActiveJob::QueueAdapters::InlineAdapter }
|
||||
def queue_adapter
|
||||
_queue_adapter
|
||||
end
|
||||
|
||||
# Specify the backend queue provider. The default queue adapter
|
||||
# is the :inline queue. See QueueAdapters for more
|
||||
# information.
|
||||
def queue_adapter=(name_or_adapter_or_class)
|
||||
self._queue_adapter = interpret_adapter(name_or_adapter_or_class)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def interpret_adapter(name_or_adapter_or_class)
|
||||
case name_or_adapter_or_class
|
||||
when Symbol, String
|
||||
self.queue_adapter = load_adapter(name_or_adapter_or_class)
|
||||
load_adapter(name_or_adapter_or_class)
|
||||
else
|
||||
@@queue_adapter = if queue_adapter?(name_or_adapter_or_class)
|
||||
if queue_adapter?(name_or_adapter_or_class)
|
||||
name_or_adapter_or_class
|
||||
elsif queue_adapter_class?(name_or_adapter_or_class)
|
||||
ActiveSupport::Deprecation.warn "Passing an adapter class is deprecated " \
|
||||
"and will be removed in Rails 5.1. Please pass an adapter name " \
|
||||
"(.queue_adapter = :#{name_or_adapter_or_class.name.demodulize.remove('Adapter').underscore}) " \
|
||||
"or an instance (.queue_adapter = #{name_or_adapter_or_class.name}.new) instead."
|
||||
name_or_adapter_or_class.new
|
||||
"and will be removed in Rails 5.1. Please pass an adapter name " \
|
||||
"(.queue_adapter = :#{name_or_adapter_or_class.name.demodulize.remove('Adapter').underscore}) " \
|
||||
"or an instance (.queue_adapter = #{name_or_adapter_or_class.name}.new) instead."
|
||||
name_or_adapter_or_class.new
|
||||
else
|
||||
raise ArgumentError
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
QUEUE_ADAPTER_METHODS = [:enqueue, :enqueue_at].freeze
|
||||
|
||||
def queue_adapter?(object)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
require 'active_support/core_ext/class/subclasses'
|
||||
require 'active_support/core_ext/hash/keys'
|
||||
|
||||
module ActiveJob
|
||||
|
@ -7,8 +8,17 @@ module ActiveJob
|
|||
|
||||
included do
|
||||
def before_setup
|
||||
@old_queue_adapter = queue_adapter
|
||||
ActiveJob::Base.queue_adapter = :test
|
||||
test_adapter = ActiveJob::QueueAdapters::TestAdapter.new
|
||||
|
||||
@old_queue_adapters = (ActiveJob::Base.subclasses << ActiveJob::Base).select do |klass|
|
||||
# only override explicitly set adapters, a quirk of `class_attribute`
|
||||
klass.singleton_class.public_instance_methods(false).include?(:_queue_adapter)
|
||||
end.map do |klass|
|
||||
[klass, klass.queue_adapter].tap do
|
||||
klass.queue_adapter = test_adapter
|
||||
end
|
||||
end
|
||||
|
||||
clear_enqueued_jobs
|
||||
clear_performed_jobs
|
||||
super
|
||||
|
@ -16,7 +26,9 @@ module ActiveJob
|
|||
|
||||
def after_teardown
|
||||
super
|
||||
ActiveJob::Base.queue_adapter = @old_queue_adapter
|
||||
@old_queue_adapters.each do |(klass, adapter)|
|
||||
klass.queue_adapter = adapter
|
||||
end
|
||||
end
|
||||
|
||||
# Asserts that the number of enqueued jobs matches the given number.
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
require 'helper'
|
||||
|
||||
module ActiveJob
|
||||
module QueueAdapters
|
||||
class StubOneAdapter
|
||||
def enqueue(*); end
|
||||
def enqueue_at(*); end
|
||||
end
|
||||
|
||||
class StubTwoAdapter
|
||||
def enqueue(*); end
|
||||
def enqueue_at(*); end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class QueueAdapterTest < ActiveJob::TestCase
|
||||
test 'should forbid nonsense arguments' do
|
||||
assert_raises(ArgumentError) { ActiveJob::Base.queue_adapter = Mutex }
|
||||
|
@ -12,13 +26,31 @@ class QueueAdapterTest < ActiveJob::TestCase
|
|||
'fake'
|
||||
end
|
||||
|
||||
def enqueue(*)
|
||||
end
|
||||
|
||||
def enqueue_at(*)
|
||||
end
|
||||
def enqueue(*); end
|
||||
def enqueue_at(*); end
|
||||
end
|
||||
|
||||
assert_deprecated { ActiveJob::Base.queue_adapter = klass }
|
||||
end
|
||||
|
||||
test 'should allow overriding the queue_adapter at the child class level without affecting the parent or its sibling' do
|
||||
base_queue_adapter = ActiveJob::Base.queue_adapter
|
||||
|
||||
child_job_one = Class.new(ActiveJob::Base)
|
||||
child_job_one.queue_adapter = :stub_one
|
||||
|
||||
assert_not_equal ActiveJob::Base.queue_adapter, child_job_one.queue_adapter
|
||||
assert_kind_of ActiveJob::QueueAdapters::StubOneAdapter, child_job_one.queue_adapter
|
||||
|
||||
child_job_two = Class.new(ActiveJob::Base)
|
||||
child_job_two.queue_adapter = :stub_two
|
||||
|
||||
assert_kind_of ActiveJob::QueueAdapters::StubTwoAdapter, child_job_two.queue_adapter
|
||||
assert_kind_of ActiveJob::QueueAdapters::StubOneAdapter, child_job_one.queue_adapter, "child_job_one's queue adapter should remain unchanged"
|
||||
assert_equal base_queue_adapter, ActiveJob::Base.queue_adapter, "ActiveJob::Base's queue adapter should remain unchanged"
|
||||
|
||||
child_job_three = Class.new(ActiveJob::Base)
|
||||
|
||||
assert_not_nil child_job_three.queue_adapter
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,6 +4,15 @@ require 'jobs/logging_job'
|
|||
require 'jobs/nested_job'
|
||||
|
||||
class ActiveJobTestCaseTest < ActiveJob::TestCase
|
||||
# this tests that this job class doesn't get its adapter set.
|
||||
# that's the correct behaviour since we don't want to break
|
||||
# the `class_attribute` inheritence
|
||||
class TestClassAttributeInheritenceJob < ActiveJob::Base
|
||||
def self.queue_adapter=(*)
|
||||
raise 'Attemping to break `class_attribute` inheritence, bad!'
|
||||
end
|
||||
end
|
||||
|
||||
def test_include_helper
|
||||
assert_includes self.class.ancestors, ActiveJob::TestHelper
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue