Commit d0b76d06 authored by Rémy Coutable's avatar Rémy Coutable

Cache PerformanceBar.allowed_user_ids list locally and in Redis

Signed-off-by: default avatarRémy Coutable <remy@rymai.me>
parent ea2f2ab0
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
module Gitlab module Gitlab
module PerformanceBar module PerformanceBar
ALLOWED_USER_IDS_KEY = 'performance_bar_allowed_user_ids:v2'.freeze ALLOWED_USER_IDS_KEY = 'performance_bar_allowed_user_ids:v2'.freeze
EXPIRY_TIME = 5.minutes EXPIRY_TIME_L1_CACHE = 1.minute
EXPIRY_TIME_L2_CACHE = 5.minutes
def self.enabled?(user = nil) def self.enabled?(user = nil)
return true if Rails.env.development? return true if Rails.env.development?
...@@ -19,20 +20,31 @@ module Gitlab ...@@ -19,20 +20,31 @@ module Gitlab
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def self.allowed_user_ids def self.allowed_user_ids
Rails.cache.fetch(ALLOWED_USER_IDS_KEY, expires_in: EXPIRY_TIME) do l1_cache_backend.fetch(ALLOWED_USER_IDS_KEY, expires_in: EXPIRY_TIME_L1_CACHE) do
group = Group.find_by_id(allowed_group_id) l2_cache_backend.fetch(ALLOWED_USER_IDS_KEY, expires_in: EXPIRY_TIME_L2_CACHE) do
group = Group.find_by_id(allowed_group_id)
if group if group
GroupMembersFinder.new(group).execute.pluck(:user_id) GroupMembersFinder.new(group).execute.pluck(:user_id)
else else
[] []
end
end end
end end
end end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
def self.expire_allowed_user_ids_cache def self.expire_allowed_user_ids_cache
Rails.cache.delete(ALLOWED_USER_IDS_KEY) l1_cache_backend.delete(ALLOWED_USER_IDS_KEY)
l2_cache_backend.delete(ALLOWED_USER_IDS_KEY)
end
def self.l1_cache_backend
Gitlab::ThreadMemoryCache.cache_backend
end
def self.l2_cache_backend
Rails.cache
end end
end end
end end
...@@ -3,17 +3,42 @@ require 'spec_helper' ...@@ -3,17 +3,42 @@ require 'spec_helper'
describe Gitlab::PerformanceBar do describe Gitlab::PerformanceBar do
shared_examples 'allowed user IDs are cached' do shared_examples 'allowed user IDs are cached' do
before do before do
# Warm the Redis cache # Warm the caches
described_class.enabled?(user) described_class.enabled?(user)
end end
it 'caches the allowed user IDs in cache', :use_clean_rails_memory_store_caching do it 'caches the allowed user IDs in cache', :use_clean_rails_memory_store_caching do
expect do expect do
expect(described_class.l1_cache_backend).to receive(:fetch).and_call_original
expect(described_class.l2_cache_backend).not_to receive(:fetch)
expect(described_class.enabled?(user)).to be_truthy expect(described_class.enabled?(user)).to be_truthy
end.not_to exceed_query_limit(0) end.not_to exceed_query_limit(0)
end end
it 'caches the allowed user IDs in L1 cache for 1 minute', :use_clean_rails_memory_store_caching do
Timecop.travel 2.minutes do
expect do
expect(described_class.l1_cache_backend).to receive(:fetch).and_call_original
expect(described_class.l2_cache_backend).to receive(:fetch).and_call_original
expect(described_class.enabled?(user)).to be_truthy
end.not_to exceed_query_limit(0)
end
end
it 'caches the allowed user IDs in L2 cache for 5 minutes', :use_clean_rails_memory_store_caching do
Timecop.travel 6.minutes do
expect do
expect(described_class.l1_cache_backend).to receive(:fetch).and_call_original
expect(described_class.l2_cache_backend).to receive(:fetch).and_call_original
expect(described_class.enabled?(user)).to be_truthy
end.not_to exceed_query_limit(2)
end
end
end end
it { expect(described_class.l1_cache_backend).to eq(Gitlab::ThreadMemoryCache.cache_backend) }
it { expect(described_class.l2_cache_backend).to eq(Rails.cache) }
describe '.enabled?' do describe '.enabled?' do
let(:user) { create(:user) } let(:user) { create(:user) }
......
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