Commit 5c900030 authored by Stan Hu's avatar Stan Hu

Merge branch '8765-geo-gitlab-geo-should-not-serialize-activerecord-objects' into 'master'

Add Rails.version to the Geo cache keys

See merge request gitlab-org/gitlab-ee!8775
parents 9f4701df 837a7caa
---
title: Add Rails.version to the Geo cache keys
merge_request: 8775
author:
type: fixed
# frozen_string_literal: true
module Gitlab module Gitlab
module Geo module Geo
OauthApplicationUndefinedError = Class.new(StandardError) OauthApplicationUndefinedError = Class.new(StandardError)
...@@ -6,24 +8,22 @@ module Gitlab ...@@ -6,24 +8,22 @@ module Gitlab
InvalidSignatureTimeError = Class.new(StandardError) InvalidSignatureTimeError = Class.new(StandardError)
CACHE_KEYS = %i( CACHE_KEYS = %i(
geo_primary_node primary_node
geo_secondary_nodes secondary_nodes
geo_node_enabled node_enabled
geo_node_primary oauth_application
geo_node_secondary
geo_oauth_application
).freeze ).freeze
def self.current_node def self.current_node
self.cache_value(:geo_node_current) { GeoNode.current_node } self.cache_value(:current_node) { GeoNode.current_node }
end end
def self.primary_node def self.primary_node
self.cache_value(:geo_primary_node) { GeoNode.primary_node } self.cache_value(:primary_node) { GeoNode.primary_node }
end end
def self.secondary_nodes def self.secondary_nodes
self.cache_value(:geo_secondary_nodes) { GeoNode.secondary_nodes } self.cache_value(:secondary_nodes) { GeoNode.secondary_nodes }
end end
def self.connected? def self.connected?
...@@ -31,7 +31,7 @@ module Gitlab ...@@ -31,7 +31,7 @@ module Gitlab
end end
def self.enabled? def self.enabled?
cache_value(:geo_node_enabled) { GeoNode.exists? } cache_value(:node_enabled) { GeoNode.exists? }
end end
def self.primary? def self.primary?
...@@ -74,24 +74,34 @@ module Gitlab ...@@ -74,24 +74,34 @@ module Gitlab
def self.oauth_authentication def self.oauth_authentication
return false unless Gitlab::Geo.secondary? return false unless Gitlab::Geo.secondary?
self.cache_value(:geo_oauth_application) do self.cache_value(:oauth_application) do
Gitlab::Geo.current_node.oauth_application || raise(OauthApplicationUndefinedError) Gitlab::Geo.current_node.oauth_application || raise(OauthApplicationUndefinedError)
end end
end end
def self.cache_value(key, &block) def self.cache_key_for(key)
return yield unless RequestStore.active? "geo:#{key}:#{Rails.version}"
end
def self.cache_value(raw_key, &block)
return yield unless Gitlab::SafeRequestStore.active?
# We need a short expire time as we can't manually expire on a secondary node key = cache_key_for(raw_key)
RequestStore.fetch(key) { Rails.cache.fetch(key, expires_in: 15.seconds) { yield } }
Gitlab::SafeRequestStore.fetch(key) do
# We need a short expire time as we can't manually expire on a secondary node
Rails.cache.fetch(key, expires_in: 15.seconds) { yield }
end
end end
def self.expire_cache! def self.expire_cache!
return true unless RequestStore.active? return true unless Gitlab::SafeRequestStore.active?
CACHE_KEYS.each do |raw_key|
key = cache_key_for(raw_key)
CACHE_KEYS.each do |key|
Rails.cache.delete(key) Rails.cache.delete(key)
RequestStore.delete(key) Gitlab::SafeRequestStore.delete(key)
end end
true true
......
...@@ -6,19 +6,36 @@ describe Gitlab::Geo, :geo do ...@@ -6,19 +6,36 @@ describe Gitlab::Geo, :geo do
set(:primary_node) { create(:geo_node, :primary) } set(:primary_node) { create(:geo_node, :primary) }
set(:secondary_node) { create(:geo_node) } set(:secondary_node) { create(:geo_node) }
describe 'current_node' do shared_examples 'a Geo cached value' do |method, key|
it 'includes Rails.version in the cache key', :request_store do
expect(Rails.cache).to receive(:fetch)
.with("geo:#{key}:#{Rails.version}", expires_in: 15.seconds)
described_class.public_send(method)
end
end
describe '.current_node' do
it 'returns a GeoNode instance' do it 'returns a GeoNode instance' do
expect(described_class.current_node).to eq(primary_node) expect(described_class.current_node).to eq(primary_node)
end end
it_behaves_like 'a Geo cached value', :current_node, :current_node
end end
describe 'primary_node' do describe '.primary_node' do
it 'returns a GeoNode primary instance' do it 'returns a GeoNode primary instance' do
expect(described_class.primary_node).to eq(primary_node) expect(described_class.primary_node).to eq(primary_node)
end end
it_behaves_like 'a Geo cached value', :primary_node, :primary_node
end
describe '.secondary_nodes' do
it_behaves_like 'a Geo cached value', :secondary_nodes, :secondary_nodes
end end
describe 'primary?' do describe '.primary?' do
context 'when current node is a primary node' do context 'when current node is a primary node' do
it 'returns true' do it 'returns true' do
expect(described_class.primary?).to be_truthy expect(described_class.primary?).to be_truthy
...@@ -32,7 +49,7 @@ describe Gitlab::Geo, :geo do ...@@ -32,7 +49,7 @@ describe Gitlab::Geo, :geo do
end end
end end
describe 'primary_node_configured?' do describe '.primary_node_configured?' do
context 'when current node is a primary node' do context 'when current node is a primary node' do
it 'returns true' do it 'returns true' do
expect(described_class.primary_node_configured?).to be_truthy expect(described_class.primary_node_configured?).to be_truthy
...@@ -46,7 +63,7 @@ describe Gitlab::Geo, :geo do ...@@ -46,7 +63,7 @@ describe Gitlab::Geo, :geo do
end end
end end
describe 'secondary?' do describe '.secondary?' do
context 'when current node is a secondary node' do context 'when current node is a secondary node' do
before do before do
stub_current_geo_node(secondary_node) stub_current_geo_node(secondary_node)
...@@ -64,7 +81,9 @@ describe Gitlab::Geo, :geo do ...@@ -64,7 +81,9 @@ describe Gitlab::Geo, :geo do
end end
end end
describe 'enabled?' do describe '.enabled?' do
it_behaves_like 'a Geo cached value', :enabled?, :node_enabled
context 'when any GeoNode exists' do context 'when any GeoNode exists' do
it 'returns true' do it 'returns true' do
expect(described_class.enabled?).to be_truthy expect(described_class.enabled?).to be_truthy
...@@ -92,7 +111,15 @@ describe Gitlab::Geo, :geo do ...@@ -92,7 +111,15 @@ describe Gitlab::Geo, :geo do
end end
end end
describe 'connected?' do describe '.oauth_authentication' do
before do
stub_secondary_node
end
it_behaves_like 'a Geo cached value', :oauth_authentication, :oauth_application
end
describe '.connected?' do
context 'when there is a database issue' do context 'when there is a database issue' do
it 'returns false when database connection is down' do it 'returns false when database connection is down' do
allow(GeoNode).to receive(:connected?) { false } allow(GeoNode).to receive(:connected?) { false }
...@@ -114,7 +141,7 @@ describe Gitlab::Geo, :geo do ...@@ -114,7 +141,7 @@ describe Gitlab::Geo, :geo do
end end
end end
describe 'secondary?' do describe '.secondary?' do
context 'when current node is secondary' do context 'when current node is secondary' do
it 'returns true' do it 'returns true' do
stub_current_geo_node(secondary_node) stub_current_geo_node(secondary_node)
...@@ -129,7 +156,17 @@ describe Gitlab::Geo, :geo do ...@@ -129,7 +156,17 @@ describe Gitlab::Geo, :geo do
end end
end end
describe 'license_allows?' do describe '.expire_cache!' do
it 'clears the Geo cache keys', :request_store do
described_class::CACHE_KEYS.each do |raw_key|
expect(Rails.cache).to receive(:delete).with("geo:#{raw_key}:#{Rails.version}")
end
described_class.expire_cache!
end
end
describe '.license_allows?' do
it 'returns true if license has Geo addon' do it 'returns true if license has Geo addon' do
stub_licensed_features(geo: true) stub_licensed_features(geo: true)
expect(described_class.license_allows?).to be_truthy expect(described_class.license_allows?).to be_truthy
......
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