Use project ID in repository cache to prevent stale data from persisting across projects
We have a number of bugs caused by cache keys not being flushed properly during deletion of a project. Add the project ID to ensure this never happens. Closes #20027
This commit is contained in:
parent
8318011034
commit
3618796e15
4 changed files with 15 additions and 10 deletions
|
@ -9,6 +9,9 @@ v 8.11.0 (unreleased)
|
||||||
- Load project invited groups and members eagerly in ProjectTeam#fetch_members
|
- Load project invited groups and members eagerly in ProjectTeam#fetch_members
|
||||||
- Add GitLab Workhorse version to admin dashboard (Katarzyna Kobierska Ula Budziszewska)
|
- Add GitLab Workhorse version to admin dashboard (Katarzyna Kobierska Ula Budziszewska)
|
||||||
|
|
||||||
|
v 8.10.2 (unreleased)
|
||||||
|
- Use project ID in repository cache to prevent stale data from persisting across projects
|
||||||
|
|
||||||
v 8.10.1 (unreleased)
|
v 8.10.1 (unreleased)
|
||||||
- Fix Error 500 when creating Wiki pages with hyphens or spaces
|
- Fix Error 500 when creating Wiki pages with hyphens or spaces
|
||||||
- Ignore invalid trusted proxies in X-Forwarded-For header
|
- Ignore invalid trusted proxies in X-Forwarded-For header
|
||||||
|
|
|
@ -1031,7 +1031,7 @@ class Repository
|
||||||
private
|
private
|
||||||
|
|
||||||
def cache
|
def cache
|
||||||
@cache ||= RepositoryCache.new(path_with_namespace)
|
@cache ||= RepositoryCache.new(path_with_namespace, @project.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def head_exists?
|
def head_exists?
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
# Interface to the Redis-backed cache store used by the Repository model
|
# Interface to the Redis-backed cache store used by the Repository model
|
||||||
class RepositoryCache
|
class RepositoryCache
|
||||||
attr_reader :namespace, :backend
|
attr_reader :namespace, :backend, :project_id
|
||||||
|
|
||||||
def initialize(namespace, backend = Rails.cache)
|
def initialize(namespace, project_id, backend = Rails.cache)
|
||||||
@namespace = namespace
|
@namespace = namespace
|
||||||
@backend = backend
|
@backend = backend
|
||||||
|
@project_id = project_id
|
||||||
end
|
end
|
||||||
|
|
||||||
def cache_key(type)
|
def cache_key(type)
|
||||||
"#{type}:#{namespace}"
|
"#{type}:#{namespace}:#{project_id}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def expire(key)
|
def expire(key)
|
||||||
|
|
|
@ -1,33 +1,34 @@
|
||||||
require_relative '../../lib/repository_cache'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe RepositoryCache, lib: true do
|
describe RepositoryCache, lib: true do
|
||||||
|
let(:project) { create(:project) }
|
||||||
let(:backend) { double('backend').as_null_object }
|
let(:backend) { double('backend').as_null_object }
|
||||||
let(:cache) { RepositoryCache.new('example', backend) }
|
let(:cache) { RepositoryCache.new('example', project.id, backend) }
|
||||||
|
|
||||||
describe '#cache_key' do
|
describe '#cache_key' do
|
||||||
it 'includes the namespace' do
|
it 'includes the namespace' do
|
||||||
expect(cache.cache_key(:foo)).to eq 'foo:example'
|
expect(cache.cache_key(:foo)).to eq "foo:example:#{project.id}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#expire' do
|
describe '#expire' do
|
||||||
it 'expires the given key from the cache' do
|
it 'expires the given key from the cache' do
|
||||||
cache.expire(:foo)
|
cache.expire(:foo)
|
||||||
expect(backend).to have_received(:delete).with('foo:example')
|
expect(backend).to have_received(:delete).with("foo:example:#{project.id}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#fetch' do
|
describe '#fetch' do
|
||||||
it 'fetches the given key from the cache' do
|
it 'fetches the given key from the cache' do
|
||||||
cache.fetch(:bar)
|
cache.fetch(:bar)
|
||||||
expect(backend).to have_received(:fetch).with('bar:example')
|
expect(backend).to have_received(:fetch).with("bar:example:#{project.id}")
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'accepts a block' do
|
it 'accepts a block' do
|
||||||
p = -> {}
|
p = -> {}
|
||||||
|
|
||||||
cache.fetch(:baz, &p)
|
cache.fetch(:baz, &p)
|
||||||
expect(backend).to have_received(:fetch).with('baz:example', &p)
|
expect(backend).to have_received(:fetch).with("baz:example:#{project.id}", &p)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue