Skip to content
  • eileencodes's avatar
    05821c6c
    Fix preventing writes for ApplicationRecord · 05821c6c
    eileencodes authored
    
    
    ApplicationRecord is special. If you have a multiple database
    application we need to treat `ApplicationRecord` and
    `ActiveRecord::Base` as the same connection, otherwise applications
    will end up with duplicate connections to the same database. This is
    problematic because there are a limited number of open connections an
    application could have to a single database. By not treating
    `ActiveRecord::Base` and `ApplicationRecord` the same we could
    effectively double connections to a database (then multiplied by the
    number of processes).
    
    In the case of granular connection swapping we need to be able to read
    `ApplicationRecord` off the stack while storing the
    `connection_specification_name` as `ActiveRecord::Base`. In order to do
    this we read the `current_preventing_writes` off the pool's
    "owner_name" which was `connection_specification_name`.
    
    To fix the issue here need to pass the original class to
    `establish_connection` on the handler and then down to the `PoolConfig`.
    We can then determine the `connection_specification_name` from the
    `connection_klass` the same way we did in `resolve_config_for_connection`.
    This isn't ideal, and I'd like to move away from the string class but
    this has been part of the known API for awhile so I don't feel
    comfortable changing that without investigation.
    
    We can then read the `connection_klass` in `preventing_writes?` instead
    of the connection specification name. If you're using a nil or string
    value for your class, then multiple databases really won't work so
    there's no point in supporting prevent writes for that.
    
    Co-authored-by: default avatarJohn Crepezzi <john.crepezzi@gmail.com>
    Co-authored-by: default avataralpaca-tc <alpaca-tc@alpaca.tc>
    05821c6c
    Fix preventing writes for ApplicationRecord
    eileencodes authored
    
    
    ApplicationRecord is special. If you have a multiple database
    application we need to treat `ApplicationRecord` and
    `ActiveRecord::Base` as the same connection, otherwise applications
    will end up with duplicate connections to the same database. This is
    problematic because there are a limited number of open connections an
    application could have to a single database. By not treating
    `ActiveRecord::Base` and `ApplicationRecord` the same we could
    effectively double connections to a database (then multiplied by the
    number of processes).
    
    In the case of granular connection swapping we need to be able to read
    `ApplicationRecord` off the stack while storing the
    `connection_specification_name` as `ActiveRecord::Base`. In order to do
    this we read the `current_preventing_writes` off the pool's
    "owner_name" which was `connection_specification_name`.
    
    To fix the issue here need to pass the original class to
    `establish_connection` on the handler and then down to the `PoolConfig`.
    We can then determine the `connection_specification_name` from the
    `connection_klass` the same way we did in `resolve_config_for_connection`.
    This isn't ideal, and I'd like to move away from the string class but
    this has been part of the known API for awhile so I don't feel
    comfortable changing that without investigation.
    
    We can then read the `connection_klass` in `preventing_writes?` instead
    of the connection specification name. If you're using a nil or string
    value for your class, then multiple databases really won't work so
    there's no point in supporting prevent writes for that.
    
    Co-authored-by: default avatarJohn Crepezzi <john.crepezzi@gmail.com>
    Co-authored-by: default avataralpaca-tc <alpaca-tc@alpaca.tc>
Loading