Skip to content
Snippets Groups Projects
Commit 03b1bcbb authored by Drew Blessing's avatar Drew Blessing
Browse files

Truncate tree to max 1,000 items and display notice to users

Rendering ten thousands of tree items consumes a lot of server
time and can cause timeouts in extreme cases. Realistically,
displaying more than 1,000 files is probably not useful so
truncate and show the user a notice instead. 'Find files' can be
used to locate specific files beyond the 1,000 limit.
parent a4072db0
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -125,7 +125,7 @@
color: $white-normal;
}
 
&:hover {
&:hover:not(.tree-truncated-warning) {
td {
background-color: $row-hover;
border-top: 1px solid $row-hover-border;
Loading
Loading
@@ -198,6 +198,11 @@
}
}
 
.tree-truncated-warning {
color: $orange-600;
background-color: $orange-100;
}
.tree-time-ago {
min-width: 135px;
color: $gl-text-color-secondary;
Loading
Loading
module TreeHelper
FILE_LIMIT = 1_000
# Sorts a repository's tree so that folders are before files and renders
# their corresponding partials
#
# contents - A Grit::Tree object for the current tree
# tree - A `Tree` object for the current tree
def render_tree(tree)
# Sort submodules and folders together by name ahead of files
folders, files, submodules = tree.trees, tree.blobs, tree.submodules
tree = ""
tree = ''
items = (folders + submodules).sort_by(&:name) + files
tree << render(partial: "projects/tree/tree_row", collection: items) if items.present?
if items.size > FILE_LIMIT
tree << render(partial: 'projects/tree/truncated_notice_tree_row',
locals: { limit: FILE_LIMIT, total: items.size })
items = items.take(FILE_LIMIT)
end
tree << render(partial: 'projects/tree/tree_row', collection: items) if items.present?
tree.html_safe
end
 
Loading
Loading
%tr.tree-truncated-warning
%td{ colspan: '3' }
= icon('exclamation-triangle fw')
%span
Too many items to show. To preserve performance only
%strong #{number_with_delimiter(limit)} of #{number_with_delimiter(total)}
items are displayed.
---
title: Truncate tree to max 1,000 items and display notice to users
merge_request:
author:
type: performance
require 'spec_helper'
 
describe TreeHelper do
let(:project) { create(:project, :repository) }
let(:repository) { project.repository }
let(:sha) { 'ce369011c189f62c815f5971d096b26759bab0d1' }
describe '.render_tree' do
before do
@id = sha
@project = project
end
it 'displays all entries without a warning' do
tree = repository.tree(sha, 'files')
html = render_tree(tree)
expect(html).not_to have_selector('.tree-truncated-warning')
end
it 'truncates entries and adds a warning' do
stub_const('TreeHelper::FILE_LIMIT', 1)
tree = repository.tree(sha, 'files')
html = render_tree(tree)
expect(html).to have_selector('.tree-truncated-warning', count: 1)
expect(html).to have_selector('.tree-item-file-name', count: 1)
end
end
describe 'flatten_tree' do
let(:project) { create(:project, :repository) }
let(:repository) { project.repository }
let(:sha) { 'ce369011c189f62c815f5971d096b26759bab0d1' }
let(:tree) { repository.tree(sha, 'files') }
let(:root_path) { 'files' }
let(:tree_item) { tree.entries.find { |entry| entry.path == path } }
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment