Rename Gitlab::Geo::Cache to Gitlab::JsonCache

The Gitlab::Geo::Cache is a utility class that
can be reused outside of the Geo context.
parent 4b7f7680
...@@ -80,11 +80,11 @@ module Gitlab ...@@ -80,11 +80,11 @@ module Gitlab
end end
def self.cache def self.cache
@cache ||= Gitlab::Geo::Cache.new @cache ||= Gitlab::JsonCache.new(:geo)
end end
def self.request_store_cache def self.request_store_cache
@request_store_cache ||= Gitlab::Geo::Cache.new(backend: Gitlab::SafeRequestStore) @request_store_cache ||= Gitlab::JsonCache.new(:geo, backend: Gitlab::SafeRequestStore)
end end
def self.cache_value(key, klass: nil, &block) def self.cache_value(key, klass: nil, &block)
......
# frozen_string_literal: true
module Gitlab
module Geo
class Cache
attr_reader :namespace, :backend
def initialize(backend: Rails.cache)
@backend = backend
@namespace = :geo
end
def active?
if backend.respond_to?(:active?)
backend.active?
else
true
end
end
def cache_key(key)
"#{namespace}:#{key}:#{Rails.version}"
end
def expire(key)
backend.delete(cache_key(key))
end
def read(key, klass = nil)
value = backend.read(cache_key(key))
value = parse_value(value, klass) if value
value
end
def write(key, value, options = {})
backend.write(cache_key(key), *[value.to_json, options].reject(&:blank?))
end
def fetch(key, options = {}, &block)
klass = options.delete(:klass)
value = read(key, klass)
return value unless value.nil?
value = yield
write(key, value, options)
value
end
private
def parse_value(raw, klass)
value = ActiveSupport::JSON.decode(raw)
case value
when Hash then parse_entry(value, klass)
when Array then parse_entries(value, klass)
else
value
end
rescue ActiveSupport::JSON.parse_error
nil
end
def parse_entry(raw, klass)
klass.new(raw) if valid_entry?(raw, klass)
end
def valid_entry?(raw, klass)
return false unless klass && raw.is_a?(Hash)
(raw.keys - klass.attribute_names).empty?
end
def parse_entries(values, klass)
values.map { |value| parse_entry(value, klass) }.compact
end
end
end
end
# frozen_string_literal: true
module Gitlab
class JsonCache
attr_reader :namespace, :backend
def initialize(namespace, backend: Rails.cache)
@backend = backend
@namespace = namespace
end
def active?
if backend.respond_to?(:active?)
backend.active?
else
true
end
end
def cache_key(key)
"#{namespace}:#{key}:#{Rails.version}"
end
def expire(key)
backend.delete(cache_key(key))
end
def read(key, klass = nil)
value = backend.read(cache_key(key))
value = parse_value(value, klass) if value
value
end
def write(key, value, options = {})
backend.write(cache_key(key), *[value.to_json, options].reject(&:blank?))
end
def fetch(key, options = {}, &block)
klass = options.delete(:klass)
value = read(key, klass)
return value unless value.nil?
value = yield
write(key, value, options)
value
end
private
def parse_value(raw, klass)
value = ActiveSupport::JSON.decode(raw)
case value
when Hash then parse_entry(value, klass)
when Array then parse_entries(value, klass)
else
value
end
rescue ActiveSupport::JSON.parse_error
nil
end
def parse_entry(raw, klass)
klass.new(raw) if valid_entry?(raw, klass)
end
def valid_entry?(raw, klass)
return false unless klass && raw.is_a?(Hash)
(raw.keys - klass.attribute_names).empty?
end
def parse_entries(values, klass)
values.map { |value| parse_entry(value, klass) }.compact
end
end
end
...@@ -2,20 +2,21 @@ ...@@ -2,20 +2,21 @@
require 'spec_helper' require 'spec_helper'
describe Gitlab::Geo::Cache do describe Gitlab::JsonCache do
let(:backend) { double('backend').as_null_object } let(:backend) { double('backend').as_null_object }
let(:namespace) { 'geo' }
let(:key) { 'foo' } let(:key) { 'foo' }
let(:expanded_key) { "geo:#{key}:#{Rails.version}" } let(:expanded_key) { "#{namespace}:#{key}:#{Rails.version}" }
let(:node) { create(:geo_node) } let(:node) { create(:geo_node) }
subject(:cache) { described_class.new(backend: backend) } subject(:cache) { described_class.new(namespace, backend: backend) }
describe '#active?' do describe '#active?' do
context 'when backend respond to active? method' do context 'when backend respond to active? method' do
it 'delegates to the underlying cache implementation' do it 'delegates to the underlying cache implementation' do
backend = double('backend', active?: false) backend = double('backend', active?: false)
cache = described_class.new(backend: backend) cache = described_class.new(namespace, backend: backend)
expect(cache.active?).to eq(false) expect(cache.active?).to eq(false)
end end
...@@ -25,7 +26,7 @@ describe Gitlab::Geo::Cache do ...@@ -25,7 +26,7 @@ describe Gitlab::Geo::Cache do
it 'returns true' do it 'returns true' do
backend = double('backend') backend = double('backend')
cache = described_class.new(backend: backend) cache = described_class.new(namespace, backend: backend)
expect(cache.active?).to eq(true) expect(cache.active?).to eq(true)
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