aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_controller
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_controller')
-rw-r--r--actionpack/lib/action_controller/metal/live.rb15
-rw-r--r--actionpack/lib/action_controller/test_case.rb10
2 files changed, 23 insertions, 2 deletions
diff --git a/actionpack/lib/action_controller/metal/live.rb b/actionpack/lib/action_controller/metal/live.rb
index e3c540bf5f..acc4507b2d 100644
--- a/actionpack/lib/action_controller/metal/live.rb
+++ b/actionpack/lib/action_controller/metal/live.rb
@@ -237,9 +237,8 @@ module ActionController
# This processes the action in a child thread. It lets us return the
# response code and headers back up the rack stack, and still process
# the body in parallel with sending data to the client
- Thread.new {
+ new_controller_thread {
t2 = Thread.current
- t2.abort_on_exception = true
# Since we're processing the view in a different thread, copy the
# thread locals from the main thread to the child thread. :'(
@@ -270,6 +269,18 @@ module ActionController
raise error if error
end
+ # Spawn a new thread to serve up the controller in. This is to get
+ # around the fact that Rack isn't based around IOs and we need to use
+ # a thread to stream data from the response bodies. Nobody should call
+ # this method except in Rails internals. Seriously!
+ def new_controller_thread # :nodoc:
+ Thread.new {
+ t2 = Thread.current
+ t2.abort_on_exception = true
+ yield
+ }
+ end
+
def log_error(exception)
logger = ActionController::Base.logger
return unless logger
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb
index b43bb9dc17..ac45b2e363 100644
--- a/actionpack/lib/action_controller/test_case.rb
+++ b/actionpack/lib/action_controller/test_case.rb
@@ -12,6 +12,16 @@ module ActionController
include Testing::Functional
end
+ module Live
+ # Disable controller / rendering threads in tests. User tests can access
+ # the database on the main thread, so they could open a txn, then the
+ # controller thread will open a new connection and try to access data
+ # that's only visible to the main thread's txn. This is the problem in #23483
+ def new_controller_thread # :nodoc:
+ yield
+ end
+ end
+
# ActionController::TestCase will be deprecated and moved to a gem in Rails 5.1.
# Please use ActionDispatch::IntegrationTest going forward.
class TestRequest < ActionDispatch::TestRequest #:nodoc: