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