Extract attribute caching to RedisCacheable concern
This commit is contained in:
parent
c92e1d731c
commit
aa60c7a2b5
|
@ -2,14 +2,13 @@ module Ci
|
|||
class Runner < ActiveRecord::Base
|
||||
extend Gitlab::Ci::Model
|
||||
include Gitlab::SQL::Pattern
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
include RedisCacheable
|
||||
|
||||
RUNNER_QUEUE_EXPIRY_TIME = 60.minutes
|
||||
ONLINE_CONTACT_TIMEOUT = 1.hour
|
||||
UPDATE_DB_RUNNER_INFO_EVERY = 40.minutes
|
||||
AVAILABLE_SCOPES = %w[specific shared active paused online].freeze
|
||||
FORM_EDITABLE = %i[description tag_list active run_untagged locked access_level].freeze
|
||||
CACHED_ATTRIBUTES_EXPIRY_TIME = 24.hours
|
||||
|
||||
has_many :builds
|
||||
has_many :runner_projects, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
@ -50,6 +49,8 @@ module Ci
|
|||
ref_protected: 1
|
||||
}
|
||||
|
||||
cached_attr_reader :version, :revision, :platform, :architecture, :contacted_at
|
||||
|
||||
# Searches for runners matching the given query.
|
||||
#
|
||||
# This method uses ILIKE on PostgreSQL and LIKE on MySQL.
|
||||
|
@ -70,16 +71,6 @@ module Ci
|
|||
ONLINE_CONTACT_TIMEOUT.ago
|
||||
end
|
||||
|
||||
def self.cached_attr_reader(*attributes)
|
||||
attributes.each do |attribute|
|
||||
define_method("#{attribute}") do
|
||||
cached_attribute(attribute) || read_attribute(attribute)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
cached_attr_reader :version, :revision, :platform, :architecture, :contacted_at
|
||||
|
||||
def set_default_values
|
||||
self.token = SecureRandom.hex(15) if self.token.blank?
|
||||
end
|
||||
|
@ -189,10 +180,6 @@ module Ci
|
|||
"runner:build_queue:#{self.token}"
|
||||
end
|
||||
|
||||
def cache_attribute_key
|
||||
"runner:info:#{self.id}"
|
||||
end
|
||||
|
||||
def persist_cached_data?
|
||||
# Use a random threshold to prevent beating DB updates.
|
||||
# It generates a distribution between [40m, 80m].
|
||||
|
@ -204,25 +191,6 @@ module Ci
|
|||
(Time.now - real_contacted_at) >= contacted_at_max_age
|
||||
end
|
||||
|
||||
def cached_attribute(key)
|
||||
(cached_attributes || {})[key]
|
||||
end
|
||||
|
||||
def cached_attributes
|
||||
strong_memoize(:cached_attributes) do
|
||||
Gitlab::Redis::SharedState.with do |redis|
|
||||
data = redis.get(cache_attribute_key)
|
||||
JSON.parse(data, symbolize_names: true) if data
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def cache_attributes(values)
|
||||
Gitlab::Redis::SharedState.with do |redis|
|
||||
redis.set(cache_attribute_key, values.to_json, ex: CACHED_ATTRIBUTES_EXPIRY_TIME)
|
||||
end
|
||||
end
|
||||
|
||||
def tag_constraints
|
||||
unless has_tags? || run_untagged?
|
||||
errors.add(:tags_list,
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
module RedisCacheable
|
||||
extend ActiveSupport::Concern
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
|
||||
CACHED_ATTRIBUTES_EXPIRY_TIME = 24.hours
|
||||
|
||||
class_methods do
|
||||
def cached_attr_reader(*attributes)
|
||||
attributes.each do |attribute|
|
||||
define_method("#{attribute}") do
|
||||
cached_attribute(attribute) || read_attribute(attribute)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def cached_attribute(attribute)
|
||||
(cached_attributes || {})[attribute]
|
||||
end
|
||||
|
||||
def cache_attributes(values)
|
||||
Gitlab::Redis::SharedState.with do |redis|
|
||||
redis.set(cache_attribute_key, values.to_json, ex: CACHED_ATTRIBUTES_EXPIRY_TIME)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def cache_attribute_key
|
||||
"#{self.class.name}:attributes:#{self.id}"
|
||||
end
|
||||
|
||||
def cached_attributes
|
||||
strong_memoize(:cached_attributes) do
|
||||
Gitlab::Redis::SharedState.with do |redis|
|
||||
data = redis.get(cache_attribute_key)
|
||||
JSON.parse(data, symbolize_names: true) if data
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,34 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe RedisCacheable do
|
||||
let(:runner) { build(:ci_runner) }
|
||||
|
||||
describe '#cached_attribute' do
|
||||
subject { runner.cached_attribute(:anything) }
|
||||
|
||||
it 'gets the cache attribute' do
|
||||
Gitlab::Redis::SharedState.with do |redis|
|
||||
expect(redis).to receive(:get).with(runner.send(:cache_attribute_key))
|
||||
end
|
||||
|
||||
subject
|
||||
end
|
||||
end
|
||||
|
||||
describe '#cache_attributes' do
|
||||
let(:values) { { name: 'new_name' } }
|
||||
|
||||
subject { runner.cache_attributes(values) }
|
||||
|
||||
it 'sets the cache attributes' do
|
||||
Gitlab::Redis::SharedState.with do |redis|
|
||||
values.each do |key, value|
|
||||
redis_key = runner.send(:cache_attribute_key)
|
||||
expect(redis).to receive(:set).with(redis_key, values.to_json, anything)
|
||||
end
|
||||
end
|
||||
|
||||
subject
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue