Commit 6eec5ba5 authored by Adam Hegyi's avatar Adam Hegyi Committed by Stan Hu

Use upsert for MR metrics

parent 070ae2bc
...@@ -1853,6 +1853,9 @@ class MergeRequest < ApplicationRecord ...@@ -1853,6 +1853,9 @@ class MergeRequest < ApplicationRecord
override :ensure_metrics override :ensure_metrics
def ensure_metrics def ensure_metrics
if Feature.enabled?(:use_upsert_query_for_mr_metrics)
MergeRequest::Metrics.record!(self)
else
# Backward compatibility: some merge request metrics records will not have target_project_id filled in. # Backward compatibility: some merge request metrics records will not have target_project_id filled in.
# In that case the first `safe_find_or_create_by` will return false. # In that case the first `safe_find_or_create_by` will return false.
# The second finder call will be eliminated in https://gitlab.com/gitlab-org/gitlab/-/issues/233507 # The second finder call will be eliminated in https://gitlab.com/gitlab-org/gitlab/-/issues/233507
...@@ -1874,6 +1877,7 @@ class MergeRequest < ApplicationRecord ...@@ -1874,6 +1877,7 @@ class MergeRequest < ApplicationRecord
association(:metrics).target = metrics_record association(:metrics).target = metrics_record
end end
end end
end
def allows_reviewers? def allows_reviewers?
true true
......
...@@ -14,10 +14,25 @@ class MergeRequest::Metrics < ApplicationRecord ...@@ -14,10 +14,25 @@ class MergeRequest::Metrics < ApplicationRecord
scope :with_valid_time_to_merge, -> { where(arel_table[:merged_at].gt(arel_table[:created_at])) } scope :with_valid_time_to_merge, -> { where(arel_table[:merged_at].gt(arel_table[:created_at])) }
scope :by_target_project, ->(project) { where(target_project_id: project) } scope :by_target_project, ->(project) { where(target_project_id: project) }
def self.time_to_merge_expression class << self
def time_to_merge_expression
Arel.sql('EXTRACT(epoch FROM SUM(AGE(merge_request_metrics.merged_at, merge_request_metrics.created_at)))') Arel.sql('EXTRACT(epoch FROM SUM(AGE(merge_request_metrics.merged_at, merge_request_metrics.created_at)))')
end end
def record!(mr)
sql = <<~SQL
INSERT INTO #{self.table_name} (merge_request_id, target_project_id, updated_at, created_at)
VALUES (#{mr.id}, #{mr.target_project_id}, NOW(), NOW())
ON CONFLICT (merge_request_id)
DO UPDATE SET
target_project_id = EXCLUDED.target_project_id,
updated_at = NOW()
SQL
connection.execute(sql)
end
end
private private
def ensure_target_project_id def ensure_target_project_id
......
---
name: use_upsert_query_for_mr_metrics
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69240
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339677
milestone: '14.3'
type: development
group: group::optimize
default_enabled: false
...@@ -8,7 +8,9 @@ module Analytics ...@@ -8,7 +8,9 @@ module Analytics
def execute(force: false) def execute(force: false)
merge_requests.each do |mr| merge_requests.each do |mr|
metrics = mr.ensure_metrics mr.ensure_metrics
mr.reset # clear already loaded (nil) metrics association
metrics = mr.metrics
next if !force && metric_already_present?(metrics) next if !force && metric_already_present?(metrics)
......
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