Commit 8eb35066 authored by Jacob Vosmaer's avatar Jacob Vosmaer

Deal with Rails autoload instance variable resets

Rails auto-load (a development feature) can end up resetting instance
variables on classes. This breaks Gitlab::GitalyClient, which uses
instance variables to keep global hashes to look up channels and
addresses. This change adds code that regenerates the hashes if they
suddenly become nil.
parent a40e357f
...@@ -2,17 +2,5 @@ require 'uri' ...@@ -2,17 +2,5 @@ require 'uri'
# Make sure we initialize our Gitaly channels before Sidekiq starts multi-threaded execution. # Make sure we initialize our Gitaly channels before Sidekiq starts multi-threaded execution.
if Gitlab.config.gitaly.enabled || Rails.env.test? if Gitlab.config.gitaly.enabled || Rails.env.test?
Gitlab.config.repositories.storages.each do |name, params| Gitlab::GitalyClient.configure_channels
address = params['gitaly_address']
unless address.present?
raise "storage #{name.inspect} is missing a gitaly_address"
end
unless URI(address).scheme.in?(%w(tcp unix))
raise "Unsupported Gitaly address: #{address.inspect}"
end
Gitlab::GitalyClient.configure_channel(name, address)
end
end end
...@@ -4,11 +4,23 @@ module Gitlab ...@@ -4,11 +4,23 @@ module Gitlab
module GitalyClient module GitalyClient
SERVER_VERSION_FILE = 'GITALY_SERVER_VERSION'.freeze SERVER_VERSION_FILE = 'GITALY_SERVER_VERSION'.freeze
def self.configure_channel(storage, address) # This function is not thread-safe because it updates Hashes in instance variables.
@addresses ||= {} def self.configure_channels
@addresses[storage] = address @addresses = {}
@channels ||= {} @channels = {}
@channels[storage] = new_channel(address) Gitlab.config.repositories.storages.each do |name, params|
address = params['gitaly_address']
unless address.present?
raise "storage #{name.inspect} is missing a gitaly_address"
end
unless URI(address).scheme.in?(%w(tcp unix))
raise "Unsupported Gitaly address: #{address.inspect}"
end
@addresses[name] = address
@channels[name] = new_channel(address)
end
end end
def self.new_channel(address) def self.new_channel(address)
...@@ -21,10 +33,26 @@ module Gitlab ...@@ -21,10 +33,26 @@ module Gitlab
end end
def self.get_channel(storage) def self.get_channel(storage)
if !Rails.env.production? && @channels.nil?
# In development mode the Rails auto-loader may reset the instance
# variables of this class. What we do here is not thread-safe. In normal
# circumstances (including production) these instance variables have
# been initialized from config/initializers.
configure_channels
end
@channels[storage] @channels[storage]
end end
def self.get_address(storage) def self.get_address(storage)
if !Rails.env.production? && @addresses.nil?
# In development mode the Rails auto-loader may reset the instance
# variables of this class. What we do here is not thread-safe. In normal
# circumstances (including development) these instance variables have
# been initialized from config/initializers.
configure_channels
end
@addresses[storage] @addresses[storage]
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment