Commit abe8cbe9 authored by Zeger-Jan van de Weg's avatar Zeger-Jan van de Weg

Load repository language from the DB if detected

The repository charts page used to detect the repository language for
each request that was made to the page. Given the detection is an
expensive operation and the same data is stored in the database the
database is now serving the request.

The same goes for an API endpoint that serves the languages.

When a repository is empty or non-existent the languages will always be
empty. And the language detection RPC isn't requested.

Closes: https://gitlab.com/gitlab-org/gitlab-ce/issues/47390
parent 48d31abc
...@@ -45,7 +45,14 @@ class Projects::GraphsController < Projects::ApplicationController ...@@ -45,7 +45,14 @@ class Projects::GraphsController < Projects::ApplicationController
end end
def get_languages def get_languages
@languages = @project.repository.languages @languages =
if @project.repository_languages.present?
@project.repository_languages.map do |lang|
{ value: lang.share, label: lang.name, color: lang.color, highlight: lang.color }
end
else
@project.repository.languages
end
end end
def fetch_graph def fetch_graph
......
---
title: Load repository language from the database if detected before
merge_request: 25518
author:
type: performance
...@@ -386,7 +386,11 @@ module API ...@@ -386,7 +386,11 @@ module API
desc 'Get languages in project repository' desc 'Get languages in project repository'
get ':id/languages' do get ':id/languages' do
user_project.repository.languages.map { |language| language.values_at(:label, :value) }.to_h if user_project.repository_languages.present?
user_project.repository_languages.map { |l| [l.name, l.share] }.to_h
else
user_project.repository.languages.map { |language| language.values_at(:label, :value) }.to_h
end
end end
desc 'Remove a project' desc 'Remove a project'
......
...@@ -24,4 +24,20 @@ describe Projects::GraphsController do ...@@ -24,4 +24,20 @@ describe Projects::GraphsController do
expect(response).to redirect_to action: :charts expect(response).to redirect_to action: :charts
end end
end end
describe 'charts' do
context 'when languages were previously detected' do
let!(:repository_language) { create(:repository_language, project: project) }
it 'sets the languages properly' do
get(:charts, params: { namespace_id: project.namespace.path, project_id: project.path, id: 'master' })
expect(assigns[:languages]).to eq(
[value: repository_language.share,
label: repository_language.name,
color: repository_language.color,
highlight: repository_language.color])
end
end
end
end end
...@@ -4,6 +4,15 @@ require 'spec_helper' ...@@ -4,6 +4,15 @@ require 'spec_helper'
shared_examples 'languages and percentages JSON response' do shared_examples 'languages and percentages JSON response' do
let(:expected_languages) { project.repository.languages.map { |language| language.values_at(:label, :value)}.to_h } let(:expected_languages) { project.repository.languages.map { |language| language.values_at(:label, :value)}.to_h }
before do
allow(project.repository).to receive(:languages).and_return(
[{ value: 66.69, label: "Ruby", color: "#701516", highlight: "#701516" },
{ value: 22.98, label: "JavaScript", color: "#f1e05a", highlight: "#f1e05a" },
{ value: 7.91, label: "HTML", color: "#e34c26", highlight: "#e34c26" },
{ value: 2.42, label: "CoffeeScript", color: "#244776", highlight: "#244776" }]
)
end
it 'returns expected language values' do it 'returns expected language values' do
get api("/projects/#{project.id}/languages", user) get api("/projects/#{project.id}/languages", user)
...@@ -11,6 +20,23 @@ shared_examples 'languages and percentages JSON response' do ...@@ -11,6 +20,23 @@ shared_examples 'languages and percentages JSON response' do
expect(json_response).to eq(expected_languages) expect(json_response).to eq(expected_languages)
expect(json_response.count).to be > 1 expect(json_response.count).to be > 1
end end
context 'when the languages were detected before' do
before do
Projects::DetectRepositoryLanguagesService.new(project, project.owner).execute
end
it 'returns the detection from the database' do
# Allow this to happen once, so the expected languages can be determined
expect(project.repository).to receive(:languages).once
get api("/projects/#{project.id}/languages", user)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to eq(expected_languages)
expect(json_response.count).to be > 1
end
end
end end
describe API::Projects do describe API::Projects do
......
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