1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00
rails--rails/actioncable/test/subscription_adapter/postgresql_test.rb
Jon Moss 686f6a762f Action Cable owns database connection, not Active Record
Before this commit, the database connection used in Action Cable's
PostgreSQL adapter was "owned" by `ActiveRecord::Base.connection_pool`.
This meant that if, for example, `#clear_reloadable_connections!` was called on the pool, Active
Record would "steal" the database connection from Action Cable, and
would cause all sorts of issues. This became evident during file
reloads; despite Action Cable trying its hardest to return its borrowed
database connection to Active Record via `@pubsub.shutdown`, Active Record calls
`#clear_reloadable_connections!` on the connection pool, and due to the order of callbacks, Active
Record's callback was being executed first. This meant that if you tried
to rerender a view after a file was reloaded, you would have to wait
through Active Record's timeout and such.

Now, Action Cable takes direct ownership of the database connection it
uses. It removes the connection from the pool to avoid the situation
described above. Action Cable also makes sure to call `#disconnect!` on
the connection when appropriate, to match the previous behavior of
Active Record.

[ Jon Moss & Matthew Draper]
2017-03-25 12:44:20 -04:00

63 lines
1.6 KiB
Ruby

require "test_helper"
require_relative "./common"
require "active_record"
class PostgresqlAdapterTest < ActionCable::TestCase
include CommonSubscriptionAdapterTest
def setup
database_config = { "adapter" => "postgresql", "database" => "activerecord_unittest" }
ar_tests = File.expand_path("../../../activerecord/test", __dir__)
if Dir.exist?(ar_tests)
require File.join(ar_tests, "config")
require File.join(ar_tests, "support/config")
local_config = ARTest.config["arunit"]
database_config.update local_config if local_config
end
ActiveRecord::Base.establish_connection database_config
begin
ActiveRecord::Base.connection
rescue
@rx_adapter = @tx_adapter = nil
skip "Couldn't connect to PostgreSQL: #{database_config.inspect}"
end
super
end
def teardown
super
ActiveRecord::Base.clear_all_connections!
end
def cable_config
{ adapter: "postgresql" }
end
def test_clear_active_record_connections_adapter_still_works
server = ActionCable::Server::Base.new
server.config.cable = cable_config.with_indifferent_access
server.config.logger = Logger.new(StringIO.new).tap { |l| l.level = Logger::UNKNOWN }
adapter_klass = Class.new(server.config.pubsub_adapter) do
def active?
!@listener.nil?
end
end
adapter = adapter_klass.new(server)
subscribe_as_queue("channel", adapter) do |queue|
adapter.broadcast("channel", "hello world")
assert_equal "hello world", queue.pop
end
ActiveRecord::Base.clear_reloadable_connections!
assert adapter.active?
end
end