makara icon indicating copy to clipboard operation
makara copied to clipboard

Override master db selection method not working

Open aman199002 opened this issue 4 years ago • 2 comments

I need to modify the default condition for master db selection in my application based on some cached value. I have defined a custom proxy class as mentioned in documentation in config/initializers directory.

class MyAwesomeSqlProxy < ::Makara::Proxy
  hijack_method :select, :ping
  send_to_all :connect, :reconnect, :disconnect, :clear_cache

  def connection_for(config)
    ::Sql::Client.new(config)
  end

  def needs_master?(method_name, args)
    # Modified this method for testing to always route to master    
    return true  
  end
end

Any changes in this class does not seem to work. Do I need to define this class at some other location and load explicitly? Or this feature to override db selection is not supported as mentioned in documentation?

aman199002 avatar Feb 11 '22 04:02 aman199002

It's been awhile for sure, but I don't see your database.yml here. There is some thing to set this Proxy to the adapter: in your database.yml.

I'd consider extending to one you need, too. For example if you are using MySQL, do

module ActiveRecord
  module ConnectionAdapters
    class MakaraTestingAdapter < ActiveRecord::ConnectionAdapters::MakaraMysql2Adapter
       def needs_primary?(method_name, args)
          # Modified this method for testing to always route to primary    
          return true  
      end
  end
end

database.yml

production:
  adapter: 'testing'

  makara:
   ...

bleonard avatar Feb 12 '22 01:02 bleonard

I tried the same with postgresql as mentioned below.

config/initializes/postgresql_makara_custom_adapter.rb

module ActiveRecord
  module ConnectionAdapters
    class PostgresqlMakaraCustomAdapter < ::Makara::Proxy
      
      def needs_primary?(method_name, args)
          # Modified this method for testing to always route to primary    
          return true  
      end

    end
  end
end
  

database.yml

production:
  adapter: 'postgresql_makara_custom'
  makara:
   ...

Getting active_record error on load when running the application: activerecord-5.1.4/lib/active_record/connection_adapters/connection_specification.rb:196:in `spec': undefined method `config' for #<Hash:0x00007fc4a0e036e0> (NoMethodError)

However I checked the code inside gem and tried by overriding the makara_abstract_adapter class via monkey patching in my application as mentioned below: config/initializes/makara_abstract_adapter.rb

module ActiveRecord
  module ConnectionAdapters
    class MakaraAbstractAdapter < ::Makara::Proxy

      protected

      def needs_master?(method_name, args)
        return true if replication_lag?
        sql = coerce_query_to_sql_string(args.first)
        return true if sql_master_matchers.any?{|m| sql =~ m }
        return false if sql_slave_matchers.any?{|m| sql =~ m }
        true
      end
      
      private

      def replication_lag?
        ....
      end

    end
  end
end

database.yml

production:
  adapter: postgresql_makara
  makara:
   ...

The same is working and I can modify the condition inside needs_master method.

aman199002 avatar Feb 14 '22 12:02 aman199002