Commit ae21f6c5 authored by Ahmad Sherif's avatar Ahmad Sherif
Browse files

Merge branch 'improvement/split-and-refactor-ci-builds-running-querying' into 'master'

Split and refactor querying for total CI builds

This MR:
- splits metrics for builds in `running` state just like for the `pending` state (so projects are distinguished by`shared_runners_enabled` value),
- refactors querying for metrics about total builds count, so the data is collected with one query instead of two.

/fyi @ayufan

See merge request !30
parents 0c58eb64 a12948e6
......@@ -3,18 +3,15 @@ module GitLab
module Database
# A helper class to collect blocked queries
class CiBuildsCollector < Base
RUNNING_BUILDS_QUERY =
"SELECT COUNT(*) AS count FROM ci_builds AS b WHERE b.type = 'Ci::Build' AND b.status = 'running'".freeze
TOTAL_BUILDS_QUERY =
"SELECT p.shared_runners_enabled, b.status, COUNT(*) AS count FROM ci_builds AS b JOIN projects AS p " \
"ON p.id = b.gl_project_id WHERE b.type = 'Ci::Build' AND b.status IN ('pending', 'running') " \
"GROUP BY p.shared_runners_enabled, b.status".freeze
NOT_UPDATED_RUNNING_BUILDS_QUERY =
"SELECT COUNT(*) AS count FROM ci_builds AS b WHERE b.type = 'Ci::Build' AND b.status = 'running' " \
"AND b.updated_at < NOW() - INTERVAL '1 hour'".freeze
PENDING_BUILDS_QUERY =
"SELECT p.shared_runners_enabled, COUNT(*) AS count FROM ci_builds AS b JOIN projects AS p " \
"ON p.id = b.gl_project_id WHERE b.type = 'Ci::Build' AND b.status = 'pending' " \
"GROUP BY p.shared_runners_enabled".freeze
RUNNING_PER_SHARED_RUNNER_QUERY =
"SELECT b.runner_id, COUNT(*) AS count " \
"FROM ci_builds AS b " \
......@@ -31,8 +28,11 @@ module GitLab
def run
results = {}
results[:all] = get_general(RUNNING_BUILDS_QUERY)
results[:pending] = get_shared_enabled_grouped(PENDING_BUILDS_QUERY)
total = get_shared_enabled_and_status_grouped(TOTAL_BUILDS_QUERY)
results[:running] = total[:running]
results[:pending] = total[:pending]
results[:not_updated_last_hour] = get_general(NOT_UPDATED_RUNNING_BUILDS_QUERY)
results[:per_runner] = get_per_shared_runner(RUNNING_PER_SHARED_RUNNER_QUERY)
results[:per_runner_mirrors] = get_per_shared_runner(RUNNING_FOR_MIRRORS_PER_SHARED_RUNNER_QUERY)
......@@ -66,16 +66,21 @@ module GitLab
0
end
def get_shared_enabled_grouped(query)
results = { shared_enabled: 0, shared_disabled: 0 }
def get_shared_enabled_and_status_grouped(query)
results = { running: { shared_enabled: 0, shared_disabled: 0 },
pending: { shared_enabled: 0, shared_disabled: 0 } }
connection.exec(query).each do |row|
row["shared_runners_enabled"] = row["shared_runners_enabled"] == "t"
results[:shared_enabled] = row["count"].to_i if row["shared_runners_enabled"]
results[:shared_disabled] = row["count"].to_i unless row["shared_runners_enabled"]
shared_enabled = row["shared_runners_enabled"] == "t"
status = row["status"].to_sym
results[status][:shared_enabled] = row["count"].to_i if shared_enabled
results[status][:shared_disabled] = row["count"].to_i unless shared_enabled
end
results
rescue PG::UndefinedTable, PG::UndefinedColumn
{ shared_enabled: 0, shared_disabled: 0 }
{ running: { shared_enabled: 0, shared_disabled: 0 }, pending: { shared_enabled: 0, shared_disabled: 0 } }
end
def shared_runners_ids
......@@ -114,7 +119,10 @@ module GitLab
private
def metrics_total
@metrics.add("ci_builds_total", @results[:all], status: "running")
@metrics.add("ci_builds_total", @results[:running][:shared_enabled], status: "running",
shared_runners_enabled_projects: 1)
@metrics.add("ci_builds_total", @results[:running][:shared_disabled], status: "running",
shared_runners_enabled_projects: 0)
@metrics.add("ci_builds_total", @results[:pending][:shared_enabled], status: "pending",
shared_runners_enabled_projects: 1)
@metrics.add("ci_builds_total", @results[:pending][:shared_disabled], status: "pending",
......
......@@ -2,18 +2,16 @@ require "spec_helper"
require "gitlab_monitor/database/ci_builds"
describe GitLab::Monitor::Database do
let(:running_builds_query) { "SELECT RUNNING" }
let(:total_builds_query) { "SELECT TOTAL BUILDS" }
let(:not_updated_running_builds_query) { "SELECT NOT UPDATED RUNNING" }
let(:pending_builds_query) { "SELECT PENDING BUILDS" }
let(:per_runner_query) { "SELECT ALL RUNNING PER RUNNER %s" }
let(:mirrors_per_runner_query) { "SELECT MIRRORS RUNNING PER RUNNER %s" }
let(:connection) { double("connection") }
before do
stub_const("GitLab::Monitor::Database::CiBuildsCollector::RUNNING_BUILDS_QUERY", running_builds_query)
stub_const("GitLab::Monitor::Database::CiBuildsCollector::TOTAL_BUILDS_QUERY", total_builds_query)
stub_const("GitLab::Monitor::Database::CiBuildsCollector::NOT_UPDATED_RUNNING_BUILDS_QUERY",
not_updated_running_builds_query)
stub_const("GitLab::Monitor::Database::CiBuildsCollector::PENDING_BUILDS_QUERY", pending_builds_query)
stub_const("GitLab::Monitor::Database::CiBuildsCollector::RUNNING_PER_SHARED_RUNNER_QUERY", per_runner_query)
stub_const("GitLab::Monitor::Database::CiBuildsCollector::RUNNING_FOR_MIRRORS_PER_SHARED_RUNNER_QUERY",
mirrors_per_runner_query)
......@@ -22,11 +20,12 @@ describe GitLab::Monitor::Database do
allow_any_instance_of(GitLab::Monitor::Database::CiBuildsCollector).to receive(:shared_runners_ids)
.and_return([1, 2])
allow(connection).to receive(:exec).with(running_builds_query).and_return([{ "count" => 5 }])
allow(connection).to receive(:exec).with(total_builds_query)
.and_return([{ "shared_runners_enabled" => "f", "status" => "running", "count" => 2 },
{ "shared_runners_enabled" => "t", "status" => "running", "count" => 3 },
{ "shared_runners_enabled" => "f", "status" => "pending", "count" => 2 },
{ "shared_runners_enabled" => "t", "status" => "pending", "count" => 5 }])
allow(connection).to receive(:exec).with(not_updated_running_builds_query).and_return([{ "count" => 2 }])
allow(connection).to receive(:exec).with(pending_builds_query)
.and_return([{ "shared_runners_enabled" => "f", "count" => 2 },
{ "shared_runners_enabled" => "t", "count" => 5 }])
allow(connection).to receive(:exec).with(per_runner_query % "1, 2")
.and_return([{ "runner_id" => 2, "count" => 15 }])
allow(connection).to receive(:exec).with(mirrors_per_runner_query % "1, 2")
......@@ -39,9 +38,9 @@ describe GitLab::Monitor::Database do
it "executes the query" do
expect(collector.run).to eq(per_runner: { 1 => 0, 2 => 15 },
per_runner_mirrors: { 1 => 0, 2 => 10 },
all: 5,
not_updated_last_hour: 2,
pending: { shared_enabled: 5, shared_disabled: 2 })
running: { shared_enabled: 3, shared_disabled: 2 },
pending: { shared_enabled: 5, shared_disabled: 2 },
not_updated_last_hour: 2)
end
end
......@@ -60,7 +59,8 @@ describe GitLab::Monitor::Database do
prober.probe_db
prober.write_to(writer)
expect(writer.string).to match(/ci_builds_total{status="running"} 5/)
expect(writer.string).to match(/ci_builds_total{status="running",shared_runners_enabled_projects="1"} 3/)
expect(writer.string).to match(/ci_builds_total{status="running",shared_runners_enabled_projects="0"} 2/)
expect(writer.string).to match(/ci_builds_total{status="pending",shared_runners_enabled_projects="1"} 5/)
expect(writer.string).to match(/ci_builds_total{status="pending",shared_runners_enabled_projects="0"} 2/)
expect(writer.string).to match(/ci_builds_stale{status="running",when="last_hour"} 2/)
......
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