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
end
def self.cache
@cache ||= Gitlab::Geo::Cache.new
@cache ||= Gitlab::JsonCache.new(:geo)
end
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
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 @@
require 'spec_helper'
describe Gitlab::Geo::Cache do
describe Gitlab::JsonCache do
let(:backend) { double('backend').as_null_object }
let(:namespace) { 'geo' }
let(:key) { 'foo' }
let(:expanded_key) { "geo:#{key}:#{Rails.version}" }
let(:expanded_key) { "#{namespace}:#{key}:#{Rails.version}" }
let(:node) { create(:geo_node) }
subject(:cache) { described_class.new(backend: backend) }
subject(:cache) { described_class.new(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(backend: backend)
cache = described_class.new(namespace, backend: backend)
expect(cache.active?).to eq(false)
end
......@@ -25,7 +26,7 @@ describe Gitlab::Geo::Cache do
it 'returns true' do
backend = double('backend')
cache = described_class.new(backend: backend)
cache = described_class.new(namespace, backend: backend)
expect(cache.active?).to eq(true)
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