Commit cb8b0f2c authored by Ahmad Sherif's avatar Ahmad Sherif

Use a connection pool for DB probes

parent d8f253a0
Pipeline #67826 passed with stage
in 33 seconds
......@@ -2,6 +2,7 @@ PATH
remote: .
specs:
gitlab-monitor (2.0.0)
connection_pool (~> 2.2.1)
pg (~> 0.18.4)
quantile (~> 0.2.0)
redis-namespace (~> 1.5.2)
......@@ -13,7 +14,7 @@ GEM
specs:
ast (2.3.0)
concurrent-ruby (1.0.5)
connection_pool (2.2.0)
connection_pool (2.2.1)
diff-lcs (1.2.5)
parser (2.3.1.2)
ast (~> 2.2)
......
......@@ -25,6 +25,7 @@ Gem::Specification.new do |s|
s.add_runtime_dependency "quantile", "~> 0.2.0"
s.add_runtime_dependency "sidekiq", "~> 4.2"
s.add_runtime_dependency "redis-namespace", "~> 1.5.2"
s.add_runtime_dependency "connection_pool", "~> 2.2.1"
s.add_development_dependency "rspec", "~> 3.3"
end
require "pg"
require "connection_pool"
module GitLab
module Monitor
......@@ -7,6 +8,14 @@ module GitLab
#
# It takes a connection string (e.g. "dbname=test port=5432")
class Base
def self.connection_pool
@connection_pool ||= Hash.new do |h, connection_string|
h[connection_string] = ConnectionPool.new(size: 3, timeout: 5) do
PG.connect(connection_string)
end
end
end
def initialize(args)
@connection_string = args[:connection_string]
end
......@@ -15,16 +24,8 @@ module GitLab
fail NotImplemented
end
def connected?
!connection.nil?
end
private
def connection
@connection ||= PG.connect(@connection_string)
rescue PG::ConnectionBad # rubocop:disable Lint/HandleExceptions
# Do nothing, we could be on the slave machine
def connection_pool
self.class.connection_pool[@connection_string]
end
end
end
......
......@@ -178,7 +178,9 @@ module GitLab
end
def stale_builds
connection.exec(STALE_BUILDS_QUERY)[0]["count"].to_i
connection_pool.with do |conn|
conn.exec(STALE_BUILDS_QUERY)[0]["count"].to_i
end
rescue PG::UndefinedTable, PG::UndefinedColumn
0
end
......@@ -219,16 +221,20 @@ module GitLab
end
def exec_query_with_custom_random_page_cost(query)
connection.transaction do |conn|
conn.exec(SET_RANDOM_PAGE_COST)
conn.exec(query)
connection_pool.with do |conn|
conn.transaction do |trans|
trans.exec(SET_RANDOM_PAGE_COST)
trans.exec(query)
end
end
end
def mirror_column?
@mirror_column ||=
begin
connection.exec(MIRROR_COLUMN_QUERY)[0]["exists"] == "t"
connection_pool.with do |conn|
conn.exec(MIRROR_COLUMN_QUERY)[0]["exists"] == "t"
end
rescue PG::UndefinedColumn
false
end
......@@ -243,8 +249,6 @@ module GitLab
end
def probe_db
return self unless @collector.connected?
@results = @collector.run
ci_builds_metrics(@results[:pending_builds], "ci_pending_builds")
......@@ -252,6 +256,8 @@ module GitLab
ci_stale_builds_metrics
metrics_per_runner
self
rescue PG::ConnectionBad
self
end
......
......@@ -30,7 +30,9 @@ module GitLab
private
def execute(query)
connection.exec(construct_query(query))[0]["count"]
connection_pool.with do |conn|
conn.exec(construct_query(query))[0]["count"]
end
rescue PG::UndefinedTable, PG::UndefinedColumn
0
end
......@@ -52,13 +54,13 @@ module GitLab
end
def probe_db
return self unless @collector.connected?
results = @collector.run
results.each do |key, value|
@metrics.add("gitlab_database_rows", value.to_i, query_name: key.to_s)
end
self
rescue PG::ConnectionBad
self
end
......
......@@ -15,8 +15,10 @@ module GitLab
SQL
def run
connection.exec(QUERY).each.with_object({}) do |row, stats|
stats[row.delete("relname")] = row
connection_pool.with do |conn|
conn.exec(QUERY).each.with_object({}) do |row, stats|
stats[row.delete("relname")] = row
end
end
end
end
......@@ -29,8 +31,6 @@ module GitLab
end
def probe_db
return self unless @collector.connected?
result = @collector.run
result.each do |table_name, tuple_stats|
......@@ -39,6 +39,8 @@ module GitLab
end
end
self
rescue PG::ConnectionBad
self
end
......
......@@ -10,6 +10,7 @@ describe GitLab::Monitor::Database do
let(:per_runner_query_ee) { "SELECT ALL RUNNING PER RUNNER EE" }
let(:per_runner_query_ce) { "SELECT ALL RUNNING PER RUNNER CE" }
let(:mirror_column_query) { "SELECT DOES MIRROR COLUMN EXISTS" }
let(:connection_pool) { double("connection pool") }
let(:connection) { double("connection") }
def stub_ee
......@@ -63,7 +64,8 @@ describe GitLab::Monitor::Database do
stub_const("GitLab::Monitor::Database::CiBuildsCollector::PER_RUNNER_QUERY_CE", per_runner_query_ce)
stub_const("GitLab::Monitor::Database::CiBuildsCollector::MIRROR_COLUMN_QUERY", mirror_column_query)
allow_any_instance_of(GitLab::Monitor::Database::CiBuildsCollector).to receive(:connection).and_return(connection)
allow_any_instance_of(GitLab::Monitor::Database::CiBuildsCollector).to receive(:connection_pool).and_return(connection_pool)
allow(connection_pool).to receive(:with).and_yield(connection)
allow(connection).to receive(:transaction).and_yield(connection)
allow(connection).to receive(:exec).with(set_random_page_cost_query)
......
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