diff options
author | Matija Čupić <matteeyah@gmail.com> | 2018-05-15 21:55:16 +0200 |
---|---|---|
committer | Matija Čupić <matteeyah@gmail.com> | 2018-05-15 21:55:16 +0200 |
commit | 6cc3a07dca635aa61d275eb6803cd986f4c9f967 (patch) | |
tree | 398079c866fd6ef146273a15f67ffb7c7c0fc577 | |
parent | 2c29e80a93dffb1a854f4c63171b1a91eddea8d9 (diff) | |
download | gitlab-ce-6cc3a07dca635aa61d275eb6803cd986f4c9f967.tar.gz |
Dynamically cast value from cache
-rw-r--r-- | app/models/ci/runner.rb | 3 | ||||
-rw-r--r-- | app/models/concerns/redis_cacheable.rb | 19 | ||||
-rw-r--r-- | spec/models/concerns/redis_cacheable_spec.rb | 42 |
3 files changed, 15 insertions, 49 deletions
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index 54326d0c42c..49db5f6ab7f 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -75,8 +75,7 @@ module Ci project_type: 3 } - cached_attr_reader :version, :revision, :platform, :architecture, :ip_address - cached_attr_time_reader :contacted_at + cached_attr_reader :version, :revision, :platform, :architecture, :ip_address, :contacted_at chronic_duration_attr :maximum_timeout_human_readable, :maximum_timeout diff --git a/app/models/concerns/redis_cacheable.rb b/app/models/concerns/redis_cacheable.rb index 8bd0df8dfbe..4fdaaddeee7 100644 --- a/app/models/concerns/redis_cacheable.rb +++ b/app/models/concerns/redis_cacheable.rb @@ -8,16 +8,9 @@ module RedisCacheable def cached_attr_reader(*attributes) attributes.each do |attribute| define_method(attribute) do - cached_attribute(attribute) || read_attribute(attribute) - end - end - end - - def cached_attr_time_reader(*attributes) - attributes.each do |attribute| - define_method(attribute) do cached_value = cached_attribute(attribute) - cached_value ? Time.zone.parse(cached_value) : read_attribute(attribute) + cached_value = cast_value_from_cache(attribute, cached_value) if cached_value + cached_value || read_attribute(attribute) end end end @@ -49,4 +42,12 @@ module RedisCacheable end end end + + def cast_value_from_cache(attribute, value) + if self.class.column_for_attribute(attribute).respond_to?(:type_cast_from_database) + self.class.column_for_attribute(attribute).type_cast_from_database(value) + else + self.class.type_for_attribute(attribute).cast(value) + end + end end diff --git a/spec/models/concerns/redis_cacheable_spec.rb b/spec/models/concerns/redis_cacheable_spec.rb index 2e496cfb439..827629c3180 100644 --- a/spec/models/concerns/redis_cacheable_spec.rb +++ b/spec/models/concerns/redis_cacheable_spec.rb @@ -6,6 +6,10 @@ describe RedisCacheable do def read_attribute(attribute) attributes[attribute] end + + def cast_value_from_cache(attribute, cached_value) + cached_value + end end end @@ -75,42 +79,4 @@ describe RedisCacheable do expect(instance.name).to eq('new_value') end end - - describe '#cached_attr_time_reader', :clean_gitlab_redis_shared_state do - subject { instance.time } - - let(:other_time) { Time.zone.parse('May 14 2018') } - - before do - model.cached_attr_time_reader(:time) - end - - context 'when there is no cached value' do - it 'reads the attribute' do - expect(instance).to receive(:read_attribute).and_call_original - - expect(subject).to be_instance_of(ActiveSupport::TimeWithZone) - expect(subject).to eq(payload[:time]) - end - end - - context 'when there is a cached value' do - it 'reads the cached value' do - expect(instance).not_to receive(:read_attribute) - - instance.cache_attributes(time: other_time) - - expect(subject).to be_instance_of(ActiveSupport::TimeWithZone) - expect(subject).to eq(other_time) - end - end - - it 'always returns the latest values' do - expect(instance.time).to eq(payload[:time]) - - instance.cache_attributes(time: other_time) - - expect(instance.time).to eq(other_time) - end - end end |