consolidate course permissions cache, use in grants_right

We have code to cache the course permissions for a user in the
permissions code itself, and also in Course#enrollment_allows. The
latter was also building up the cache one permission at a time, and
writing it back to memcache every time, causing a lot of needless
memcache writes.

grants_right?() was also skipping this cache since it doesn't call
grants_rights, so special case that as well.

Change-Id: I89ff5d44a0f50985e2ecfdefb68df869e7d68a1a
Reviewed-on: https://gerrit.instructure.com/2841
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Brian Whitmer <brian@instructure.com>
This commit is contained in:
Brian Palmer 2011-03-28 10:07:52 -06:00
parent 76bfff3157
commit aa9821c761
2 changed files with 20 additions and 21 deletions

View File

@ -705,22 +705,16 @@ class Course < ActiveRecord::Base
def enrollment_allows(user, session, permission)
return false unless user && permission
@enrollment_lookup ||= {}
@enrollment_permission_lookup ||= (Rails.cache.read([self, 'enrollment_permission_lookup'].cache_key) || {}).dup
if session && temp_type = session["role_course_#{self.id}"]
@enrollment_lookup[user.id] = [Enrollment.typed_enrollment(temp_type).new(:course_id => self.id, :user_id => user.id, :workflow_state => 'active')] rescue nil
elsif session && session[:session_affects_permissions]
@enrollment_lookup[user.id] = nil
end
if !@enrollment_permission_lookup.has_key?([user.id, permission]) || (session && session[:session_affects_permissions])
@enrollment_lookup[user.id] ||= self.enrollments.active_or_pending.for_user(user)
@enrollment_permission_lookup[[user.id, permission]] = @enrollment_lookup[user.id].any?{|e| e.has_permission_to?(permission) }
unless session && session[:session_affects_permissions]
Rails.cache.write([self, 'enrollment_permission_lookup'].cache_key, @enrollment_permission_lookup.dup)
@enrollment_lookup[user.id] ||=
if session && temp_type = session["role_course_#{self.id}"]
[Enrollment.typed_enrollment(temp_type).new(:course_id => self.id, :user_id => user.id, :workflow_state => 'active')] rescue nil
else
self.enrollments.active_or_pending.for_user(user)
end
end
@enrollment_permission_lookup[[user.id, permission]]
@enrollment_lookup[user.id].any? {|e| e.has_permission_to?(permission) }
end
def self.find_all_by_context_code(codes)

View File

@ -186,8 +186,7 @@ module Instructure #:nodoc:
cache_lookup = nil if session && session[:session_affects_permissions]
user_id = user ? user.id : nil
cache_param = [user_id, sought_rights].flatten
# return @rights_cache[cache_param] if user_id && @rights_cache && @rights_cache[cache_param] != nil
# According to my understanding, calling Rails.cache.fetch with an
# empty string will always return the contents of the block, and
# will not cache the value at all
@ -202,11 +201,10 @@ module Instructure #:nodoc:
sought_rights = granted_rights if sought_rights.empty?
res = sought_rights.inject({}) { |h, r| h[r] = granted_rights.include?(r); h }
@rights_cache ||= {}
@rights_cache[cache_param] = res
res
end
# TODO: I don't think this is used anywhere, check and remove
def true_user_grants_right?(user, *sought_rights)
session = nil
if !sought_rights[0].is_a? Symbol
@ -215,7 +213,7 @@ module Instructure #:nodoc:
sought_right = sought_rights[0].to_sym rescue nil
grants_right?(user, {:session_affects_permissions => true}, sought_right)
end
def grants_right?(user, *sought_rights)
session = nil
if !sought_rights[0].is_a? Symbol
@ -223,10 +221,17 @@ module Instructure #:nodoc:
end
sought_right = sought_rights[0].to_sym rescue nil
return false unless sought_right
# if this is a course, call grants_rights which has specific logic to
# cache course rights lookups. otherwise we lose the benefits of that cache.
if self.is_a?(Course) && !(session && session[:session_affects_permissions])
return !!(self.grants_rights?(user, *[session].compact)[sought_right])
end
granted_rights = check_policy(user, session, *sought_rights)
granted_rights.include?(sought_right)
end
# Used for a more-natural: user.has_rights?(@account, :destroy)
def has_rights?(obj, *sought_rights)
granted_rights = obj.check_policy(self)