FIX: Reconnect in restore process connects to correct DB (#8218)

Simplified flow of restore is like that
```
migrate_database
reconnect
extract_uploads
```

Problem with incorrect current database started with this fix https://github.com/discourse/discourse/commit/025d4ee91f4

Dump task is reconnecting to default database https://github.com/rails/rails/blob/master/activerecord/lib/active_record/railties/databases.rake#L429

And then, we are trying to reconnect to the original database with that code:
```
def reconnect_database
  log "Reconnecting to the database..."
  RailsMultisite::ConnectionManagement::establish_connection(db: @current_db)
end
```

This reconnect is not switching us back to correct database because of that check
https://github.com/discourse/rails_multisite/blob/master/lib/rails_multisite/connection_management.rb#L181
Basically, it finds existing handler and it thinks that we are connected to correct DB and this step can be skipped.

To solve it, we can reload RailsMultisite::ConnectionManagement which creates a new instance of that class
https://github.com/discourse/rails_multisite/blob/master/lib/rails_multisite/connection_management.rb#L38
This commit is contained in:
Krzysztof Kotlarek 2019-10-23 17:23:50 +11:00 committed by Sam
parent 950da34826
commit f69dacf979
2 changed files with 23 additions and 0 deletions

View File

@ -404,6 +404,7 @@ module BackupRestore
def reconnect_database
log "Reconnecting to the database..."
RailsMultisite::ConnectionManagement::reload
RailsMultisite::ConnectionManagement::establish_connection(db: @current_db)
end

View File

@ -100,4 +100,26 @@ describe BackupRestore::Restorer do
@restorer.copy_archive_to_tmp_directory
end
end
context 'Database connection' do
fab!(:admin) { Fabricate(:admin) }
before do
SiteSetting.allow_restore = true
@restore_path = File.join(Rails.root, 'public', 'backups', RailsMultisite::ConnectionManagement.current_db)
described_class.any_instance.stubs(ensure_we_have_a_filename: true)
described_class.any_instance.stubs(initialize_state: true)
end
let(:conn) { RailsMultisite::ConnectionManagement }
let(:restorer) { described_class.new(admin.id) }
it 'correctly reconnects to database' do
restorer.instance_variable_set(:@current_db, 'second')
conn.config_filename = "spec/fixtures/multisite/two_dbs.yml"
conn.establish_connection(db: 'second')
expect(RailsMultisite::ConnectionManagement.current_db).to eq('second')
ActiveRecord::Base.connection_pool.spec.config[:db_key] = "incorrect_db"
restorer.send(:reconnect_database)
expect(RailsMultisite::ConnectionManagement.current_db).to eq('second')
end
end
end