Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Using multiple connections in ActiveRecord

Using multiple connections in ActiveRecord

Arthur Nogueira Neves

August 06, 2016
Tweet

More Decks by Arthur Nogueira Neves

Other Decks in Technology

Transcript

  1. How people build software ! ! Open source 3 •

    Rails commiter team • rubygems.org • memcached gem CONTRIBUTORS.RUBYONRAILS.ORG
  2. How people build software ! Agenda 4 • Before Rails

    5 • What is new in Rails 5 • Future work in Rails 5.1 #
  3. How people build software ! ! Use cases for different

    connections 6 • Data partitioning • Read only database • Sharding
  4. How people build software ! ! 8 1 # user.rb

    2 class User < ActiveRecord::Base 3 establish_connection :user_db 4 end 5 6 # database.yml 7 development: 8 database: foo_db 9 user_db: 10 database: user_db
  5. How people build software ! ! 11 1 def establish_connection(owner,

    spec) 2 @class_to_pool.clear 3 raise RuntimeError, "Anonymous class is not allowed." unless owner.name 4 owner_to_pool[owner.name] = ConnectionAdapters::ConnectionPool.new(spec) 5 end
  6. How people build software ! ! 12 1 def retrieve_connection_pool(klass)

    2 class_to_pool[klass.name] ||= begin 3 until pool = pool_for(klass) 4 klass = klass.superclass 5 break unless klass <= Base 6 end 7 8 class_to_pool[klass.name] = pool 9 end 10 end
  7. How people build software ! ! Solutions 13 • Install

    a gem. • db_charmer • octopus • apartment • Do your own • Inline extend models • multiple connection handlers
  8. How people build software ! ! Multiple connection handlers 16

    1 class ConnectionSwitcher 2 def initialize 3 self.handlers = {readonly: ConnectionHandler.new} 4 end 5 6 def with_readonly(&block) 7 before = ActiveRecord::Base.connection_handler 8 ActiveRecord::Base.connection_handler = handlers[:readonly] 9 yield 10 ensure 11 ActiveRecord::Base.connection_handler = before 12 end 13 end
  9. How people build software ! ! Multiple connection handlers 17

    1 class User < ActiveRecord::Base 2 establish_connection :user_db 3 switcher.with_readonly do 4 establish_connection :user_db_readonly 5 end 6 end 7 8 switcher.with_readonly do 9 user = User.find 10 end
  10. How people build software ! ! Rails 5 20 •

    Decouple Active Record model and connection pool • Model.establish_connection() method • Use a new key for the connection pools list • Fix all the things around it
  11. How people build software ! ! Handler establish_connection code 21

    1 def establish_connection(config) 2 resolver = ConnectionSpecification::Resolver.new(Base.configurations) 3 spec = resolver.spec(config) 4 5 remove_connection(spec.name) 6 owner_to_pool[spec.name] = ConnectionAdapters::ConnectionPool.new(spec) 7 end
  12. How people build software ! ! Data partitioning use case

    22 1 # initializer 2 ActiveRecord::Base.connection_handler.establish_connection :user_db 3 4 # user.rb 5 class User < ActiveRecord::Base 6 self.connection_specification_name = :user_db 7 end
  13. How people build software ! ! Readonly use case 23

    1 class User < ActiveRecord::Base 2 attr_writer :readonly_mode 3 4 def self.connection_specification_name 5 if readonly_mode 6 "readonly" 7 else 8 "primary" 9 end 10 end 11 end 12 13 User.readonly_mode = true 14 user = User.find(1)
  14. How people build software ! ! Backwards compatible 25 1

    class User < ActiveRecord::Base 2 establish_connection :user_db 3 end Model.establish_connection still works: ⚠ Don’t use it ⚠
  15. How people build software ! ! Rails 5.1 27 •

    Better database.yml • Improve db: tasks • establish all connections during boot
  16. How people build software ! ! Better database.yml 28 1

    # database.yml 2 development: 3 primary: 4 database: foo_development 5 adapter: mysql2 6 shard1: 7 database: foo2_development 8 adapter: mysql2 9 readonly: 10 database: foo_development 11 user: readonly_user 12 adapter: mysql2 13 test: 14 primary: 15 production: 16 primary:
  17. How people build software ! ! Rails 5.1 29 •

    Better database.yml • Improve db: tasks • establish all connections during boot • Migrations • Fixtures
  18. How people build software ! ! Summary 30 • Rails

    < 5 • Lot of code necessary + Patches in AR • Rails 5 • Ground work is done for ease connection handling • Rails 5.1 • Will have even more improvements