mirror of
https://github.com/codeninjasllc/discourse.git
synced 2025-02-17 04:01:29 -05:00
fix Rails 4 multisite so connection handlers don't keep spinning up new pools
This commit is contained in:
parent
dee38dad9d
commit
0327f6e02a
7 changed files with 113 additions and 16 deletions
7
vendor/gems/rails_multisite/Gemfile
vendored
7
vendor/gems/rails_multisite/Gemfile
vendored
|
@ -1,11 +1,14 @@
|
||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
gem 'rails'
|
gem 'rails'
|
||||||
gem 'rspec'
|
gem 'rspec'
|
||||||
gem 'activerecord'
|
gem 'activerecord'
|
||||||
gem 'sqlite3'
|
gem 'sqlite3'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
gem 'guard'
|
||||||
|
gem 'guard-rspec'
|
||||||
|
|
||||||
# Specify your gem's dependencies in rails_multisite.gemspec
|
# Specify your gem's dependencies in rails_multisite.gemspec
|
||||||
gemspec
|
gemspec
|
||||||
|
|
9
vendor/gems/rails_multisite/Guardfile
vendored
Normal file
9
vendor/gems/rails_multisite/Guardfile
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# A sample Guardfile
|
||||||
|
# More info at https://github.com/guard/guard#readme
|
||||||
|
|
||||||
|
guard :rspec do
|
||||||
|
watch(%r{^spec/.+_spec\.rb$})
|
||||||
|
watch(%r{^lib/rails_multisite/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
||||||
|
watch('spec/spec_helper.rb') { "spec" }
|
||||||
|
end
|
||||||
|
|
|
@ -16,16 +16,23 @@ module RailsMultisite
|
||||||
handler = @@connection_handlers[spec]
|
handler = @@connection_handlers[spec]
|
||||||
unless handler
|
unless handler
|
||||||
handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
|
handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
|
||||||
|
if rails4?
|
||||||
|
handler.establish_connection(ActiveRecord::Base, spec)
|
||||||
|
end
|
||||||
@@connection_handlers[spec] = handler
|
@@connection_handlers[spec] = handler
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
handler = @@default_connection_handler
|
handler = @@default_connection_handler
|
||||||
|
if rails4? && !@@established_default
|
||||||
|
handler.establish_connection(ActiveRecord::Base, spec)
|
||||||
|
@@established_default = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
ActiveRecord::Base.connection_handler = handler
|
ActiveRecord::Base.connection_handler = handler
|
||||||
if rails4?
|
|
||||||
ActiveRecord::Base.connection_handler.establish_connection(ActiveRecord::Base, spec)
|
unless rails4?
|
||||||
else
|
handler.establish_connection("ActiveRecord::Base", spec)
|
||||||
ActiveRecord::Base.connection_handler.establish_connection("ActiveRecord::Base", spec)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -100,17 +107,19 @@ module RailsMultisite
|
||||||
@@host_spec_cache[host] = @@default_spec
|
@@host_spec_cache[host] = @@default_spec
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@@default_connection_handler = ActiveRecord::Base.connection_handler
|
||||||
|
|
||||||
# inject our connection_handler pool
|
# inject our connection_handler pool
|
||||||
# WARNING MONKEY PATCH
|
# WARNING MONKEY PATCH
|
||||||
#
|
#
|
||||||
# see: https://github.com/rails/rails/issues/8344#issuecomment-10800848
|
# see: https://github.com/rails/rails/issues/8344#issuecomment-10800848
|
||||||
#
|
if ActiveRecord::VERSION::MAJOR == 3
|
||||||
@@default_connection_handler = ActiveRecord::Base.connection_handler
|
ActiveRecord::Base.send :include, NewConnectionHandler
|
||||||
ActiveRecord::Base.send :include, NewConnectionHandler if ActiveRecord::VERSION::MAJOR == 3
|
ActiveRecord::Base.connection_handler = @@default_connection_handler
|
||||||
|
end
|
||||||
ActiveRecord::Base.connection_handler = @@default_connection_handler
|
|
||||||
|
|
||||||
@@connection_handlers = {}
|
@@connection_handlers = {}
|
||||||
|
@@established_default = false
|
||||||
end
|
end
|
||||||
|
|
||||||
module NewConnectionHandler
|
module NewConnectionHandler
|
||||||
|
|
|
@ -1,16 +1,26 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
require 'rails_multisite'
|
require 'rails_multisite'
|
||||||
|
|
||||||
|
class Person < ActiveRecord::Base; end
|
||||||
|
|
||||||
describe RailsMultisite::ConnectionManagement do
|
describe RailsMultisite::ConnectionManagement do
|
||||||
|
|
||||||
subject { RailsMultisite::ConnectionManagement }
|
subject { RailsMultisite::ConnectionManagement }
|
||||||
|
|
||||||
|
def with_connection(db)
|
||||||
|
subject.establish_connection(db: db)
|
||||||
|
yield ActiveRecord::Base.connection.raw_connection
|
||||||
|
ensure
|
||||||
|
ActiveRecord::Base.connection_handler.clear_active_connections!
|
||||||
|
end
|
||||||
|
|
||||||
context 'default' do
|
context 'default' do
|
||||||
its(:all_dbs) { should == ['default']}
|
its(:all_dbs) { should == ['default']}
|
||||||
|
|
||||||
context 'current' do
|
context 'current' do
|
||||||
before do
|
before do
|
||||||
subject.establish_connection(db: 'default')
|
subject.establish_connection(db: 'default')
|
||||||
|
ActiveRecord::Base.establish_connection
|
||||||
end
|
end
|
||||||
|
|
||||||
its(:current_db) { should == 'default' }
|
its(:current_db) { should == 'default' }
|
||||||
|
@ -25,6 +35,7 @@ describe RailsMultisite::ConnectionManagement do
|
||||||
subject.config_filename = "spec/fixtures/two_dbs.yml"
|
subject.config_filename = "spec/fixtures/two_dbs.yml"
|
||||||
subject.load_settings!
|
subject.load_settings!
|
||||||
end
|
end
|
||||||
|
|
||||||
its(:all_dbs) { should == ['default', 'second']}
|
its(:all_dbs) { should == ['default', 'second']}
|
||||||
|
|
||||||
context 'second db' do
|
context 'second db' do
|
||||||
|
@ -36,6 +47,53 @@ describe RailsMultisite::ConnectionManagement do
|
||||||
its(:current_hostname) { should == "second.localhost" }
|
its(:current_hostname) { should == "second.localhost" }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'data partitioning' do
|
||||||
|
after do
|
||||||
|
['default','second'].each do |db|
|
||||||
|
with_connection(db) do |cnn|
|
||||||
|
cnn.execute("drop table people") rescue nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'partitions data correctly' do
|
||||||
|
col1 = []
|
||||||
|
col2 = []
|
||||||
|
|
||||||
|
['default','second'].map do |db|
|
||||||
|
|
||||||
|
with_connection(db) do |cnn|
|
||||||
|
cnn.execute("create table if not exists people(id INTEGER PRIMARY KEY AUTOINCREMENT, db)")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
SQLite3::Database.query_log.clear
|
||||||
|
|
||||||
|
5.times do
|
||||||
|
['default','second'].map do |db|
|
||||||
|
Thread.new do
|
||||||
|
with_connection(db) do |cnn|
|
||||||
|
Person.create!(db: db)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end.map(&:join)
|
||||||
|
end
|
||||||
|
|
||||||
|
lists = []
|
||||||
|
['default', 'second'].each do |db|
|
||||||
|
with_connection(db) do |cnn|
|
||||||
|
lists << Person.order(:id).to_a.map{|p| [p.id, p.db]}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
lists[1].should == (1..5).map{|id| [id, "second"]}
|
||||||
|
lists[0].should == (1..5).map{|id| [id, "default"]}
|
||||||
|
|
||||||
|
# puts SQLite3::Database.query_log.map{|args, caller, oid| "#{oid} #{args.join.inspect}"}.join("\n")
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
test:
|
test:
|
||||||
adapter: sqlite3
|
adapter: sqlite3
|
||||||
database: rails_multisite
|
database: "db.test"
|
||||||
timeout: 5000
|
timeout: 5000
|
||||||
host_names:
|
host_names:
|
||||||
- default.localhost
|
- default.localhost
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
second:
|
second:
|
||||||
adapter: sqlite3
|
adapter: sqlite3
|
||||||
database: second_db
|
database: "db1.test"
|
||||||
username: username
|
|
||||||
password: password
|
|
||||||
db_id: 1
|
|
||||||
host_names:
|
host_names:
|
||||||
- second.localhost
|
- second.localhost
|
||||||
- 2nd.localhost
|
- 2nd.localhost
|
||||||
|
|
21
vendor/gems/rails_multisite/spec/spec_helper.rb
vendored
21
vendor/gems/rails_multisite/spec/spec_helper.rb
vendored
|
@ -6,6 +6,27 @@ require 'active_record'
|
||||||
ENV["RAILS_ENV"] ||= 'test'
|
ENV["RAILS_ENV"] ||= 'test'
|
||||||
RSpec.configure do |config|
|
RSpec.configure do |config|
|
||||||
|
|
||||||
|
require 'sqlite3'
|
||||||
|
class SQLite3::Database
|
||||||
|
def self.query_log
|
||||||
|
@@query_log ||= []
|
||||||
|
end
|
||||||
|
|
||||||
|
alias_method :old_execute, :execute
|
||||||
|
alias_method :old_prepare, :prepare
|
||||||
|
|
||||||
|
def execute(*args,&blk)
|
||||||
|
self.class.query_log << [args, caller, Thread.current.object_id]
|
||||||
|
old_execute(*args,&blk)
|
||||||
|
end
|
||||||
|
|
||||||
|
def prepare(*args,&blk)
|
||||||
|
self.class.query_log << [args, caller, Thread.current.object_id]
|
||||||
|
old_prepare(*args,&blk)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
config.color_enabled = true
|
config.color_enabled = true
|
||||||
|
|
||||||
config.before(:suite) do
|
config.before(:suite) do
|
||||||
|
|
Loading…
Reference in a new issue