refactor keeping multiple copies of a specific cache key into a helper class

Change-Id: I7fd54391837e70fcb21b16573e2eb73cf533eb03
Reviewed-on: https://gerrit.instructure.com/42490
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Jacob Fugal <jacob@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
QA-Review: Cody Cutrer <cody@instructure.com>
This commit is contained in:
Cody Cutrer 2014-10-09 12:53:39 -06:00
parent 27dbafc6cc
commit a8c7bb617c
3 changed files with 35 additions and 8 deletions

View File

@ -736,17 +736,13 @@ class Account < ActiveRecord::Base
state :deleted
end
def self.all_site_admin_account_users_copies
[Setting.get('all_site_admin_account_users_copies', 1).to_i, 1].max
end
def account_users_for(user)
return [] unless user
@account_users_cache ||= {}
if self == Account.site_admin
shard.activate do
@account_users_cache[user.global_id] ||= begin
all_site_admin_account_users_hash = Rails.cache.fetch("all_site_admin_account_users2:#{rand(Account.all_site_admin_account_users_copies)}") do
all_site_admin_account_users_hash = MultiCache.fetch("all_site_admin_account_users2") do
# this is a plain ruby hash to keep the cached portion as small as possible
self.account_users.inject({}) { |result, au| result[au.user_id] ||= []; result[au.user_id] << [au.id, au.membership_type]; result }
end

View File

@ -28,9 +28,7 @@ class Cacher < ActiveRecord::Observer
when AccountUser
if obj.account_id == Account.site_admin.id
Shard.default.activate do
(0...Account.all_site_admin_account_users_copies).each do |i|
Rails.cache.delete("all_site_admin_account_users2:#{i}")
end
MultiCache.delete("all_site_admin_account_users2")
end
end
end

33
lib/multi_cache.rb Normal file
View File

@ -0,0 +1,33 @@
#
# Copyright (C) 2014 Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
module MultiCache
def self.copies(key)
[Setting.get("#{key}_copies", 1).to_i, 1].max
end
def self.fetch(key, &block)
Rails.cache.fetch("#{key}:#{rand(copies(key))}", &block)
end
def self.delete(key)
(0...copies(key)).each do |i|
Rails.cache.delete("#{key}:#{i}")
end
end
end