diff --git a/app/models/repository.rb b/app/models/repository.rb index f6400f7aff1..4e45a6723b8 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -30,7 +30,7 @@ class Repository commit = Gitlab::Git::Commit.find(raw_repository, id) commit = Commit.new(commit) if commit commit - rescue Rugged::OdbError => ex + rescue Rugged::OdbError nil end @@ -61,25 +61,25 @@ class Repository end def add_branch(branch_name, ref) - Rails.cache.delete(cache_key(:branch_names)) + cache.expire(:branch_names) gitlab_shell.add_branch(path_with_namespace, branch_name, ref) end def add_tag(tag_name, ref, message = nil) - Rails.cache.delete(cache_key(:tag_names)) + cache.expire(:tag_names) gitlab_shell.add_tag(path_with_namespace, tag_name, ref, message) end def rm_branch(branch_name) - Rails.cache.delete(cache_key(:branch_names)) + cache.expire(:branch_names) gitlab_shell.rm_branch(path_with_namespace, branch_name) end def rm_tag(tag_name) - Rails.cache.delete(cache_key(:tag_names)) + cache.expire(:tag_names) gitlab_shell.rm_tag(path_with_namespace, tag_name) end @@ -97,19 +97,15 @@ class Repository end def branch_names - Rails.cache.fetch(cache_key(:branch_names)) do - raw_repository.branch_names - end + cache.fetch(:branch_names) { raw_repository.branch_names } end def tag_names - Rails.cache.fetch(cache_key(:tag_names)) do - raw_repository.tag_names - end + cache.fetch(:tag_names) { raw_repository.tag_names } end def commit_count - Rails.cache.fetch(cache_key(:commit_count)) do + cache.fetch(:commit_count) do begin raw_repository.commit_count(self.root_ref) rescue @@ -121,26 +117,19 @@ class Repository # Return repo size in megabytes # Cached in redis def size - Rails.cache.fetch(cache_key(:size)) do - raw_repository.size - end + cache.fetch(:size) { raw_repository.size } end def expire_cache - Rails.cache.delete(cache_key(:size)) - Rails.cache.delete(cache_key(:branch_names)) - Rails.cache.delete(cache_key(:tag_names)) - Rails.cache.delete(cache_key(:commit_count)) - Rails.cache.delete(cache_key(:graph_log)) - Rails.cache.delete(cache_key(:readme)) - Rails.cache.delete(cache_key(:version)) - Rails.cache.delete(cache_key(:contribution_guide)) + %i(size branch_names tag_names commit_count graph_log + readme version contribution_guide).each do |key| + cache.expire(key) + end end def graph_log - Rails.cache.fetch(cache_key(:graph_log)) do - commits = raw_repository.log(limit: 6000, - skip_merges: true, + cache.fetch(:graph_log) do + commits = raw_repository.log(limit: 6000, skip_merges: true, ref: root_ref) commits.map do |rugged_commit| @@ -176,10 +165,6 @@ class Repository end end - def cache_key(type) - "#{type}:#{path_with_namespace}" - end - def method_missing(m, *args, &block) raw_repository.send(m, *args, &block) end @@ -199,13 +184,11 @@ class Repository end def readme - Rails.cache.fetch(cache_key(:readme)) do - tree(:head).readme - end + cache.fetch(:readme) { tree(:head).readme } end def version - Rails.cache.fetch(cache_key(:version)) do + cache.fetch(:version) do tree(:head).blobs.find do |file| file.name.downcase == 'version' end @@ -213,9 +196,7 @@ class Repository end def contribution_guide - Rails.cache.fetch(cache_key(:contribution_guide)) do - tree(:head).contribution_guide - end + cache.fetch(:contribution_guide) { tree(:head).contribution_guide } end def head_commit @@ -351,4 +332,10 @@ class Repository [] end end + + private + + def cache + @cache ||= RepositoryCache.new(path_with_namespace) + end end diff --git a/lib/repository_cache.rb b/lib/repository_cache.rb new file mode 100644 index 00000000000..0d52f50be91 --- /dev/null +++ b/lib/repository_cache.rb @@ -0,0 +1,25 @@ +# Interface to the Redis-backed cache store used by the Repository model +class RepositoryCache + attr_reader :namespace + + def initialize(namespace, backend = Rails.cache) + @namespace = namespace + @backend = backend + end + + def cache_key(type) + "#{type}:#{namespace}" + end + + def expire(key) + backend.delete(cache_key(key)) + end + + def fetch(key, &block) + backend.fetch(cache_key(key), &block) + end + + private + + attr_reader :backend +end diff --git a/spec/lib/repository_cache_spec.rb b/spec/lib/repository_cache_spec.rb new file mode 100644 index 00000000000..af399f3a731 --- /dev/null +++ b/spec/lib/repository_cache_spec.rb @@ -0,0 +1,34 @@ +require 'rspec' +require_relative '../../lib/repository_cache' + +describe RepositoryCache do + let(:backend) { double('backend').as_null_object } + let(:cache) { RepositoryCache.new('example', backend) } + + describe '#cache_key' do + it 'includes the namespace' do + expect(cache.cache_key(:foo)).to eq 'foo:example' + end + end + + describe '#expire' do + it 'expires the given key from the cache' do + cache.expire(:foo) + expect(backend).to have_received(:delete).with('foo:example') + end + end + + describe '#fetch' do + it 'fetches the given key from the cache' do + cache.fetch(:bar) + expect(backend).to have_received(:fetch).with('bar:example') + end + + it 'accepts a block' do + p = -> {} + + cache.fetch(:baz, &p) + expect(backend).to have_received(:fetch).with('baz:example', &p) + end + end +end