Memoize the latest builds of a pipeline

This ensures that if a pipeline is present for the last commit on a
project's homepage we only run 1 query to get the builds, instead of
running 2 queries.

See https://gitlab.com/gitlab-org/gitlab-ce/issues/36878#note_40073339
for more information.
This commit is contained in:
Yorick Peterse 2017-09-12 18:13:07 +02:00
parent 3e999684f9
commit 7219009993
No known key found for this signature in database
GPG Key ID: EDD30D2BEB691AC9
4 changed files with 42 additions and 15 deletions

View File

@ -453,6 +453,10 @@ module Ci
.fabricate!
end
def latest_builds_with_artifacts
@latest_builds_with_artifacts ||= builds.latest.with_artifacts
end
private
def ci_yaml_from_repo

View File

@ -26,18 +26,16 @@
%i.fa.fa-download
%span= _('Download tar')
- if pipeline
- artifacts = pipeline.builds.latest.with_artifacts
- if artifacts.any?
%li.dropdown-header Artifacts
- unless pipeline.latest?
- latest_pipeline = project.pipeline_for(ref)
%li
.unclickable= ci_status_for_statuseable(latest_pipeline)
%li.dropdown-header Previous Artifacts
- artifacts.each do |job|
%li
= link_to latest_succeeded_project_artifacts_path(project, "#{ref}/download", job: job.name), rel: 'nofollow', download: '' do
%i.fa.fa-download
%span
#{ s_('DownloadArtifacts|Download') } '#{job.name}'
- if pipeline && pipeline.latest_builds_with_artifacts.any?
%li.dropdown-header Artifacts
- unless pipeline.latest?
- latest_pipeline = project.pipeline_for(ref)
%li
.unclickable= ci_status_for_statuseable(latest_pipeline)
%li.dropdown-header Previous Artifacts
- pipeline.latest_builds_with_artifacts.each do |job|
%li
= link_to latest_succeeded_project_artifacts_path(project, "#{ref}/download", job: job.name), rel: 'nofollow', download: '' do
%i.fa.fa-download
%span
#{s_('DownloadArtifacts|Download')} '#{job.name}'

View File

@ -0,0 +1,5 @@
---
title: "Memoize the latest builds of a pipeline on a project's homepage"
merge_request:
author:
type: other

View File

@ -1439,4 +1439,24 @@ describe Ci::Pipeline, :mailer do
it_behaves_like 'not sending any notification'
end
end
describe '#latest_builds_with_artifacts' do
let!(:pipeline) { create(:ci_pipeline, :success) }
let!(:build) do
create(:ci_build, :success, :artifacts, pipeline: pipeline)
end
it 'returns the latest builds' do
expect(pipeline.latest_builds_with_artifacts).to eq([build])
end
it 'memoizes the returned relation' do
query_count = ActiveRecord::QueryRecorder
.new { 2.times { pipeline.latest_builds_with_artifacts.to_a } }
.count
expect(query_count).to eq(1)
end
end
end