Commit f1bfb5fd authored by Patrick Bajao's avatar Patrick Bajao

Track merge_requests_users usage data

To get the NSM for source code group, we need to track the number
of unique merge requests users. This will be used to determine
how much of MAUs in percentage are using merge requests.
parent fdb3fbba
---
title: Track merge_requests_users usage data
merge_request: 32562
author:
type: changed
......@@ -4,14 +4,15 @@ class AddIndexOnAuthorIdAndCreatedAtToEvents < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
INDEX_NAME = 'index_events_on_author_id_and_created_at'
disable_ddl_transaction!
def up
add_concurrent_index :events, [:author_id, :created_at]
add_concurrent_index :events, [:author_id, :created_at], name: INDEX_NAME
end
def down
remove_concurrent_index :events, [:author_id, :created_at]
remove_concurrent_index :events, INDEX_NAME
end
end
# frozen_string_literal: true
class AddMergeRequestPartialIndexToEvents < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
INDEX_NAME = 'index_events_on_author_id_and_created_at_merge_requests'
def up
add_concurrent_index(
:events,
[:author_id, :created_at],
name: INDEX_NAME,
where: "(target_type = 'MergeRequest')"
)
end
def down
remove_concurrent_index :events, INDEX_NAME
end
end
......@@ -9706,6 +9706,8 @@ CREATE INDEX index_events_on_action ON public.events USING btree (action);
CREATE INDEX index_events_on_author_id_and_created_at ON public.events USING btree (author_id, created_at);
CREATE INDEX index_events_on_author_id_and_created_at_merge_requests ON public.events USING btree (author_id, created_at) WHERE ((target_type)::text = 'MergeRequest'::text);
CREATE INDEX index_events_on_author_id_and_project_id ON public.events USING btree (author_id, project_id);
CREATE INDEX index_events_on_group_id_partial ON public.events USING btree (group_id) WHERE (group_id IS NOT NULL);
......@@ -14036,5 +14038,6 @@ COPY "schema_migrations" (version) FROM STDIN;
20200527151413
20200527152116
20200527152657
20200528123703
\.
......@@ -39,8 +39,8 @@ module EE
override :uncached_data
def uncached_data
time_period = { created_at: 28.days.ago..Time.current }
usage_activity_by_stage_monthly = usage_activity_by_stage(:usage_activity_by_stage_monthly, time_period)
usage_activity_by_stage_monthly = usage_activity_by_stage(:usage_activity_by_stage_monthly, default_time_period)
super
.merge(usage_activity_by_stage)
.merge(usage_activity_by_stage_monthly)
......
......@@ -32,6 +32,7 @@ module Gitlab
.merge(cycle_analytics_usage_data)
.merge(object_store_usage_data)
.merge(recording_ce_finish_data)
.merge(merge_requests_usage_data(default_time_period))
end
def to_json(force_refresh: false)
......@@ -382,6 +383,27 @@ module Gitlab
{} # augmented in EE
end
# rubocop: disable CodeReuse/ActiveRecord
def merge_requests_usage_data(time_period)
query =
Event
.where(target_type: Event::TARGET_TYPES[:merge_request].to_s)
.where(time_period)
merge_request_users = distinct_count(
query,
:author_id,
batch_size: 5_000, # Based on query performance, this is the optimal batch size.
start: User.minimum(:id),
finish: User.maximum(:id)
)
{
merge_requests_users: merge_request_users
}
end
# rubocop: enable CodeReuse/ActiveRecord
def installation_type
if Rails.env.production?
Gitlab::INSTALLATION_TYPE
......@@ -389,6 +411,10 @@ module Gitlab
"gitlab-development-kit"
end
end
def default_time_period
{ created_at: 28.days.ago..Time.current }
end
end
end
end
......
......@@ -49,9 +49,9 @@ module Gitlab
FALLBACK
end
def distinct_count(relation, column = nil, batch: true, start: nil, finish: nil)
def distinct_count(relation, column = nil, batch: true, batch_size: nil, start: nil, finish: nil)
if batch && Feature.enabled?(:usage_ping_batch_counter, default_enabled: true)
Gitlab::Database::BatchCount.batch_distinct_count(relation, column, start: start, finish: finish)
Gitlab::Database::BatchCount.batch_distinct_count(relation, column, batch_size: batch_size, start: start, finish: finish)
else
relation.distinct_count_by(column)
end
......
......@@ -574,4 +574,27 @@ describe Gitlab::UsageData, :aggregate_failures do
it_behaves_like 'usage data execution'
end
describe '#merge_requests_usage_data' do
let(:time_period) { { created_at: 2.days.ago..Time.current } }
let(:merge_request) { create(:merge_request) }
let(:other_user) { create(:user) }
let(:another_user) { create(:user) }
before do
create(:event, target: merge_request, author: merge_request.author, created_at: 1.day.ago)
create(:event, target: merge_request, author: merge_request.author, created_at: 1.hour.ago)
create(:event, target: merge_request, author: merge_request.author, created_at: 3.days.ago)
create(:event, target: merge_request, author: other_user, created_at: 1.day.ago)
create(:event, target: merge_request, author: other_user, created_at: 1.hour.ago)
create(:event, target: merge_request, author: other_user, created_at: 3.days.ago)
create(:event, target: merge_request, author: another_user, created_at: 4.days.ago)
end
it 'returns the distinct count of users using merge requests (via events table) within the specified time period' do
expect(described_class.merge_requests_usage_data(time_period)).to eq(
merge_requests_users: 2
)
end
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