Commit ea35fd05 authored by Grzegorz Bizon's avatar Grzegorz Bizon

Refactor pipeline preloader to split reponsibilities better

parent 76a7157c
...@@ -24,7 +24,7 @@ class Projects::PipelinesController < Projects::ApplicationController ...@@ -24,7 +24,7 @@ class Projects::PipelinesController < Projects::ApplicationController
@finished_count = limited_pipelines_count(project, 'finished') @finished_count = limited_pipelines_count(project, 'finished')
@pipelines_count = limited_pipelines_count(project) @pipelines_count = limited_pipelines_count(project)
Gitlab::Ci::Pipeline::Preloader.preload(@pipelines) Gitlab::Ci::Pipeline::Preloader.new(@pipelines).preload!
respond_to do |format| respond_to do |format|
format.html format.html
......
...@@ -5,26 +5,46 @@ module Gitlab ...@@ -5,26 +5,46 @@ module Gitlab
module Pipeline module Pipeline
# Class for preloading data associated with pipelines such as commit # Class for preloading data associated with pipelines such as commit
# authors. # authors.
module Preloader class Preloader
def self.preload(pipelines) def initialize(pipelines)
@pipelines = pipelines
end
def preload!
@pipelines.each do |pipeline|
Pipeline::Preloader::Instance.new(pipeline)
.preload_commits
.preload_pipeline_warnings
.preload_stages_warnings
end
end
class Instance
def initialize(pipeline)
@pipeline = pipeline
end
def preload_commits
# This ensures that all the pipeline commits are eager loaded before we # This ensures that all the pipeline commits are eager loaded before we
# start using them. # start using them.
pipelines.each(&:commit) #
# This also preloads the author of every commit. We're using "lazy_author"
pipelines.each do |pipeline|
# This preloads the author of every commit. We're using "lazy_author"
# here since "author" immediately loads the data on the first call. # here since "author" immediately loads the data on the first call.
pipeline.commit.try(:lazy_author) tap { @pipeline.commit.try(:lazy_author) }
end
def preload_pipeline_warnings
# This preloads the number of warnings for every pipeline, ensuring # This preloads the number of warnings for every pipeline, ensuring
# that Ci::Pipeline#has_warnings? doesn't execute any additional # that Ci::Pipeline#has_warnings? doesn't execute any additional
# queries. # queries.
pipeline.number_of_warnings tap { @pipeline.number_of_warnings }
end
def preload_stages_warnings
# This preloads the number of warnings for every stage, ensuring # This preloads the number of warnings for every stage, ensuring
# that Ci::Stage#has_warnings? doesn't execute any additional # that Ci::Stage#has_warnings? doesn't execute any additional
# queries. # queries.
pipeline.stages.each { |stage| stage.number_of_warnings } tap { @pipeline.stages.each { |stage| stage.number_of_warnings } }
end end
end end
end end
......
...@@ -36,8 +36,6 @@ describe Projects::PipelinesController do ...@@ -36,8 +36,6 @@ describe Projects::PipelinesController do
expect(json_response['count']['running']).to eq '1' expect(json_response['count']['running']).to eq '1'
expect(json_response['count']['pending']).to eq '1' expect(json_response['count']['pending']).to eq '1'
expect(json_response['count']['finished']).to eq '2' expect(json_response['count']['finished']).to eq '2'
puts queries.log
puts "Queries count: #{queries.count}"
expect(queries.count).to be < 32 expect(queries.count).to be < 32
end end
......
# frozen_string_literal: true # frozen_string_literal: true
require 'spec_helper' require 'fast_spec_helper'
describe Gitlab::Ci::Pipeline::Preloader do describe Gitlab::Ci::Pipeline::Preloader do
describe '.preload' do let(:stage) { double(:stage) }
it 'preloads the author of every pipeline commit' do let(:commit) { double(:commit) }
commit = double(:commit)
pipeline = double(:pipeline, commit: commit)
expect(commit) let(:pipeline) do
.to receive(:lazy_author) double(:pipeline, commit: commit, stages: [stage])
end
expect(pipeline) describe '#preload!' do
.to receive(:number_of_warnings) it 'preloads commit authors and number of warnings' do
expect(commit).to receive(:lazy_author)
expect(pipeline).to receive(:number_of_warnings)
expect(stage).to receive(:number_of_warnings)
described_class.preload([pipeline]) described_class.new([pipeline]).preload!
end end
end 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