show temporary invitations from all shards

test plan:
 * turn on cross-shard invitations in the console
   (Setting.set('cross_shard_invitations', '1'))
 * create a user with an email address in a shard (NOT
   a site admin)
 * in an unrelated shard with open registration on,
   as an admin invite that e-mail address to a course
 * log in as the original user on the first shard; the invitation
   should show up on your dashboard
 * accepting/rejecting that invitation is *not* yet supported

Change-Id: I3b0c9657fe0dd37a737af9f4253ea8ef8b2f2b91
Reviewed-on: https://gerrit.instructure.com/14903
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Jacob Fugal <jacob@instructure.com>
This commit is contained in:
Cody Cutrer 2012-10-31 13:34:39 -06:00
parent c1a08e7119
commit 626dddfddc
3 changed files with 111 additions and 24 deletions

View File

@ -359,4 +359,8 @@ class CommunicationChannel < ActiveRecord::Base
protected :assert_path_type
def self.serialization_excludes; [:confirmation_code]; end
def self.associated_shards(path)
[Shard.default]
end
end

View File

@ -323,7 +323,13 @@ class Enrollment < ActiveRecord::Base
def clear_email_caches
if self.workflow_state_changed? && (self.workflow_state_was == 'invited' || self.workflow_state == 'invited')
self.user.communication_channels.email.unretired.each { |cc| Rails.cache.delete([cc.path, 'invited_enrollments'].cache_key)}
if Enrollment.cross_shard_invitations?
Shard.default.activate do
self.user.communication_channels.email.unretired.each { |cc| Rails.cache.delete([cc.path, 'all_invited_enrollments'].cache_key)}
end
else
self.user.communication_channels.email.unretired.each { |cc| Rails.cache.delete([cc.path, 'invited_enrollments'].cache_key)}
end
end
end
@ -837,8 +843,18 @@ class Enrollment < ActiveRecord::Base
}
}
def self.cached_temporary_invitations(email)
Rails.cache.fetch([email, 'invited_enrollments'].cache_key) do
Enrollment.invited.for_email(email).to_a
if Enrollment.cross_shard_invitations?
Shard.default.activate do
invitations = Rails.cache.fetch([email, 'all_invited_enrollments'].cache_key) do
Shard.with_each_shard(CommunicationChannel.associated_shards(email)) do
Enrollment.invited.for_email(email).to_a
end
end
end
else
Rails.cache.fetch([email, 'invited_enrollments'].cache_key) do
Enrollment.invited.for_email(email).to_a
end
end
end
@ -959,4 +975,8 @@ class Enrollment < ActiveRecord::Base
course.conclude_at ||
course.enrollment_term && course.enrollment_term.end_at
end
def self.cross_shard_invitations?
false
end
end

View File

@ -1141,29 +1141,92 @@ describe Enrollment do
end
end
it "should uncache temporary user invitations when state changes" do
enable_cache do
course(:active_all => 1)
user
@user.update_attribute(:workflow_state, 'creation_pending')
@user.communication_channels.create!(:path => 'jt@instructure.com')
@enrollment = @course.enroll_user(@user)
Enrollment.cached_temporary_invitations('jt@instructure.com').length.should == 1
@enrollment.accept
Enrollment.cached_temporary_invitations('jt@instructure.com').should == []
describe "cached_temporary_invitations" do
it "should uncache temporary user invitations when state changes" do
enable_cache do
course(:active_all => 1)
user
@user.update_attribute(:workflow_state, 'creation_pending')
@user.communication_channels.create!(:path => 'jt@instructure.com')
@enrollment = @course.enroll_user(@user)
Enrollment.cached_temporary_invitations('jt@instructure.com').length.should == 1
@enrollment.accept
Enrollment.cached_temporary_invitations('jt@instructure.com').should == []
end
end
end
it "should uncache user enrollments when rejected" do
enable_cache do
course_with_student(:active_course => 1)
User.update_all({:updated_at => 1.year.ago}, :id => @user.id)
@user.reload
@user.cached_current_enrollments.should == [@enrollment]
@enrollment.reject!
# have to get the new updated_at
@user.reload
@user.cached_current_enrollments(true).should == []
it "should uncache user enrollments when rejected" do
enable_cache do
course_with_student(:active_course => 1)
User.update_all({:updated_at => 1.year.ago}, :id => @user.id)
@user.reload
@user.cached_current_enrollments.should == [@enrollment]
@enrollment.reject!
# have to get the new updated_at
@user.reload
@user.cached_current_enrollments(true).should == []
end
end
context "sharding" do
it_should_behave_like "sharding"
before do
Enrollment.stubs(:cross_shard_invitations?).returns(true)
course(:active_all => 1)
user
@user.update_attribute(:workflow_state, 'creation_pending')
@user.communication_channels.create!(:path => 'jt@instructure.com')
@enrollment1 = @course.enroll_user(@user)
@shard1.activate do
account = Account.create!
course(:active_all => 1, :account => account)
user
@user.update_attribute(:workflow_state, 'creation_pending')
@user.communication_channels.create!(:path => 'jt@instructure.com')
@enrollment2 = @course.enroll_user(@user)
end
pending "working CommunicationChannel.associated_shards" unless CommunicationChannel.associated_shards('jt@instructure.com').length == 2
end
it "should include invitations from other shards" do
Enrollment.cached_temporary_invitations('jt@instructure.com').sort_by(&:global_id).should == [@enrollment1, @enrollment2].sort_by(&:global_id)
@shard1.activate do
Enrollment.cached_temporary_invitations('jt@instructure.com').sort_by(&:global_id).should == [@enrollment1, @enrollment2].sort_by(&:global_id)
end
@shard2.activate do
Enrollment.cached_temporary_invitations('jt@instructure.com').sort_by(&:global_id).should == [@enrollment1, @enrollment2].sort_by(&:global_id)
end
end
it "should have a single cache for all shards" do
enable_cache do
@shard2.activate do
Enrollment.cached_temporary_invitations('jt@instructure.com').sort_by(&:global_id).should == [@enrollment1, @enrollment2].sort_by(&:global_id)
end
Shard.expects(:with_each_shard).never
@shard1.activate do
Enrollment.cached_temporary_invitations('jt@instructure.com').sort_by(&:global_id).should == [@enrollment1, @enrollment2].sort_by(&:global_id)
end
Enrollment.cached_temporary_invitations('jt@instructure.com').sort_by(&:global_id).should == [@enrollment1, @enrollment2].sort_by(&:global_id)
end
end
it "should invalidate the cache from any shard" do
enable_cache do
@shard2.activate do
Enrollment.cached_temporary_invitations('jt@instructure.com').sort_by(&:global_id).should == [@enrollment1, @enrollment2].sort_by(&:global_id)
@enrollment2.reject!
end
@shard1.activate do
Enrollment.cached_temporary_invitations('jt@instructure.com').should == [@enrollment1]
@enrollment1.reject!
end
Enrollment.cached_temporary_invitations('jt@instructure.com').should == []
end
end
end
end