mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge pull request #40626 from jonathanhefner/executor-wrap-db-seeds
Wrap evaluation of db/seeds.rb with the executor
This commit is contained in:
commit
90fa01b4c0
6 changed files with 35 additions and 76 deletions
|
@ -12,7 +12,7 @@ module ActiveJob
|
||||||
# Rails.application.config.active_job.queue_adapter = :inline
|
# Rails.application.config.active_job.queue_adapter = :inline
|
||||||
class InlineAdapter
|
class InlineAdapter
|
||||||
def enqueue(job) #:nodoc:
|
def enqueue(job) #:nodoc:
|
||||||
Thread.new { Base.execute(job.serialize) }.join
|
Base.execute(job.serialize)
|
||||||
end
|
end
|
||||||
|
|
||||||
def enqueue_at(*) #:nodoc:
|
def enqueue_at(*) #:nodoc:
|
||||||
|
|
|
@ -4,7 +4,6 @@ require "helper"
|
||||||
require "jobs/logging_job"
|
require "jobs/logging_job"
|
||||||
require "jobs/hello_job"
|
require "jobs/hello_job"
|
||||||
require "jobs/provider_jid_job"
|
require "jobs/provider_jid_job"
|
||||||
require "jobs/thread_job"
|
|
||||||
require "active_support/core_ext/numeric/time"
|
require "active_support/core_ext/numeric/time"
|
||||||
|
|
||||||
class QueuingTest < ActiveSupport::TestCase
|
class QueuingTest < ActiveSupport::TestCase
|
||||||
|
@ -146,21 +145,4 @@ class QueuingTest < ActiveSupport::TestCase
|
||||||
assert job_executed "#{@id}.2"
|
assert job_executed "#{@id}.2"
|
||||||
assert job_executed_at("#{@id}.2") < job_executed_at("#{@id}.1")
|
assert job_executed_at("#{@id}.2") < job_executed_at("#{@id}.1")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "inline jobs run on separate threads" do
|
|
||||||
skip unless adapter_is?(:inline)
|
|
||||||
|
|
||||||
after_job_thread = Thread.new do
|
|
||||||
ThreadJob.latch.wait
|
|
||||||
assert_nil Thread.current[:job_ran]
|
|
||||||
assert ThreadJob.thread[:job_ran]
|
|
||||||
ThreadJob.test_latch.count_down
|
|
||||||
end
|
|
||||||
|
|
||||||
ThreadJob.perform_later
|
|
||||||
|
|
||||||
after_job_thread.join
|
|
||||||
|
|
||||||
assert_nil Thread.current[:job_ran]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class ThreadJob < ActiveJob::Base
|
|
||||||
class << self
|
|
||||||
attr_accessor :thread
|
|
||||||
|
|
||||||
def latch
|
|
||||||
@latch ||= Concurrent::CountDownLatch.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_latch
|
|
||||||
@test_latch ||= Concurrent::CountDownLatch.new
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def perform
|
|
||||||
Thread.current[:job_ran] = true
|
|
||||||
self.class.thread = Thread.current
|
|
||||||
self.class.latch.count_down
|
|
||||||
self.class.test_latch.wait
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
require "rails/railtie"
|
require "rails/railtie"
|
||||||
require "rails/engine/railties"
|
require "rails/engine/railties"
|
||||||
|
require "active_support/callbacks"
|
||||||
require "active_support/core_ext/module/delegation"
|
require "active_support/core_ext/module/delegation"
|
||||||
require "active_support/core_ext/object/try"
|
require "active_support/core_ext/object/try"
|
||||||
require "pathname"
|
require "pathname"
|
||||||
|
@ -422,6 +423,9 @@ module Rails
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
include ActiveSupport::Callbacks
|
||||||
|
define_callbacks :load_seed
|
||||||
|
|
||||||
delegate :middleware, :root, :paths, to: :config
|
delegate :middleware, :root, :paths, to: :config
|
||||||
delegate :engine_name, :isolated?, to: :class
|
delegate :engine_name, :isolated?, to: :class
|
||||||
|
|
||||||
|
@ -559,13 +563,7 @@ module Rails
|
||||||
# Blog::Engine.load_seed
|
# Blog::Engine.load_seed
|
||||||
def load_seed
|
def load_seed
|
||||||
seed_file = paths["db/seeds.rb"].existent.first
|
seed_file = paths["db/seeds.rb"].existent.first
|
||||||
return unless seed_file
|
run_callbacks(:load_seed) { load(seed_file) } if seed_file
|
||||||
|
|
||||||
if config.try(:active_job)&.queue_adapter == :async
|
|
||||||
with_inline_jobs { load(seed_file) }
|
|
||||||
else
|
|
||||||
load(seed_file)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
initializer :load_environment_config, before: :load_environment_hook, group: :all do
|
initializer :load_environment_config, before: :load_environment_hook, group: :all do
|
||||||
|
@ -637,6 +635,12 @@ module Rails
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
initializer :wrap_executor_around_load_seed do |app|
|
||||||
|
self.class.set_callback(:load_seed, :around) do |engine, seeds_block|
|
||||||
|
app.executor.wrap(&seeds_block)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
initializer :engines_blank_point do
|
initializer :engines_blank_point do
|
||||||
# We need this initializer so all extra initializers added in engines are
|
# We need this initializer so all extra initializers added in engines are
|
||||||
# consistently executed after all the initializers above across all engines.
|
# consistently executed after all the initializers above across all engines.
|
||||||
|
@ -678,18 +682,6 @@ module Rails
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def with_inline_jobs
|
|
||||||
queue_adapter = config.active_job.queue_adapter
|
|
||||||
ActiveSupport.on_load(:active_job) do
|
|
||||||
self.queue_adapter = :inline
|
|
||||||
end
|
|
||||||
yield
|
|
||||||
ensure
|
|
||||||
ActiveSupport.on_load(:active_job) do
|
|
||||||
self.queue_adapter = queue_adapter
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def has_migrations?
|
def has_migrations?
|
||||||
paths["db/migrate"].existent.any?
|
paths["db/migrate"].existent.any?
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "rails/initializable"
|
require "rails/initializable"
|
||||||
|
require "active_support/descendants_tracker"
|
||||||
require "active_support/inflector"
|
require "active_support/inflector"
|
||||||
require "active_support/core_ext/module/introspection"
|
require "active_support/core_ext/module/introspection"
|
||||||
require "active_support/core_ext/module/delegation"
|
require "active_support/core_ext/module/delegation"
|
||||||
|
@ -135,6 +136,7 @@ module Rails
|
||||||
class Railtie
|
class Railtie
|
||||||
autoload :Configuration, "rails/railtie/configuration"
|
autoload :Configuration, "rails/railtie/configuration"
|
||||||
|
|
||||||
|
extend ActiveSupport::DescendantsTracker
|
||||||
include Initializable
|
include Initializable
|
||||||
|
|
||||||
ABSTRACT_RAILTIES = %w(Rails::Railtie Rails::Engine Rails::Application)
|
ABSTRACT_RAILTIES = %w(Rails::Railtie Rails::Engine Rails::Application)
|
||||||
|
@ -144,13 +146,7 @@ module Rails
|
||||||
delegate :config, to: :instance
|
delegate :config, to: :instance
|
||||||
|
|
||||||
def subclasses
|
def subclasses
|
||||||
@subclasses ||= []
|
super.reject(&:abstract_railtie?)
|
||||||
end
|
|
||||||
|
|
||||||
def inherited(base)
|
|
||||||
unless base.abstract_railtie?
|
|
||||||
subclasses << base
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def rake_tasks(&blk)
|
def rake_tasks(&blk)
|
||||||
|
|
|
@ -879,29 +879,40 @@ en:
|
||||||
assert Bukkits::Engine.config.bukkits_seeds_loaded
|
assert Bukkits::Engine.config.bukkits_seeds_loaded
|
||||||
end
|
end
|
||||||
|
|
||||||
test "jobs are ran inline while loading seeds with async adapter configured" do
|
test "loading seed data is wrapped by the executor" do
|
||||||
app_file "db/seeds.rb", <<-RUBY
|
app_file "db/seeds.rb", <<-RUBY
|
||||||
Rails.application.config.seed_queue_adapter = ActiveJob::Base.queue_adapter
|
Rails.application.config.seeding_wrapped_by_executor = Rails.application.executor.active?
|
||||||
RUBY
|
RUBY
|
||||||
|
|
||||||
boot_rails
|
boot_rails
|
||||||
Rails.application.load_seed
|
Rails.application.load_seed
|
||||||
|
|
||||||
assert_instance_of ActiveJob::QueueAdapters::InlineAdapter, Rails.application.config.seed_queue_adapter
|
assert_predicate Rails.application.config, :seeding_wrapped_by_executor
|
||||||
assert_instance_of ActiveJob::QueueAdapters::AsyncAdapter, ActiveJob::Base.queue_adapter
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test "jobs are ran with original adapter while loading seeds with custom adapter configured" do
|
test "inline jobs do not clear CurrentAttributes when loading seed data" do
|
||||||
app_file "db/seeds.rb", <<-RUBY
|
app_file "db/seeds.rb", <<-RUBY
|
||||||
Rails.application.config.seed_queue_adapter = ActiveJob::Base.queue_adapter
|
class SeedsAttributes < ActiveSupport::CurrentAttributes
|
||||||
|
attribute :foo
|
||||||
|
end
|
||||||
|
|
||||||
|
class SeedsJob < ActiveJob::Base
|
||||||
|
self.queue_adapter = :inline
|
||||||
|
def perform
|
||||||
|
Rails.application.config.seeds_job_ran = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
SeedsAttributes.foo = 42
|
||||||
|
SeedsJob.perform_later
|
||||||
|
Rails.application.config.seeds_attributes_foo = SeedsAttributes.foo
|
||||||
RUBY
|
RUBY
|
||||||
|
|
||||||
boot_rails
|
boot_rails
|
||||||
Rails.application.config.active_job.queue_adapter = :delayed_job
|
|
||||||
Rails.application.load_seed
|
Rails.application.load_seed
|
||||||
|
|
||||||
assert_instance_of ActiveJob::QueueAdapters::DelayedJobAdapter, Rails.application.config.seed_queue_adapter
|
assert Rails.application.config.seeds_job_ran
|
||||||
assert_instance_of ActiveJob::QueueAdapters::DelayedJobAdapter, ActiveJob::Base.queue_adapter
|
assert_equal 42, Rails.application.config.seeds_attributes_foo
|
||||||
end
|
end
|
||||||
|
|
||||||
test "seed data can be loaded when ActiveJob is not present" do
|
test "seed data can be loaded when ActiveJob is not present" do
|
||||||
|
|
Loading…
Reference in a new issue