Commit 91bf332a authored by Igor Drozdov's avatar Igor Drozdov

Cache content_sha256 field for Files API

Changelog: performance
parent a3a0c0ba
...@@ -35,10 +35,9 @@ module API ...@@ -35,10 +35,9 @@ module API
not_found!('Commit') unless @commit not_found!('Commit') unless @commit
@repo = user_project.repository @repo = user_project.repository
@blob = @repo.blob_at(@commit.sha, params[:file_path]) @blob = @repo.blob_at(@commit.sha, params[:file_path], limit: Gitlab::Git::Blob::LFS_POINTER_MAX_SIZE)
not_found!('File') unless @blob not_found!('File') unless @blob
@blob.load_all_data!
end end
def commit_response(attrs) def commit_response(attrs)
...@@ -48,13 +47,21 @@ module API ...@@ -48,13 +47,21 @@ module API
} }
end end
def content_sha
Rails.cache.fetch("blob_content_sha256:#{user_project.full_path}:#{@blob.id}") do
@blob.load_all_data!
Digest::SHA256.hexdigest(@blob.data)
end
end
def blob_data def blob_data
{ {
file_name: @blob.name, file_name: @blob.name,
file_path: @blob.path, file_path: @blob.path,
size: @blob.size, size: @blob.size,
encoding: "base64", encoding: "base64",
content_sha256: Digest::SHA256.hexdigest(@blob.data), content_sha256: content_sha,
ref: params[:ref], ref: params[:ref],
blob_id: @blob.id, blob_id: @blob.id,
commit_id: @commit.id, commit_id: @commit.id,
...@@ -154,6 +161,8 @@ module API ...@@ -154,6 +161,8 @@ module API
get ":id/repository/files/:file_path", requirements: FILE_ENDPOINT_REQUIREMENTS do get ":id/repository/files/:file_path", requirements: FILE_ENDPOINT_REQUIREMENTS do
assign_file_vars! assign_file_vars!
@blob.load_all_data!
data = blob_data data = blob_data
set_http_headers(data) set_http_headers(data)
......
...@@ -95,6 +95,19 @@ RSpec.describe API::Files do ...@@ -95,6 +95,19 @@ RSpec.describe API::Files do
expect(response.headers['X-Gitlab-Content-Sha256']).to eq('c440cd09bae50c4632cc58638ad33c6aa375b6109d811e76a9cc3a613c1e8887') expect(response.headers['X-Gitlab-Content-Sha256']).to eq('c440cd09bae50c4632cc58638ad33c6aa375b6109d811e76a9cc3a613c1e8887')
end end
it 'caches sha256 of the content', :use_clean_rails_redis_caching do
head api(route(file_path), current_user, **options), params: params
expect(Rails.cache.fetch("blob_content_sha256:#{project.full_path}:#{response.headers['X-Gitlab-Blob-Id']}"))
.to eq('c440cd09bae50c4632cc58638ad33c6aa375b6109d811e76a9cc3a613c1e8887')
expect_next_instance_of(Gitlab::Git::Blob) do |instance|
expect(instance).not_to receive(:load_all_data!)
end
head api(route(file_path), current_user, **options), params: params
end
it 'returns file by commit sha' do it 'returns file by commit sha' do
# This file is deleted on HEAD # This file is deleted on HEAD
file_path = "files%2Fjs%2Fcommit%2Ejs%2Ecoffee" file_path = "files%2Fjs%2Fcommit%2Ejs%2Ecoffee"
......
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