Refactor Gitlab::JsonCache to accepts an option hash

parent 760a9991
......@@ -15,15 +15,15 @@ module Gitlab
).freeze
def self.current_node
self.cache_value(:current_node, klass: GeoNode) { GeoNode.current_node }
self.cache_value(:current_node, as: GeoNode) { GeoNode.current_node }
end
def self.primary_node
self.cache_value(:primary_node, klass: GeoNode) { GeoNode.primary_node }
self.cache_value(:primary_node, as: GeoNode) { GeoNode.primary_node }
end
def self.secondary_nodes
self.cache_value(:secondary_nodes, klass: GeoNode) { GeoNode.secondary_nodes }
self.cache_value(:secondary_nodes, as: GeoNode) { GeoNode.secondary_nodes }
end
def self.connected?
......@@ -80,19 +80,19 @@ module Gitlab
end
def self.cache
@cache ||= Gitlab::JsonCache.new(:geo)
@cache ||= Gitlab::JsonCache.new(namespace: :geo)
end
def self.request_store_cache
@request_store_cache ||= Gitlab::JsonCache.new(:geo, backend: Gitlab::SafeRequestStore)
@request_store_cache ||= Gitlab::JsonCache.new(namespace: :geo, backend: Gitlab::SafeRequestStore)
end
def self.cache_value(key, klass: nil, &block)
def self.cache_value(key, as: nil, &block)
return yield unless request_store_cache.active?
request_store_cache.fetch(key, klass: klass) do
request_store_cache.fetch(key, as: as) do
# We need a short expire time as we can't manually expire on a secondary node
cache.fetch(key, klass: klass, expires_in: 15.seconds) { yield }
cache.fetch(key, as: as, expires_in: 15.seconds) { yield }
end
end
......
......@@ -2,11 +2,12 @@
module Gitlab
class JsonCache
attr_reader :namespace, :backend
attr_reader :backend, :cache_key_with_version, :namespace
def initialize(namespace, backend: Rails.cache)
@backend = backend
@namespace = namespace
def initialize(options = {})
@backend = options.fetch(:backend, Rails.cache)
@namespace = options.fetch(:namespace, nil)
@cache_key_with_version = options.fetch(:cache_key_with_version, true)
end
def active?
......@@ -18,7 +19,13 @@ module Gitlab
end
def cache_key(key)
"#{namespace}:#{key}:#{Rails.version}"
expanded_cache_key = [namespace, key].compact
if cache_key_with_version
expanded_cache_key << Rails.version
end
expanded_cache_key.join(':')
end
def expire(key)
......@@ -36,8 +43,9 @@ module Gitlab
end
def fetch(key, options = {}, &block)
klass = options.delete(:klass)
klass = options.delete(:as)
value = read(key, klass)
return value unless value.nil?
value = yield
......
......@@ -9,14 +9,14 @@ describe Gitlab::JsonCache do
let(:expanded_key) { "#{namespace}:#{key}:#{Rails.version}" }
let(:node) { create(:geo_node) }
subject(:cache) { described_class.new(namespace, backend: backend) }
subject(:cache) { described_class.new(namespace: namespace, backend: backend) }
describe '#active?' do
context 'when backend respond to active? method' do
it 'delegates to the underlying cache implementation' do
backend = double('backend', active?: false)
cache = described_class.new(namespace, backend: backend)
cache = described_class.new(namespace: namespace, backend: backend)
expect(cache.active?).to eq(false)
end
......@@ -26,7 +26,7 @@ describe Gitlab::JsonCache do
it 'returns true' do
backend = double('backend')
cache = described_class.new(namespace, backend: backend)
cache = described_class.new(namespace: namespace, backend: backend)
expect(cache.active?).to eq(true)
end
......@@ -34,10 +34,44 @@ describe Gitlab::JsonCache do
end
describe '#cache_key' do
it 'expands out the key with namespace and Rails version' do
cache_key = cache.cache_key(key)
context 'when namespace is not defined' do
it 'expands out the key with Rails version' do
cache = described_class.new(cache_key_with_version: true)
expect(cache_key).to eq(expanded_key)
cache_key = cache.cache_key(key)
expect(cache_key).to eq("#{key}:#{Rails.version}")
end
end
context 'when cache_key_with_version is true' do
it 'expands out the key with namespace and Rails version' do
cache = described_class.new(namespace: namespace, cache_key_with_version: true)
cache_key = cache.cache_key(key)
expect(cache_key).to eq("#{namespace}:#{key}:#{Rails.version}")
end
end
context 'when cache_key_with_version is false' do
it 'expands out the key with namespace' do
cache = described_class.new(namespace: namespace, cache_key_with_version: false)
cache_key = cache.cache_key(key)
expect(cache_key).to eq("#{namespace}:#{key}")
end
end
context 'when namespace is nil, and cache_key_with_version is false' do
it 'returns the key' do
cache = described_class.new(namespace: nil, cache_key_with_version: false)
cache_key = cache.cache_key(key)
expect(cache_key).to eq(key)
end
end
end
......@@ -251,18 +285,18 @@ describe Gitlab::JsonCache do
end
it 'parses the cached value' do
result = cache.fetch(key, klass: GeoNode) { 'block result' }
result = cache.fetch(key, as: GeoNode) { 'block result' }
expect(result).to eq(node)
end
it 'returns the result of the block when klass is nil' do
result = cache.fetch(key, klass: nil) { 'block result' }
it "returns the result of the block when 'as' option is nil" do
result = cache.fetch(key, as: nil) { 'block result' }
expect(result).to eq('block result')
end
it 'returns the result of the block when klass is not informed' do
it "returns the result of the block when 'as' option is not informed" do
result = cache.fetch(key) { 'block result' }
expect(result).to eq('block result')
......@@ -275,18 +309,18 @@ describe Gitlab::JsonCache do
end
it 'parses the cached value' do
result = cache.fetch(key, klass: GeoNode) { 'block result' }
result = cache.fetch(key, as: GeoNode) { 'block result' }
expect(result).to eq([node])
end
it 'returns an empty array when klass is nil' do
result = cache.fetch(key, klass: nil) { 'block result' }
it "returns an empty array when 'as' option is nil" do
result = cache.fetch(key, as: nil) { 'block result' }
expect(result).to eq([])
end
it 'returns an empty array when klass is not informed' do
it "returns an empty array when 'as' option is not informed" do
result = cache.fetch(key) { 'block result' }
expect(result).to eq([])
......
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