diff options
author | Zeger-Jan van de Weg <git@zjvandeweg.nl> | 2019-02-25 10:57:34 +0300 |
---|---|---|
committer | Zeger-Jan van de Weg <git@zjvandeweg.nl> | 2019-02-25 17:15:16 +0300 |
commit | abe8cbe90b06f4355b6a783eb22bf46154569ec5 (patch) | |
tree | 2689f8f59c74d811b1a67d5da36c15d06c84b0cd | |
parent | 48d31abc97528a36614b545f0b61fa14053ce4a8 (diff) |
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
-rw-r--r-- | app/controllers/projects/graphs_controller.rb | 9 | ||||
-rw-r--r-- | changelogs/unreleased/zj-load-languages-from-database.yml | 5 | ||||
-rw-r--r-- | lib/api/projects.rb | 6 | ||||
-rw-r--r-- | spec/controllers/projects/graphs_controller_spec.rb | 16 | ||||
-rw-r--r-- | spec/requests/api/projects_spec.rb | 26 |
5 files changed, 60 insertions, 2 deletions
diff --git a/app/controllers/projects/graphs_controller.rb b/app/controllers/projects/graphs_controller.rb index 925b6ed9bfd..c80fce513f6 100644 --- a/app/controllers/projects/graphs_controller.rb +++ b/app/controllers/projects/graphs_controller.rb @@ -45,7 +45,14 @@ class Projects::GraphsController < Projects::ApplicationController end 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 def fetch_graph diff --git a/changelogs/unreleased/zj-load-languages-from-database.yml b/changelogs/unreleased/zj-load-languages-from-database.yml new file mode 100644 index 00000000000..1688829b42c --- /dev/null +++ b/changelogs/unreleased/zj-load-languages-from-database.yml @@ -0,0 +1,5 @@ +--- +title: Load repository language from the database if detected before +merge_request: 25518 +author: +type: performance diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 6a93ef9f3ad..36ee36fbe60 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -386,7 +386,11 @@ module API desc 'Get languages in project repository' 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 desc 'Remove a project' diff --git a/spec/controllers/projects/graphs_controller_spec.rb b/spec/controllers/projects/graphs_controller_spec.rb index 73fb7307e11..8decd8f1382 100644 --- a/spec/controllers/projects/graphs_controller_spec.rb +++ b/spec/controllers/projects/graphs_controller_spec.rb @@ -24,4 +24,20 @@ describe Projects::GraphsController do expect(response).to redirect_to action: :charts 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 diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index cfa7a1a31a3..73b4ccfb7b3 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -4,6 +4,15 @@ require 'spec_helper' shared_examples 'languages and percentages JSON response' do 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 get api("/projects/#{project.id}/languages", user) @@ -11,6 +20,23 @@ shared_examples 'languages and percentages JSON response' do expect(json_response).to eq(expected_languages) expect(json_response.count).to be > 1 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 describe API::Projects do |