Commit 7d4db67a authored by Matthias Kaeppler's avatar Matthias Kaeppler

Track nil `proxy` to Sentry upon field access

We have a late-init scenario where load balancing isn't available before
configure_proxy is called. Logging this condition to sentry makes these
failures easier to track and diagnose.
parent fe6c395e
......@@ -3,9 +3,6 @@
module Gitlab
module Database
module LoadBalancing
# The connection proxy to use for load balancing (if enabled).
cattr_accessor :proxy
# The exceptions raised for connection errors.
CONNECTION_ERRORS = if defined?(PG)
[
......@@ -22,6 +19,21 @@ module Gitlab
[].freeze
end
ProxyNotConfiguredError = Class.new(StandardError)
# The connection proxy to use for load balancing (if enabled).
def self.proxy
unless @proxy
Gitlab::ErrorTracking.track_exception(
ProxyNotConfiguredError.new(
"Attempting to access the database load balancing proxy, but it wasn't configured.\n" \
"Did you forget to call '#{self.name}.configure_proxy'?"
))
end
@proxy
end
# Returns a Hash containing the load balancing configuration.
def self.configuration
ActiveRecord::Base.configurations[Rails.env]['load_balancing'] || {}
......@@ -89,8 +101,8 @@ module Gitlab
end
# Configures proxying of requests.
def self.configure_proxy
self.proxy = ConnectionProxy.new(hosts)
def self.configure_proxy(proxy = ConnectionProxy.new(hosts))
@proxy = proxy
# This hijacks the "connection" method to ensure both
# `ActiveRecord::Base.connection` and all models use the same load
......
......@@ -3,6 +3,37 @@
require 'spec_helper'
describe Gitlab::Database::LoadBalancing do
describe '.proxy' do
context 'when configured' do
before do
allow(ActiveRecord::Base.singleton_class).to receive(:prepend)
subject.configure_proxy
end
after do
subject.configure_proxy(nil)
end
it 'returns the connection proxy' do
expect(subject.proxy).to be_an_instance_of(subject::ConnectionProxy)
end
end
context 'when not configured' do
it 'returns nil' do
expect(subject.proxy).to be_nil
end
it 'tracks an error to sentry' do
expect(Gitlab::ErrorTracking).to receive(:track_exception).with(
an_instance_of(subject::ProxyNotConfiguredError)
)
subject.proxy
end
end
end
describe '.configuration' do
it 'returns a Hash' do
config = { 'hosts' => %w(foo) }
......@@ -176,14 +207,16 @@ describe Gitlab::Database::LoadBalancing do
describe '.configure_proxy' do
after do
described_class.proxy = nil
described_class.configure_proxy(nil)
end
it 'configures the connection proxy' do
expect(ActiveRecord::Base.singleton_class).to receive(:prepend)
.with(Gitlab::Database::LoadBalancing::ActiveRecordProxy)
allow(ActiveRecord::Base.singleton_class).to receive(:prepend)
described_class.configure_proxy
expect(ActiveRecord::Base.singleton_class).to have_received(:prepend)
.with(Gitlab::Database::LoadBalancing::ActiveRecordProxy)
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