Commit 56cee5a2 authored by Stan Hu's avatar Stan Hu

Use Gitaly protobuf version as DiffStats cache key

This avoids the pitfalls we saw in a mixed-deployment setup. If an
updated server adds a field such as `old_path` to the DiffStats protobuf
message definition, it will serialize this JSON to Redis. However, a
server running an older version will fetch this data and encounter an
error while trying to initialize `DiffStats`.

Most of the time this protobuf definition shouldn't change, but to be
sure we use the loaded Gem version.

Closes https://gitlab.com/gitlab-org/gitlab/-/issues/233083
parent bbf94418
---
title: Use Gitaly protobuf version as DiffStats cache key
merge_request: 38414
author:
type: fixed
......@@ -6,7 +6,8 @@ module Gitlab
include Gitlab::Utils::StrongMemoize
EXPIRATION = 1.week
VERSION = 1
# The DiffStats#as_json representation is tied to the Gitaly protobuf version
VERSION = Gem.loaded_specs['gitaly'].version.to_s
def initialize(cachable_key:)
@cachable_key = cachable_key
......@@ -29,6 +30,7 @@ module Gitlab
return unless stats
cache.write(key, stats.as_json, expires_in: EXPIRATION)
clear_memoization(:cached_values)
end
def clear
......
......@@ -81,4 +81,28 @@ RSpec.describe Gitlab::Diff::StatsCache, :use_clean_rails_memory_store_caching d
stats_cache.clear
end
end
it 'VERSION is set' do
expect(described_class::VERSION).to be_present
end
context 'with multiple cache versions' do
before do
stats_cache.write_if_empty(stats)
end
it 'does not read from a stale cache' do
expect(stats_cache.read.to_json).to eq(stats.to_json)
stub_const('Gitlab::Diff::StatsCache::VERSION', '1.0.new-new-thing')
stats_cache = described_class.new(cachable_key: cachable_key)
expect(stats_cache.read).to be_nil
stats_cache.write_if_empty(stats)
expect(stats_cache.read.to_json).to eq(stats.to_json)
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