canvas-lms/db/migrate/20120101163452_migrate_queu...

85 lines
2.9 KiB
Ruby

#
# Copyright (C) 2016 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
class MigrateQueueToDefaultShard < ActiveRecord::Migration[4.2]
tag :predeploy
def up
return unless Shard.current.default?
return unless ActiveRecord::Base.configurations[Rails.env]['queue']
db_config = ActiveRecord::Base.configurations[Rails.env].dup
queue_config = db_config.delete('queue')
# they're on the same db
return if db_config == queue_config
return if ActiveRecord::Base.connection.table_exists?(:delayed_jobs)
# create the correct schema in the default shard
migrations = jobs_migrations
migrations.each do |m|
next unless ActiveRecord::SchemaMigration.where(version: m.version.to_s).exists?
m.migrate(:up)
end
# now copy stuff over
queue_conn = ActiveRecord::Base.postgresql_connection(queue_config)
# lock jobs in case old jobs code is still running
queue_conn.execute("UPDATE delayed_jobs SET locked_by='queue_migration' WHERE locked_by IS NULL")
rows = queue_conn.select_all("SELECT * FROM delayed_jobs WHERE locked_by='queue_migration'")
ActiveRecord::Base.connection.bulk_insert('delayed_jobs', rows)
table = ActiveRecord::Base.connection.quote_table_name('delayed_jobs')
ActiveRecord::Base.connection.execute("UPDATE #{table} SET locked_by=NULL WHERE locked_by='queue_migration'")
seq = ActiveRecord::Base.connection.quote_table_name('delayed_jobs_id_seq')
ActiveRecord::Base.connection.execute("SELECT setval('#{seq}', (SELECT MAX(id) FROM #{table}))")
end
def down
raise ActiveRecord::IrreversibleMigration
end
def jobs_migrations
jobs = Delayed::Backend::ActiveRecord::Job
jobs.class_eval do
class << self
alias_method :old_connection, :connection
def connection
@sentinel
end
end
end
sentinel = Object.new
jobs.instance_variable_set(:@sentinel, sentinel)
migrations = ActiveRecord::Migrator.migrations(ActiveRecord::Migrator.migrations_paths).select do |m|
m.send(:migration).new.connection == sentinel
end
jobs.class_eval do
class << self
alias_method :connection, :old_connection
remove_method :old_connection
end
end
jobs.send(:remove_instance_variable, :@sentinel)
migrations
end
end