92 lines
2.5 KiB
Ruby
92 lines
2.5 KiB
Ruby
|
module Gitlab
|
||
|
module Git
|
||
|
module Storage
|
||
|
class Health
|
||
|
attr_reader :storage_name, :info
|
||
|
|
||
|
def self.pattern_for_storage(storage_name)
|
||
|
"#{Gitlab::Git::Storage::REDIS_KEY_PREFIX}#{storage_name}:*"
|
||
|
end
|
||
|
|
||
|
def self.for_all_storages
|
||
|
storage_names = Gitlab.config.repositories.storages.keys
|
||
|
results_per_storage = nil
|
||
|
|
||
|
Gitlab::Git::Storage.redis.with do |redis|
|
||
|
keys_per_storage = all_keys_for_storages(storage_names, redis)
|
||
|
results_per_storage = load_for_keys(keys_per_storage, redis)
|
||
|
end
|
||
|
|
||
|
results_per_storage.map do |name, info|
|
||
|
info.each { |i| i[:failure_count] = i[:failure_count].value.to_i }
|
||
|
new(name, info)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def self.all_keys_for_storages(storage_names, redis)
|
||
|
keys_per_storage = {}
|
||
|
|
||
|
redis.pipelined do
|
||
|
storage_names.each do |storage_name|
|
||
|
pattern = pattern_for_storage(storage_name)
|
||
|
|
||
|
keys_per_storage[storage_name] = redis.keys(pattern)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
keys_per_storage
|
||
|
end
|
||
|
|
||
|
def self.load_for_keys(keys_per_storage, redis)
|
||
|
info_for_keys = {}
|
||
|
|
||
|
redis.pipelined do
|
||
|
keys_per_storage.each do |storage_name, keys_future|
|
||
|
info_for_storage = keys_future.value.map do |key|
|
||
|
{ name: key, failure_count: redis.hget(key, :failure_count) }
|
||
|
end
|
||
|
|
||
|
info_for_keys[storage_name] = info_for_storage
|
||
|
end
|
||
|
end
|
||
|
|
||
|
info_for_keys
|
||
|
end
|
||
|
|
||
|
def self.for_failing_storages
|
||
|
for_all_storages.select(&:failing?)
|
||
|
end
|
||
|
|
||
|
def initialize(storage_name, info)
|
||
|
@storage_name = storage_name
|
||
|
@info = info
|
||
|
end
|
||
|
|
||
|
def failing_info
|
||
|
@failing_info ||= info.select { |info_for_host| info_for_host[:failure_count] > 0 }
|
||
|
end
|
||
|
|
||
|
def failing?
|
||
|
failing_info.any?
|
||
|
end
|
||
|
|
||
|
def failing_on_hosts
|
||
|
@failing_on_hosts ||= failing_info.map do |info_for_host|
|
||
|
info_for_host[:name].split(':').last
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def failing_circuit_breakers
|
||
|
@failing_circuit_breakers ||= failing_on_hosts.map do |hostname|
|
||
|
CircuitBreaker.new(storage_name, hostname)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def total_failures
|
||
|
@total_failures ||= failing_info.sum { |info_for_host| info_for_host[:failure_count] }
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|