Commit 9449b5eb authored by Alex Pooley's avatar Alex Pooley Committed by Ash McKenzie

Improve performance of public snippets API endpoint

parent 9fbc9e69
---
title: Improve performance of /api/:version/snippets/public API and only return public
personal snippets
merge_request: 20339
author:
type: performance
# frozen_string_literal: true
class AddCreatedAtIndexToSnippets < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_concurrent_index :snippets, :created_at
end
def down
remove_concurrent_index :snippets, :created_at
end
end
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2019_11_18_182722) do ActiveRecord::Schema.define(version: 2019_11_19_023952) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "pg_trgm" enable_extension "pg_trgm"
...@@ -3628,6 +3628,7 @@ ActiveRecord::Schema.define(version: 2019_11_18_182722) do ...@@ -3628,6 +3628,7 @@ ActiveRecord::Schema.define(version: 2019_11_18_182722) do
t.boolean "secret", default: false, null: false t.boolean "secret", default: false, null: false
t.index ["author_id"], name: "index_snippets_on_author_id" t.index ["author_id"], name: "index_snippets_on_author_id"
t.index ["content"], name: "index_snippets_on_content_trigram", opclass: :gin_trgm_ops, using: :gin t.index ["content"], name: "index_snippets_on_content_trigram", opclass: :gin_trgm_ops, using: :gin
t.index ["created_at"], name: "index_snippets_on_created_at"
t.index ["file_name"], name: "index_snippets_on_file_name_trigram", opclass: :gin_trgm_ops, using: :gin t.index ["file_name"], name: "index_snippets_on_file_name_trigram", opclass: :gin_trgm_ops, using: :gin
t.index ["project_id", "visibility_level"], name: "index_snippets_on_project_id_and_visibility_level" t.index ["project_id", "visibility_level"], name: "index_snippets_on_project_id_and_visibility_level"
t.index ["title"], name: "index_snippets_on_title_trigram", opclass: :gin_trgm_ops, using: :gin t.index ["title"], name: "index_snippets_on_title_trigram", opclass: :gin_trgm_ops, using: :gin
......
...@@ -14,7 +14,7 @@ module API ...@@ -14,7 +14,7 @@ module API
end end
def public_snippets def public_snippets
SnippetsFinder.new(current_user, scope: :are_public).execute Snippet.only_personal_snippets.are_public.fresh
end end
def snippets def snippets
...@@ -33,7 +33,7 @@ module API ...@@ -33,7 +33,7 @@ module API
present paginate(snippets_for_current_user), with: Entities::PersonalSnippet present paginate(snippets_for_current_user), with: Entities::PersonalSnippet
end end
desc 'List all public snippets current_user has access to' do desc 'List all public personal snippets current_user has access to' do
detail 'This feature was introduced in GitLab 8.15.' detail 'This feature was introduced in GitLab 8.15.'
success Entities::PersonalSnippet success Entities::PersonalSnippet
end end
......
...@@ -66,6 +66,9 @@ describe API::Snippets do ...@@ -66,6 +66,9 @@ describe API::Snippets do
let!(:public_snippet_other) { create(:personal_snippet, :public, author: other_user) } let!(:public_snippet_other) { create(:personal_snippet, :public, author: other_user) }
let!(:private_snippet_other) { create(:personal_snippet, :private, author: other_user) } let!(:private_snippet_other) { create(:personal_snippet, :private, author: other_user) }
let!(:internal_snippet_other) { create(:personal_snippet, :internal, author: other_user) } let!(:internal_snippet_other) { create(:personal_snippet, :internal, author: other_user) }
let!(:public_snippet_project) { create(:project_snippet, :public, author: user) }
let!(:private_snippet_project) { create(:project_snippet, :private, author: user) }
let!(:internal_snippet_project) { create(:project_snippet, :internal, author: user) }
it 'returns all snippets with public visibility from all users' do it 'returns all snippets with public visibility from all users' do
get api("/snippets/public", user) get api("/snippets/public", user)
...@@ -76,10 +79,10 @@ describe API::Snippets do ...@@ -76,10 +79,10 @@ describe API::Snippets do
expect(json_response.map { |snippet| snippet['id']} ).to contain_exactly( expect(json_response.map { |snippet| snippet['id']} ).to contain_exactly(
public_snippet.id, public_snippet.id,
public_snippet_other.id) public_snippet_other.id)
expect(json_response.map { |snippet| snippet['web_url']} ).to include( expect(json_response.map { |snippet| snippet['web_url']} ).to contain_exactly(
"http://localhost/snippets/#{public_snippet.id}", "http://localhost/snippets/#{public_snippet.id}",
"http://localhost/snippets/#{public_snippet_other.id}") "http://localhost/snippets/#{public_snippet_other.id}")
expect(json_response.map { |snippet| snippet['raw_url']} ).to include( expect(json_response.map { |snippet| snippet['raw_url']} ).to contain_exactly(
"http://localhost/snippets/#{public_snippet.id}/raw", "http://localhost/snippets/#{public_snippet.id}/raw",
"http://localhost/snippets/#{public_snippet_other.id}/raw") "http://localhost/snippets/#{public_snippet_other.id}/raw")
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