aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorMatthew Draper <matthew@trebex.net>2018-01-25 00:39:07 +1030
committerMatthew Draper <matthew@trebex.net>2018-01-25 01:01:51 +1030
commit1280ad6d19fa56e9bf6d6a261c1231326cb3d8c3 (patch)
treea5087cd2d1c8fb92cb9350815cd748f5e7e7feac /activerecord
parentee1fda121effe791676460d72cf1bcaafe052e22 (diff)
downloadrails-1280ad6d19fa56e9bf6d6a261c1231326cb3d8c3.tar.gz
rails-1280ad6d19fa56e9bf6d6a261c1231326cb3d8c3.tar.bz2
rails-1280ad6d19fa56e9bf6d6a261c1231326cb3d8c3.zip
Make discard safe when it follows a manual disconnect
It doesn't have to do anything, but it shouldn't fail. Fixes #31766.
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb2
-rw-r--r--activerecord/test/cases/connection_adapters/connection_handler_test.rb40
2 files changed, 41 insertions, 1 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index ddc5a91286..dc6287e32c 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -281,7 +281,7 @@ module ActiveRecord
end
def discard! # :nodoc:
- @connection.socket_io.reopen(IO::NULL)
+ @connection.socket_io.reopen(IO::NULL) rescue nil
@connection = nil
end
diff --git a/activerecord/test/cases/connection_adapters/connection_handler_test.rb b/activerecord/test/cases/connection_adapters/connection_handler_test.rb
index 603ed63a8c..ef0b00b36c 100644
--- a/activerecord/test/cases/connection_adapters/connection_handler_test.rb
+++ b/activerecord/test/cases/connection_adapters/connection_handler_test.rb
@@ -171,6 +171,46 @@ module ActiveRecord
assert_equal 3, ActiveRecord::Base.connection.select_value("SELECT COUNT(*) FROM people")
end
+ def test_forked_child_recovers_from_disconnected_parent
+ object_id = ActiveRecord::Base.connection.object_id
+ assert ActiveRecord::Base.connection.active?
+
+ rd, wr = IO.pipe
+ rd.binmode
+ wr.binmode
+
+ outer_pid = fork {
+ ActiveRecord::Base.connection.disconnect!
+
+ pid = fork {
+ rd.close
+ if ActiveRecord::Base.connection.active?
+ pair = [ActiveRecord::Base.connection.object_id,
+ ActiveRecord::Base.connection.select_value("SELECT COUNT(*) FROM people")]
+ wr.write Marshal.dump pair
+ end
+ wr.close
+
+ exit # allow finalizers to run
+ }
+
+ Process.waitpid pid
+ }
+
+ wr.close
+
+ Process.waitpid outer_pid
+ child_id, child_count = Marshal.load(rd.read)
+
+ assert_not_equal object_id, child_id
+ rd.close
+
+ assert_equal 3, child_count
+
+ # Outer connection is unaffected
+ assert_equal 6, ActiveRecord::Base.connection.select_value("SELECT 2 * COUNT(*) FROM people")
+ end
+
def test_retrieve_connection_pool_copies_schema_cache_from_ancestor_pool
@pool.schema_cache = @pool.connection.schema_cache
@pool.schema_cache.add("posts")