lib/gizzard/commands.rb in gizzmo-0.4.2 vs lib/gizzard/commands.rb in gizzmo-0.5.0

- old
+ new

@@ -76,11 +76,11 @@ service.list_hostnames.map do |host| puts host end end end - + class ForwardingsCommand < ShardCommand def run service.get_forwardings().sort_by do |f| [ ((f.table_id.abs << 1) + (f.table_id < 0 ? 1 : 0)), f.base_id ] end.reject do |forwarding| @@ -255,15 +255,135 @@ output wrapper_id.to_unix end end end + class RebalanceCommand < ShardCommand + + class NamedArray < Array + attr_reader :name + def initialize(name) + @name = name + end + end + + def run + ids = @argv.map{|arg| ShardId.new(*arg.split("/")) rescue nil }.compact + by_host = ids.inject({}) do |memo, id| + memo[id.hostname] ||= NamedArray.new(id.hostname) + memo[id.hostname] << id + memo + end + + sets = by_host.values + + begin + sorted = sets.sort_by{|s| s.length } + longest = sorted.last + shortest = sorted.first + shortest.push longest.pop + end while longest.length > shortest.length + 1 + + shard_info = nil + sets.each do |set| + host = set.name + set.each do |id| + if id.hostname != host + shard_info ||= service.get_shard(id) + old = id.to_unix + id.hostname = host + puts "gizzmo create #{shard_info.class_name} -s '#{shard_info.source_type}' -d '#{shard_info.destination_type}' #{old}" + puts "gizzmo copy #{old} #{id.to_unix}" + puts "gizzmo delete #{old}" + end + end + end + end + end + + class PairCommand < ShardCommand + def run + ids = [] + @argv.map do |host| + service.shards_for_hostname(host).each do |shard| + ids << shard.id + end + end + + ids_by_table = {} + ids.map do |id| + ids_by_table[id.table_prefix] ||= [] + ids_by_table[id.table_prefix] << id + end + + ids_by_host = {} + ids.map do |id| + ids_by_host[id.hostname] ||= [] + ids_by_host[id.hostname] << id + end + + overlaps = {} + ids_by_table.values.each do |arr| + key = arr.map{|id| id.hostname }.sort + overlaps[key] ||= 0 + overlaps[key] += 1 + end + + displayed = {} + overlaps.sort_by{|hosts, count| count }.reverse.each do |(host_a, host_b), count| + next if !host_a || !host_b || displayed[host_a] || displayed[host_b] + id_a = ids_by_host[host_a].first + id_b = ids_by_host[host_b].first + weight_a = service.list_upward_links(id_a).first.weight + weight_b = service.list_upward_links(id_b).first.weight + if weight_a > weight_b + puts "#{host_a}\t#{host_b}" + else + puts "#{host_b}\t#{host_a}" + end + displayed[host_a] = true + displayed[host_b] = true + end + remaining = @argv - displayed.keys + loop do + a = remaining.shift + b = remaining.shift + break unless a && b + puts "#{a}\t#{b}" + end + end + end + + class ReportCommand < ShardCommand + def run + regex = @argv.first + help!("regex is a required option") unless regex + regex = Regexp.compile(regex) + service.list_hostnames.map do |host| + puts host + counts = {} + service.shards_for_hostname(host).each do |shard| + id = shard.id.to_unix + if key = id[regex, 1] || id[regex, 0] + counts[key] ||= 0 + counts[key] += 1 + end + end + counts.sort.each do |k, v| + puts " %3d %s" % [v, k] + end + end + end + end + class FindCommand < ShardCommand def run - help!("host is a required option") unless command_options.shard_host - service.shards_for_hostname(command_options.shard_host).each do |shard| - next if command_options.shard_type && shard.class_name !~ Regexp.new(command_options.shard_type) - output shard.id.to_unix + hosts = @argv << command_options.shard_host + hosts.compact.each do |host| + service.shards_for_hostname(host).each do |shard| + next if command_options.shard_type && shard.class_name !~ Regexp.new(command_options.shard_type) + output shard.id.to_unix + end end end end class LookupCommand < ShardCommand