From 8d32346cdec04dd85ab682eeb9f4edfcd0c9ccef Mon Sep 17 00:00:00 2001 From: Eileen Uchitelle Date: Fri, 1 Feb 2019 11:33:48 -0500 Subject: Add ability to change the names of the default handlers When I wrote the `connected_to` and `connects_to` API's I wrote them with the idea in mind that it didn't really matter what the handlers/roles were called as long as those connecting to the roles knew which one wrote and which one read. With the introduction of the middleware Rails begins to assume it's `writing` and `reading` and there's no room for other roles. At GitHub we've been using this method for a long time so we have a ton of legacy code that uses different handler names `default` and `readonly`. We could rename all our code but I think this is better for a few reasons: - Legacy apps that have been using multiple databases for a long time can have an eaiser time switching. - If we later find this to cause more issues than it's worth we can easily deprecate. - We won't force old apps to rewrite the resolver middleware just to use a different handler. Adding the writing_role/reading_role required that I move the code that creates the first handler for writing to the railtie. If I didn't move this the core class would assign the handler before I was able to assign a new one in my configuration and I'd end up with 3 handlers instead of 2. --- activerecord/lib/active_record/core.rb | 5 ++++- .../lib/active_record/middleware/database_selector/resolver.rb | 6 +++--- activerecord/lib/active_record/railtie.rb | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index 519acd7605..84604452f7 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -125,6 +125,10 @@ module ActiveRecord mattr_accessor :connection_handlers, instance_accessor: false, default: {} + mattr_accessor :writing_role, instance_accessor: false, default: :writing + + mattr_accessor :reading_role, instance_accessor: false, default: :reading + class_attribute :default_connection_handler, instance_writer: false self.filter_attributes = [] @@ -138,7 +142,6 @@ module ActiveRecord end self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new - self.connection_handlers = { writing: ActiveRecord::Base.default_connection_handler } end module ClassMethods diff --git a/activerecord/lib/active_record/middleware/database_selector/resolver.rb b/activerecord/lib/active_record/middleware/database_selector/resolver.rb index acdb9b3238..fc71835cea 100644 --- a/activerecord/lib/active_record/middleware/database_selector/resolver.rb +++ b/activerecord/lib/active_record/middleware/database_selector/resolver.rb @@ -45,7 +45,7 @@ module ActiveRecord def read_from_primary(&blk) ActiveRecord::Base.connection.while_preventing_writes do - ActiveRecord::Base.connected_to(role: :writing) do + ActiveRecord::Base.connected_to(role: ActiveRecord::Base.writing_role) do instrumenter.instrument("database_selector.active_record.read_from_primary") do yield end @@ -54,7 +54,7 @@ module ActiveRecord end def read_from_replica(&blk) - ActiveRecord::Base.connected_to(role: :reading) do + ActiveRecord::Base.connected_to(role: ActiveRecord::Base.reading_role) do instrumenter.instrument("database_selector.active_record.read_from_replica") do yield end @@ -62,7 +62,7 @@ module ActiveRecord end def write_to_primary(&blk) - ActiveRecord::Base.connected_to(role: :writing) do + ActiveRecord::Base.connected_to(role: ActiveRecord::Base.writing_role) do instrumenter.instrument("database_selector.active_record.wrote_to_primary") do yield ensure diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb index a981fa97d9..f0b5ab2f08 100644 --- a/activerecord/lib/active_record/railtie.rb +++ b/activerecord/lib/active_record/railtie.rb @@ -197,6 +197,7 @@ end_error # and then establishes the connection. initializer "active_record.initialize_database" do ActiveSupport.on_load(:active_record) do + self.connection_handlers = { writing_role => ActiveRecord::Base.default_connection_handler } self.configurations = Rails.application.config.database_configuration establish_connection end -- cgit v1.2.3