lib/tasks/switchman.rake in switchman-3.4.2 vs lib/tasks/switchman.rake in switchman-3.5.0
- old
+ new
@@ -1,40 +1,41 @@
# frozen_string_literal: true
# In rails 7.0+ if you have only 1 db in the env it doesn't try to do explicit activation
# (and for rails purposes we only have one db per env because each database server is a separate env)
-if Rails.version < '7.0'
- task_prefix = Rake::Task.task_defined?('app:db:migrate') ? 'app:db' : 'db'
+if Rails.version < "7.0"
+ task_prefix = Rake::Task.task_defined?("app:db:migrate") ? "app:db" : "db"
Rake::Task["#{task_prefix}:migrate"].clear_actions.enhance do
ActiveRecord::Tasks::DatabaseTasks.migrate
# Ensure this doesn't blow up when running inside the dummy app
Rake::Task["#{task_prefix}:_dump"].invoke
end
end
module Switchman
module Rake
- def self.filter_database_servers(&block)
- chain = filter_database_servers_chain # use a local variable so that the current chain is closed over in the following lambda
- @filter_database_servers_chain = ->(servers) { block.call(servers, chain) }
+ def self.filter_database_servers
+ # use a local variable so that the current chain is closed over in the following lambda
+ chain = filter_database_servers_chain
+ @filter_database_servers_chain = ->(servers) { yield(servers, chain) }
end
def self.scope(base_scope = Shard,
- database_server: ENV.fetch('DATABASE_SERVER', nil),
- shard: ENV.fetch('SHARD', nil))
+ database_server: ENV.fetch("DATABASE_SERVER", nil),
+ shard: ENV.fetch("SHARD", nil))
servers = DatabaseServer.all
if database_server
servers = database_server
- if servers.first == '-'
+ if servers.first == "-"
negative = true
servers = servers[1..]
end
- servers = servers.split(',')
- open = servers.delete('open')
+ servers = servers.split(",")
+ open = servers.delete("open")
- servers = servers.map { |server| DatabaseServer.find(server) }.compact
+ servers = servers.filter_map { |server| DatabaseServer.find(server) }
if open
open_servers = DatabaseServer.all.select { |server| server.config[:open] }
servers.concat(open_servers)
servers << DatabaseServer.find(nil) if open_servers.empty?
servers.uniq!
@@ -42,11 +43,11 @@
servers = DatabaseServer.all - servers if negative
end
servers = filter_database_servers_chain.call(servers)
- scope = base_scope.order(::Arel.sql('database_server_id IS NOT NULL, database_server_id, id'))
+ scope = base_scope.order(::Arel.sql("database_server_id IS NOT NULL, database_server_id, id"))
if servers != DatabaseServer.all
database_server_ids = servers.map(&:id)
database_server_ids << nil if servers.include?(Shard.default.database_server)
scope = scope.where(database_server_id: database_server_ids)
end
@@ -55,11 +56,11 @@
scope
end
def self.options
- { parallel: ENV['PARALLEL'].to_i }
+ { parallel: ENV["PARALLEL"].to_i }
end
# classes - an array or proc, to activate as the current shard during the
# task.
def self.shardify_task(task_name, classes: [::ActiveRecord::Base])
@@ -67,11 +68,11 @@
old_actions = old_task.actions.dup
old_task.actions.clear
old_task.enhance do |*task_args|
if ::Rails.env.test?
- require 'switchman/test_helper'
+ require "switchman/test_helper"
TestHelper.recreate_persistent_test_shards(dont_create: true)
end
::GuardRail.activate(:deploy) do
Shard.default.database_server.unguard do
@@ -84,11 +85,13 @@
old_actions.each { |action| action.call(*task_args) }
end
nil
end
rescue => e
- warn "Exception from #{e.current_shard.id}: #{e.current_shard.description}:\n#{e.full_message}" if options[:parallel] != 0
+ if options[:parallel] != 0
+ warn "Exception from #{e.current_shard.id}: #{e.current_shard.description}:\n#{e.full_message}"
+ end
raise
end
end
end
end
@@ -96,36 +99,36 @@
%w[db:migrate db:migrate:up db:migrate:down db:rollback].each do |task_name|
shardify_task(task_name)
end
def self.shard_scope(scope, raw_shard_ids)
- raw_shard_ids = raw_shard_ids.split(',')
+ raw_shard_ids = raw_shard_ids.split(",")
shard_ids = []
negative_shard_ids = []
ranges = []
negative_ranges = []
total_shard_count = nil
raw_shard_ids.each do |id|
case id
- when 'default'
+ when "default"
shard_ids << Shard.default.id
- when '-default'
+ when "-default"
negative_shard_ids << Shard.default.id
- when 'primary'
+ when "primary"
shard_ids.concat(Shard.primary.pluck(:id))
- when '-primary'
+ when "-primary"
negative_shard_ids.concat(Shard.primary.pluck(:id))
when /^(-?)(\d+)?\.\.(\.)?(\d+)?$/
negative, start, open, finish = $1.present?, $2, $3.present?, $4
raise "Invalid shard id or range: #{id}" unless start || finish
range = []
range << "id>=#{start}" if start
- range << "id<#{'=' unless open}#{finish}" if finish
- (negative ? negative_ranges : ranges) << "(#{range.join(' AND ')})"
+ range << "id<#{"=" unless open}#{finish}" if finish
+ (negative ? negative_ranges : ranges) << "(#{range.join(" AND ")})"
when /^-(\d+)$/
negative_shard_ids << $1.to_i
when /^\d+$/
shard_ids << id.to_i
when %r{^(-?\d+)/(\d+)$}
@@ -149,25 +152,25 @@
subscope = Shard.select(:id).order(:id)
select = []
if index != 1
subscope = subscope.offset(per_chunk * (index - 1))
- select << 'MIN(id) AS min_id'
+ select << "MIN(id) AS min_id"
end
if index != denominator
subscope = subscope.limit(per_chunk)
- select << 'MAX(id) AS max_id'
+ select << "MAX(id) AS max_id"
end
- result = Shard.from(subscope).select(select.join(', ')).to_a.first
+ result = Shard.from(subscope).select(select.join(", ")).to_a.first
range = case index
when 1
- "id<=#{result['max_id']}"
+ "id<=#{result["max_id"]}"
when denominator
- "id>=#{result['min_id']}"
+ "id>=#{result["min_id"]}"
else
- "(id>=#{result['min_id']} AND id<=#{result['max_id']})"
+ "(id>=#{result["min_id"]} AND id<=#{result["max_id"]})"
end
(numerator.negative? ? negative_ranges : ranges) << range
else
raise "Invalid shard id or range: #{id}"
@@ -184,20 +187,20 @@
negative_shard_ids = [] if ranges.empty?
end
conditions = []
positive_queries = []
- positive_queries << ranges.join(' OR ') unless ranges.empty?
+ positive_queries << ranges.join(" OR ") unless ranges.empty?
unless shard_ids.empty?
- positive_queries << 'id IN (?)'
+ positive_queries << "id IN (?)"
conditions << shard_ids
end
- positive_query = positive_queries.join(' OR ')
+ positive_query = positive_queries.join(" OR ")
scope = scope.where(positive_query, *conditions) unless positive_queries.empty?
- scope = scope.where("NOT (#{negative_ranges.join(' OR')})") unless negative_ranges.empty?
- scope = scope.where('id NOT IN (?)', negative_shard_ids) unless negative_shard_ids.empty?
+ scope = scope.where("NOT (#{negative_ranges.join(" OR")})") unless negative_ranges.empty?
+ scope = scope.where("id NOT IN (?)", negative_shard_ids) unless negative_shard_ids.empty?
scope
end
def self.filter_database_servers_chain
@filter_database_servers_chain ||= ->(servers) { servers }
@@ -206,22 +209,22 @@
module ActiveRecord
module PostgreSQLDatabaseTasks
def structure_dump(filename, extra_flags = nil)
set_psql_env
- args = ['--schema-only', '--no-privileges', '--no-owner', '--file', filename]
+ args = ["--schema-only", "--no-privileges", "--no-owner", "--file", filename]
args.concat(Array(extra_flags)) if extra_flags
shard = Shard.current.name
serialized_search_path = shard
args << "--schema=#{Shellwords.escape(shard)}"
ignore_tables = ::ActiveRecord::SchemaDumper.ignore_tables
- args += ignore_tables.flat_map { |table| ['-T', table] } if ignore_tables.any?
+ args += ignore_tables.flat_map { |table| ["-T", table] } if ignore_tables.any?
args << db_config.database
- run_cmd('pg_dump', args, 'dumping')
+ run_cmd("pg_dump", args, "dumping")
remove_sql_header_comments(filename)
- File.open(filename, 'a') { |f| f << "SET search_path TO #{serialized_search_path};\n\n" }
+ File.open(filename, "a") { |f| f << "SET search_path TO #{serialized_search_path};\n\n" }
end
end
end
end