Cache & flush tag/branch counts
The methods used for this are Repository#tag_count and Repository#branch_count which cache their output in Redis as well as memoizing it in an instance variable. Both methods have a corresponding methods/hooks to flush the caches at the right time.
This commit is contained in:
parent
149a52b10f
commit
cb5a5ba095
6 changed files with 104 additions and 10 deletions
|
@ -160,7 +160,7 @@ class Repository
|
|||
end
|
||||
|
||||
def rm_tag(tag_name)
|
||||
expire_tags_cache
|
||||
before_remove_tag
|
||||
|
||||
gitlab_shell.rm_tag(path_with_namespace, tag_name)
|
||||
end
|
||||
|
@ -183,6 +183,14 @@ class Repository
|
|||
end
|
||||
end
|
||||
|
||||
def branch_count
|
||||
@branch_count ||= cache.fetch(:branch_count) { raw_repository.branch_count }
|
||||
end
|
||||
|
||||
def tag_count
|
||||
@tag_count ||= cache.fetch(:tag_count) { raw_repository.rugged.tags.count }
|
||||
end
|
||||
|
||||
# Return repo size in megabytes
|
||||
# Cached in redis
|
||||
def size
|
||||
|
@ -278,6 +286,16 @@ class Repository
|
|||
@has_visible_content = nil
|
||||
end
|
||||
|
||||
def expire_branch_count_cache
|
||||
cache.expire(:branch_count)
|
||||
@branch_count = nil
|
||||
end
|
||||
|
||||
def expire_tag_count_cache
|
||||
cache.expire(:tag_count)
|
||||
@tag_count = nil
|
||||
end
|
||||
|
||||
def rebuild_cache
|
||||
cache_keys.each do |key|
|
||||
cache.expire(key)
|
||||
|
@ -313,9 +331,16 @@ class Repository
|
|||
expire_root_ref_cache
|
||||
end
|
||||
|
||||
# Runs code before creating a new tag.
|
||||
def before_create_tag
|
||||
# Runs code before pushing (= creating or removing) a tag.
|
||||
def before_push_tag
|
||||
expire_cache
|
||||
expire_tag_count_cache
|
||||
end
|
||||
|
||||
# Runs code before removing a tag.
|
||||
def before_remove_tag
|
||||
expire_tags_cache
|
||||
expire_tag_count_cache
|
||||
end
|
||||
|
||||
# Runs code after a repository has been forked/imported.
|
||||
|
@ -331,11 +356,13 @@ class Repository
|
|||
# Runs code after a new branch has been created.
|
||||
def after_create_branch
|
||||
expire_has_visible_content_cache
|
||||
expire_branch_count_cache
|
||||
end
|
||||
|
||||
# Runs code after an existing branch has been removed.
|
||||
def after_remove_branch
|
||||
expire_has_visible_content_cache
|
||||
expire_branch_count_cache
|
||||
end
|
||||
|
||||
def method_missing(m, *args, &block)
|
||||
|
|
|
@ -2,7 +2,7 @@ class GitTagPushService
|
|||
attr_accessor :project, :user, :push_data
|
||||
|
||||
def execute(project, user, oldrev, newrev, ref)
|
||||
project.repository.before_create_tag
|
||||
project.repository.before_push_tag
|
||||
|
||||
@project, @user = project, user
|
||||
@push_data = build_push_data(oldrev, newrev, ref)
|
||||
|
|
|
@ -1 +1 @@
|
|||
$('.js-totalbranch-count').html("#{@repository.branches.size}")
|
||||
$('.js-totalbranch-count').html("#{@repository.branch_count}")
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
= nav_link(html_options: {class: branches_tab_class}) do
|
||||
= link_to namespace_project_branches_path(@project.namespace, @project) do
|
||||
Branches
|
||||
%span.badge.js-totalbranch-count= @repository.branches.size
|
||||
%span.badge.js-totalbranch-count= @repository.branch_count
|
||||
|
||||
= nav_link(controller: [:tags, :releases]) do
|
||||
= link_to namespace_project_tags_path(@project.namespace, @project) do
|
||||
Tags
|
||||
%span.badge.js-totaltags-count= @repository.tags.length
|
||||
%span.badge.js-totaltags-count= @repository.tag_count
|
||||
|
|
|
@ -405,7 +405,7 @@ describe Repository, models: true do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#expire_branch_ache' do
|
||||
describe '#expire_branch_cache' do
|
||||
# This method is private but we need it for testing purposes. Sadly there's
|
||||
# no other proper way of testing caching operations.
|
||||
let(:cache) { repository.send(:cache) }
|
||||
|
@ -556,11 +556,12 @@ describe Repository, models: true do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#before_create_tag' do
|
||||
describe '#before_push_tag' do
|
||||
it 'flushes the cache' do
|
||||
expect(repository).to receive(:expire_cache)
|
||||
expect(repository).to receive(:expire_tag_count_cache)
|
||||
|
||||
repository.before_create_tag
|
||||
repository.before_push_tag
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -607,4 +608,44 @@ describe Repository, models: true do
|
|||
expect(repository.main_language).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe '#before_remove_tag' do
|
||||
it 'flushes the tag cache' do
|
||||
expect(repository).to receive(:expire_tag_count_cache)
|
||||
|
||||
repository.before_remove_tag
|
||||
end
|
||||
end
|
||||
|
||||
describe '#branch_count' do
|
||||
it 'returns the number of branches' do
|
||||
expect(repository.branch_count).to be_an_instance_of(Fixnum)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#tag_count' do
|
||||
it 'returns the number of tags' do
|
||||
expect(repository.tag_count).to be_an_instance_of(Fixnum)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#expire_branch_count_cache' do
|
||||
let(:cache) { repository.send(:cache) }
|
||||
|
||||
it 'expires the cache' do
|
||||
expect(cache).to receive(:expire).with(:branch_count)
|
||||
|
||||
repository.expire_branch_count_cache
|
||||
end
|
||||
end
|
||||
|
||||
describe '#expire_tag_count_cache' do
|
||||
let(:cache) { repository.send(:cache) }
|
||||
|
||||
it 'expires the cache' do
|
||||
expect(cache).to receive(:expire).with(:tag_count)
|
||||
|
||||
repository.expire_tag_count_cache
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
26
spec/services/delete_tag_service_spec.rb
Normal file
26
spec/services/delete_tag_service_spec.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe DeleteTagService, services: true do
|
||||
let(:project) { create(:project) }
|
||||
let(:repository) { project.repository }
|
||||
let(:user) { create(:user) }
|
||||
let(:service) { described_class.new(project, user) }
|
||||
|
||||
let(:tag) { double(:tag, name: '8.5', target: 'abc123') }
|
||||
|
||||
describe '#execute' do
|
||||
before do
|
||||
allow(repository).to receive(:find_tag).and_return(tag)
|
||||
end
|
||||
|
||||
it 'removes the tag' do
|
||||
expect_any_instance_of(Gitlab::Shell).to receive(:rm_tag).
|
||||
and_return(true)
|
||||
|
||||
expect(repository).to receive(:before_remove_tag)
|
||||
expect(service).to receive(:success)
|
||||
|
||||
service.execute('8.5')
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue