Commit b954fcfd authored by Jay Swain's avatar Jay Swain

Bust the cache for release highlights

This commit adds a "cache bust" for the keys used in the
ReleaseHighlight model. Following a staging deploy it became aparent
that the type of object returned by the cache did not match the
previous, which was causing 500's.

part of:
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49233
https://gitlab.com/gitlab-com/gl-infra/production/-/issues/3144
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/47852
parent 5ed50083
......@@ -16,7 +16,9 @@ class ReleaseHighlight
end
def self.paginated(page: 1)
Rails.cache.fetch(cache_key(page), expires_in: CACHE_DURATION) do
key = self.cache_key("items:page-#{page}")
Rails.cache.fetch(key, expires_in: CACHE_DURATION) do
items = self.load_items(page: page)
next if items.nil?
......@@ -44,14 +46,13 @@ class ReleaseHighlight
end
def self.file_paths
@file_paths ||= Rails.cache.fetch('release_highlight:file_paths', expires_in: CACHE_DURATION) do
@file_paths ||= Rails.cache.fetch(self.cache_key('file_paths'), expires_in: CACHE_DURATION) do
Dir.glob(FILES_PATH).sort.reverse
end
end
def self.cache_key(page)
filename = /\d*\_\d*\_\d*/.match(self.file_paths&.first)
"release_highlight:items:file-#{filename}:page-#{page}"
def self.cache_key(key)
['release_highlight', key, Gitlab.revision].join(':')
end
def self.next_page(current_page: 1)
......@@ -62,13 +63,17 @@ class ReleaseHighlight
end
def self.most_recent_item_count
Gitlab::ProcessMemoryCache.cache_backend.fetch('release_highlight:recent_item_count', expires_in: CACHE_DURATION) do
key = self.cache_key('recent_item_count')
Gitlab::ProcessMemoryCache.cache_backend.fetch(key, expires_in: CACHE_DURATION) do
self.paginated&.items&.count
end
end
def self.versions
Gitlab::ProcessMemoryCache.cache_backend.fetch('release_highlight:versions', expires_in: CACHE_DURATION) do
key = self.cache_key('versions')
Gitlab::ProcessMemoryCache.cache_backend.fetch(key, expires_in: CACHE_DURATION) do
versions = self.file_paths.first(RELEASE_VERSIONS_IN_A_YEAR).map do |path|
/\d*\_(\d*\_\d*)\.yml$/.match(path).captures[0].gsub(/0(?=\d)/, "").tr("_", ".")
end
......
......@@ -4,11 +4,9 @@ require 'spec_helper'
RSpec.describe ReleaseHighlight do
let(:fixture_dir_glob) { Dir.glob(File.join('spec', 'fixtures', 'whats_new', '*.yml')) }
let(:cache_mock) { double(:cache_mock) }
before do
allow(Dir).to receive(:glob).with(Rails.root.join('data', 'whats_new', '*.yml')).and_return(fixture_dir_glob)
allow(cache_mock).to receive(:fetch).with('release_highlight:file_paths', expires_in: 1.hour).and_yield
end
after do
......@@ -40,16 +38,11 @@ RSpec.describe ReleaseHighlight do
before do
allow(Gitlab).to receive(:com?).and_return(dot_com)
expect(Rails).to receive(:cache).twice.and_return(cache_mock)
end
context 'with page param' do
subject { ReleaseHighlight.paginated(page: page) }
before do
allow(cache_mock).to receive(:fetch).and_yield
end
context 'when there is another page of results' do
let(:page) { 2 }
......@@ -80,11 +73,14 @@ RSpec.describe ReleaseHighlight do
context 'with no page param' do
subject { ReleaseHighlight.paginated }
before do
expect(cache_mock).to receive(:fetch).with('release_highlight:items:file-20201225_01_05:page-1', expires_in: 1.hour).and_yield
it 'uses multiple levels of cache' do
expect(Rails.cache).to receive(:fetch).with("release_highlight:items:page-1:#{Gitlab.revision}", { expires_in: described_class::CACHE_DURATION }).and_call_original
expect(Rails.cache).to receive(:fetch).with("release_highlight:file_paths:#{Gitlab.revision}", { expires_in: described_class::CACHE_DURATION }).and_call_original
subject
end
it 'returns platform specific items and uses a cache key' do
it 'returns platform specific items' do
expect(subject[:items].count).to eq(1)
expect(subject[:items].first['title']).to eq("bright and sunshinin' day")
expect(subject[:next_page]).to eq(2)
......@@ -116,6 +112,12 @@ RSpec.describe ReleaseHighlight do
describe '.most_recent_item_count' do
subject { ReleaseHighlight.most_recent_item_count }
it 'uses process memory cache' do
expect(Gitlab::ProcessMemoryCache.cache_backend).to receive(:fetch).with("release_highlight:recent_item_count:#{Gitlab.revision}", expires_in: described_class::CACHE_DURATION)
subject
end
context 'when recent release items exist' do
it 'returns the count from the most recent file' do
allow(ReleaseHighlight).to receive(:paginated).and_return(double(:paginated, items: [double(:item)]))
......@@ -134,8 +136,16 @@ RSpec.describe ReleaseHighlight do
end
describe '.versions' do
subject { described_class.versions }
it 'uses process memory cache' do
expect(Gitlab::ProcessMemoryCache.cache_backend).to receive(:fetch).with("release_highlight:versions:#{Gitlab.revision}", { expires_in: described_class::CACHE_DURATION })
subject
end
it 'returns versions from the file paths' do
expect(ReleaseHighlight.versions).to eq(['1.5', '1.2', '1.1'])
expect(subject).to eq(['1.5', '1.2', '1.1'])
end
context 'when there are more than 12 versions' do
......@@ -146,7 +156,7 @@ RSpec.describe ReleaseHighlight do
it 'limits to 12 versions' do
allow(ReleaseHighlight).to receive(:file_paths).and_return(file_paths)
expect(ReleaseHighlight.versions.count).to eq(12)
expect(subject.count).to eq(12)
end
end
end
......
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